Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ permissions:
jobs:
version:
runs-on: blacksmith-4vcpu-ubuntu-2404
if: github.repository == 'anomalyco/opencode'
if: contains(fromJSON('["anomalyco/opencode","VibeTechnologies/opencode","vibetechnologies/opencode","dzianisv/opencode"]'), github.repository)
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -50,7 +50,7 @@ jobs:

- name: Install OpenCode
if: inputs.bump || inputs.version
run: bun i -g opencode-ai
run: bun i -g @vibetechnologies/opencode || bun i -g opencode-ai

- id: version
run: |
Expand All @@ -70,7 +70,7 @@ jobs:
build-cli:
needs: version
runs-on: blacksmith-4vcpu-ubuntu-2404
if: github.repository == 'anomalyco/opencode'
if: contains(fromJSON('["anomalyco/opencode","VibeTechnologies/opencode","vibetechnologies/opencode","dzianisv/opencode"]'), github.repository)
steps:
- uses: actions/checkout@v3
with:
Expand Down Expand Up @@ -443,5 +443,6 @@ jobs:
AUR_KEY: ${{ secrets.AUR_KEY }}
GITHUB_TOKEN: ${{ steps.committer.outputs.token }}
GH_REPO: ${{ needs.version.outputs.repo }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN || secrets.NODE_AUTH_TOKEN }}
NPM_CONFIG_PROVENANCE: false
LATEST_YML_DIR: /tmp/latest-yml
20 changes: 13 additions & 7 deletions packages/opencode/script/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,27 @@ for (const filepath of new Bun.Glob("*/package.json").scanSync({ cwd: "./dist" }
}
console.log("binaries", binaries)
const version = Object.values(binaries)[0]
const scope = "@vibetechnologies/opencode"
const out = "./dist/npm"

await $`mkdir -p ./dist/${pkg.name}`
await $`cp -r ./bin ./dist/${pkg.name}/bin`
await $`cp ./script/postinstall.mjs ./dist/${pkg.name}/postinstall.mjs`
await Bun.file(`./dist/${pkg.name}/LICENSE`).write(await Bun.file("../../LICENSE").text())
await $`mkdir -p ${out}`
await $`cp -r ./bin ${out}/bin`
await $`cp ./script/postinstall.mjs ${out}/postinstall.mjs`
await Bun.file(`${out}/LICENSE`).write(await Bun.file("../../LICENSE").text())

await Bun.file(`./dist/${pkg.name}/package.json`).write(
await Bun.file(`${out}/package.json`).write(
JSON.stringify(
{
name: pkg.name + "-ai",
name: scope,
bin: {
[pkg.name]: `./bin/${pkg.name}`,
},
scripts: {
postinstall: "bun ./postinstall.mjs || node ./postinstall.mjs",
},
publishConfig: {
access: "public",
},
version: version,
license: pkg.license,
optionalDependencies: binaries,
Expand All @@ -47,7 +52,8 @@ const tasks = Object.entries(binaries).map(async ([name]) => {
await $`npm publish *.tgz --access public --tag ${Script.channel}`.cwd(`./dist/${name}`)
})
await Promise.all(tasks)
await $`cd ./dist/${pkg.name} && bun pm pack && npm publish *.tgz --access public --tag ${Script.channel}`
await $`bun pm pack`.cwd(out)
await $`npm publish *.tgz --access public --tag ${Script.channel}`.cwd(out)

const image = "ghcr.io/anomalyco/opencode"
const platforms = "linux/amd64,linux/arm64"
Expand Down
18 changes: 10 additions & 8 deletions packages/opencode/src/cli/cmd/uninstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,12 @@ async function showRemovalSummary(targets: RemovalTargets, method: Installation.
}

if (method !== "curl" && method !== "unknown") {
const pkg = await Installation.pkg(method)
const cmds: Record<string, string> = {
npm: "npm uninstall -g opencode-ai",
pnpm: "pnpm uninstall -g opencode-ai",
bun: "bun remove -g opencode-ai",
yarn: "yarn global remove opencode-ai",
npm: `npm uninstall -g ${pkg}`,
pnpm: `pnpm uninstall -g ${pkg}`,
bun: `bun remove -g ${pkg}`,
yarn: `yarn global remove ${pkg}`,
brew: "brew uninstall opencode",
choco: "choco uninstall opencode",
scoop: "scoop uninstall opencode",
Expand Down Expand Up @@ -179,11 +180,12 @@ async function executeUninstall(method: Installation.Method, targets: RemovalTar
}

if (method !== "curl" && method !== "unknown") {
const pkg = await Installation.pkg(method)
const cmds: Record<string, string[]> = {
npm: ["npm", "uninstall", "-g", "opencode-ai"],
pnpm: ["pnpm", "uninstall", "-g", "opencode-ai"],
bun: ["bun", "remove", "-g", "opencode-ai"],
yarn: ["yarn", "global", "remove", "opencode-ai"],
npm: ["npm", "uninstall", "-g", pkg],
pnpm: ["pnpm", "uninstall", "-g", pkg],
bun: ["bun", "remove", "-g", pkg],
yarn: ["yarn", "global", "remove", pkg],
brew: ["brew", "uninstall", "opencode"],
choco: ["choco", "uninstall", "opencode"],
scoop: ["scoop", "uninstall", "opencode"],
Expand Down
48 changes: 35 additions & 13 deletions packages/opencode/src/installation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,32 @@ declare global {

export namespace Installation {
const log = Log.create({ service: "installation" })
export const PACKAGE = "@vibetechnologies/opencode"
export const LEGACY = "opencode-ai"

function find(output: string) {
if (output.includes(PACKAGE)) return PACKAGE
if (output.includes(LEGACY)) return LEGACY
}

export async function pkg(method: Method) {
if (method === "npm") return find(await text(["npm", "list", "-g", "--depth=0"])) ?? PACKAGE
if (method === "yarn") return find(await text(["yarn", "global", "list"])) ?? PACKAGE
if (method === "pnpm") return find(await text(["pnpm", "list", "-g", "--depth=0"])) ?? PACKAGE
if (method === "bun") return find(await text(["bun", "pm", "ls", "-g"])) ?? PACKAGE
return "opencode"
}

async function version(registry: string, channel: string) {
for (const pkg of [PACKAGE, LEGACY]) {
const res = await fetch(`${registry}/${encodeURIComponent(pkg)}/${channel}`)
if (!res.ok) continue
const data = (await res.json()) as { version: string }
if (channel === "latest" && data.version.startsWith("0.0.0-")) continue
return data.version
}
throw new Error(`Could not determine npm version for ${channel}`)
}

async function text(cmd: string[], opts: { cwd?: string; env?: NodeJS.ProcessEnv } = {}) {
return Process.text(cmd, {
Expand Down Expand Up @@ -136,9 +162,11 @@ export namespace Installation {

for (const check of checks) {
const output = await check.command()
const installedName =
check.name === "brew" || check.name === "choco" || check.name === "scoop" ? "opencode" : "opencode-ai"
if (output.includes(installedName)) {
if (check.name === "brew" || check.name === "choco" || check.name === "scoop") {
if (output.includes("opencode")) return check.name
continue
}
if (find(output)) {
return check.name
}
}
Expand Down Expand Up @@ -168,13 +196,13 @@ export namespace Installation {
result = await upgradeCurl(target)
break
case "npm":
result = await Process.run(["npm", "install", "-g", `opencode-ai@${target}`], { nothrow: true })
result = await Process.run(["npm", "install", "-g", `${PACKAGE}@${target}`], { nothrow: true })
break
case "pnpm":
result = await Process.run(["pnpm", "install", "-g", `opencode-ai@${target}`], { nothrow: true })
result = await Process.run(["pnpm", "install", "-g", `${PACKAGE}@${target}`], { nothrow: true })
break
case "bun":
result = await Process.run(["bun", "install", "-g", `opencode-ai@${target}`], { nothrow: true })
result = await Process.run(["bun", "install", "-g", `${PACKAGE}@${target}`], { nothrow: true })
break
case "brew": {
const formula = await getBrewFormula()
Expand Down Expand Up @@ -261,13 +289,7 @@ export namespace Installation {
const reg = r || "https://registry.npmjs.org"
return reg.endsWith("/") ? reg.slice(0, -1) : reg
})
const channel = CHANNEL
return fetch(`${registry}/opencode-ai/${channel}`)
.then((res) => {
if (!res.ok) throw new Error(res.statusText)
return res.json()
})
.then((data: any) => data.version)
return version(registry, CHANNEL)
}

if (detectedMethod === "choco") {
Expand Down
17 changes: 11 additions & 6 deletions packages/script/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,21 @@ const CHANNEL = await (async () => {
return await $`git branch --show-current`.text().then((x) => x.trim())
})()
const IS_PREVIEW = CHANNEL !== "latest"
const pkgs = ["@vibetechnologies/opencode", "opencode-ai"]

const VERSION = await (async () => {
if (env.OPENCODE_VERSION) return env.OPENCODE_VERSION
if (IS_PREVIEW) return `0.0.0-${CHANNEL}-${new Date().toISOString().slice(0, 16).replace(/[-:T]/g, "")}`
const version = await fetch("https://registry.npmjs.org/opencode-ai/latest")
.then((res) => {
if (!res.ok) throw new Error(res.statusText)
return res.json()
})
.then((data: any) => data.version)
const version = await (async () => {
for (const pkg of pkgs) {
const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(pkg)}/latest`)
if (!res.ok) continue
const data = (await res.json()) as { version: string }
if (CHANNEL === "latest" && data.version.startsWith("0.0.0-")) continue
return data.version
}
throw new Error("Could not determine latest npm version")
})()
const [major, minor, patch] = version.split(".").map((x: string) => Number(x) || 0)
const t = env.OPENCODE_BUMP?.toLowerCase()
if (t === "major") return `${major + 1}.0.0`
Expand Down
Loading