From 05a32f1050db5a394ac68030939414dd0d818a98 Mon Sep 17 00:00:00 2001 From: minhn4 Date: Fri, 10 Jul 2026 10:51:21 +0700 Subject: [PATCH 1/3] feat(opencode): rename installed bin from codev-code to codev The CLI's scriptName, help text, and the published package's README already tell users to run `codev`; only the installed bin name said `codev-code`. The hub (codev-ai >= 0.4.0) renames its command to `codevhub` and relinquishes the `codev` bin, so the agent package now claims it in both bin maps (workspace package.json and the published wrapper in publish.ts). Release order is mandatory: publish codev-ai@0.4.0 first, or global installs collide on the `codev` bin link with EEXIST. Known adjacent gap left as is and now documented in DIVERGENCES.md: cli/cmd/uninstall.ts still uninstalls opencode-ai (wrong package). Co-Authored-By: Claude Fable 5 --- DIVERGENCES.md | 16 +++++++++------- README.md | 2 +- bun.lock | 2 +- packages/opencode/package.json | 2 +- packages/opencode/script/publish.ts | 4 ++-- packages/opencode/script/release.ts | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 882c50deaa..3210f6ead0 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -18,10 +18,10 @@ upstream maintainers — see README → Syncing with upstream for why and how. | `packages/core/src/global.ts`, `packages/core/test/global.test.ts`, `packages/opencode/test/cli/mcp-add.test.ts` | `const app = "opencode"` → `"codev-code"`; test expectations `tmpdir()/opencode` → `tmpdir()/codev-code` and `.config/opencode/` → `.config/codev-code/` | Config/data/cache/state dirs under `~/.config/codev-code` etc.; upstream tests assert the literal dir name. | Keep ours (the one constant + expectations); take upstream's surrounding changes. | | `packages/opencode/src/index.ts`, `packages/opencode/test/cli/error.test.ts`, `packages/opencode/test/cli/help/__snapshots__/help-snapshots.test.ts.snap` | `scriptName("opencode")` → `"codev"`; `show()` prefix check `"opencode "` → `"codev "`; test expectation `` `opencode models` `` → `` `codev models` ``; help snapshots regenerated so usage lines read `codev …` | Help/usage text shows the real user-facing command (the `codev` hub forwards unknown commands to this binary). The `show()` check must always match the scriptName; upstream's error-format test and help snapshots assert the literal command. | Keep our strings + expectation; take upstream's surrounding changes. Regenerate the snapshot file with `bun test test/cli/help --update-snapshots` instead of hand-merging. | | `package.json` (root) | Added `release` script delegating to packages/opencode | `bun run release` works from the repo root. | Keep our release line; take upstream's other fields. | -| `packages/opencode/package.json` | bin key `opencode` → `codev-code` (shim path `./bin/opencode` unchanged); added `release` script | Installed binary is named `codev-code`; `bun run release` publishes the version in this file (upstream-synced; script/release.ts is fork-only). | Keep our bin key and release line; take upstream's other fields including `version`. | +| `packages/opencode/package.json` | bin key `opencode` → `codev` (shim path `./bin/opencode` unchanged); added `release` script | Installed command is `codev` — matches the CLI's `scriptName` and help text (the hub's command is `codevhub`; it relinquished the `codev` bin in codev-ai ≥ 0.4.0). `bun run release` publishes the version in this file (upstream-synced; script/release.ts is fork-only). | Keep our bin key and release line; take upstream's other fields including `version`. | | `bun.lock` | Mirrors the bin key rename above | Lockfile records workspace bin mappings. | Regenerate with `bun install`; never hand-merge. | | `packages/opencode/script/build.ts` | Platform packages' `package.json` name `codev-code-` (dist dir names unchanged — the bun compile target derives from them) | npm publishing under the fork's names. | Keep our `name:` line; take upstream's surrounding changes. | -| `packages/opencode/script/publish.ts` | `PUBLISH_NAME = "codev-code"` const; npm description "CoDev Code — the AI agent harness"; published-name→dir map; main pkg name + bin key; env-guarded exit before the Docker/AUR/Homebrew section | npm-only publishing under the fork's names (unscoped, public on npmjs); upstream's other channels target anomalyco infra. | Keep our names, description + early exit; take upstream's npm-section changes above the exit. | +| `packages/opencode/script/publish.ts` | `PUBLISH_NAME = "codev-code"` const; npm description "CoDev Code — the AI agent harness"; published-name→dir map; main pkg name + bin key `codev`; embedded README (hub via `codevhub install`, direct install runs `codev`); env-guarded exit before the Docker/AUR/Homebrew section | npm-only publishing under the fork's names (unscoped, public on npmjs); the installed command is `codev`; upstream's other channels target anomalyco infra. | Keep our names, description, bin key + early exit; take upstream's npm-section changes above the exit. | | `packages/opencode/bin/opencode` | `base` prefix `opencode-` → `codev-code-` | Runtime platform-binary lookup must match the published names. | Keep our prefix. | | `packages/opencode/script/postinstall.mjs` | `base` prefix `opencode-` → `codev-code-` | Install-time platform-binary fetch must match the published names. | Keep our prefix. | | `packages/tui/src/logo.ts` | Pixel glyphs "open"+"code" → "co"+"dev"; added hub-style `banner` (ANSI-Shadow CODEV) | Branded wordmark art; `banner` feeds the TUI home banner, CLI help, and presentation mode. | Keep our glyphs and banner. | @@ -60,11 +60,13 @@ upstream maintainers — see README → Syncing with upstream for why and how. ## Known rebrand gaps (deliberate, revisit before external distribution) -- **Auto-update**: upstream's updater (`packages/core/src/installation/`) still hardcodes - `opencode-ai` and upstream's release channels. The codev hub launches the agent with - `OPENCODE_DISABLE_AUTOUPDATE=1`, so the notify/auto path is off in normal use — but a - direct `codev-code upgrade` would still install stock opencode. Patch or disable the - upgrade command before distributing outside the team. +- **Auto-update**: the updater (`packages/opencode/src/installation/`) targets the + `codev-code` npm package and the quickbeard/codev-code GitHub releases (see table row), + so `codev upgrade` installs the fork, not stock opencode. The codev hub still launches + the agent with `OPENCODE_DISABLE_AUTOUPDATE=1` so the hub owns updates. Remaining gaps: + the `curl` install path still fetches upstream's install script, and + `packages/opencode/src/cli/cmd/uninstall.ts` still uninstalls `opencode-ai` (wrong + package; unlisted divergence — patch before distributing outside the team). - **Publishing**: npm packages publish as `codev-code` / `codev-code-` — unscoped, therefore PUBLIC on npmjs (like `codev-ai`). Local-only for now (no CI workflow): run `bun run release [channel] [--skip-build]` from `packages/opencode` with npm publish diff --git a/README.md b/README.md index d32d6e6d70..063f44776b 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Notes: - With 2FA-on-publish, npm may prompt once per package (13 of them). A granular automation token avoids that: `npm config set //registry.npmjs.org/:_authToken `. - The wrapper refuses to run when the version is already on npm. For a fork-only re-release between upstream syncs, set a suffixed version in `packages/opencode/package.json` (e.g. `1.17.13-codev.1`); the next sync takes upstream's value back. -- Verify after publishing: `npm view codev-code` and `npm install -g codev-code && codev-code --version`. +- Verify after publishing: `npm view codev-code` and `npm install -g codev-code && codev --version`. ## Syncing with upstream diff --git a/bun.lock b/bun.lock index cbdb3d4cd9..da736b1f19 100644 --- a/bun.lock +++ b/bun.lock @@ -559,7 +559,7 @@ "name": "opencode", "version": "1.17.16", "bin": { - "codev-code": "./bin/opencode", + "codev": "./bin/opencode", }, "dependencies": { "@actions/core": "1.11.1", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 7e9edfbd64..45f4d050d7 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -17,7 +17,7 @@ "dev:temporary": "bun run --conditions=browser ./src/temporary.ts" }, "bin": { - "codev-code": "./bin/opencode" + "codev": "./bin/opencode" }, "exports": { "./*": "./src/*.ts" diff --git a/packages/opencode/script/publish.ts b/packages/opencode/script/publish.ts index 8a5922acf0..b833512eea 100755 --- a/packages/opencode/script/publish.ts +++ b/packages/opencode/script/publish.ts @@ -54,7 +54,7 @@ await Bun.file(`./dist/${pkg.name}/README.md`).write( "", "```sh", "npm install -g codev-ai", - "codev install", + "codevhub install", "codev", "```", "", @@ -93,7 +93,7 @@ await Bun.file(`./dist/${pkg.name}/package.json`).write( url: "git+https://github.com/quickbeard/codev-code.git", }, bin: { - "codev-code": `./bin/${pkg.name}.exe`, + codev: `./bin/${pkg.name}.exe`, }, scripts: { postinstall: "node ./postinstall.mjs", diff --git a/packages/opencode/script/release.ts b/packages/opencode/script/release.ts index feccc78194..ce0cf88cdd 100644 --- a/packages/opencode/script/release.ts +++ b/packages/opencode/script/release.ts @@ -62,4 +62,4 @@ if (!skipBuild) await $`bun ${import.meta.dirname}/build.ts`.env(env) await $`bun ${import.meta.dirname}/publish.ts`.env(env) console.log(`\nReleased codev-code@${version} (dist-tag: ${channel})`) -console.log(`Verify: npm view codev-code@${version} && npm install -g codev-code`) +console.log(`Verify: npm view codev-code@${version} && npm install -g codev-code && codev --version`) From 320e97a43354af91c5539b5ca219e6e67033c23a Mon Sep 17 00:00:00 2001 From: minhn4 Date: Fri, 10 Jul 2026 10:58:41 +0700 Subject: [PATCH 2/3] docs: fork-only releases use next-patch prerelease versions 1.17.16-codev.1 sorts BELOW the already-published 1.17.16 (semver prereleases precede their base), so npm tooling and humans read the fork release as a downgrade. Next-patch prereleases (1.17.17-codev.1) sort above the base, below upstream's real next patch, and never collide with an upstream version string. Co-Authored-By: Claude Fable 5 --- DIVERGENCES.md | 5 +++-- README.md | 2 +- packages/opencode/script/release.ts | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 3210f6ead0..98959d5ed1 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -71,8 +71,9 @@ upstream maintainers — see README → Syncing with upstream for why and how. therefore PUBLIC on npmjs (like `codev-ai`). Local-only for now (no CI workflow): run `bun run release [channel] [--skip-build]` from `packages/opencode` with npm publish auth in place. The version comes from package.json (upstream-synced — releases track - the upstream version the fork was built from; suffix like `-codev.1` for fork-only - re-releases). Docker/AUR/Homebrew/GitHub-release channels are upstream-only and + the upstream version the fork was built from; next-patch prerelease like + `1.17.17-codev.1` for fork-only re-releases, see README → Publishing). + Docker/AUR/Homebrew/GitHub-release channels are upstream-only and disabled. The binary inside platform packages is still named `opencode` (cosmetic). - **UI branding**: TUI banner, default-theme accent, desktop/web app names, and favicon/PWA assets are rebranded (see table). Still upstream-branded, deliberately: in-app i18n strings diff --git a/README.md b/README.md index 063f44776b..337d2ce040 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ bun release --skip-build # reuse an existing dist/ (must match the package.js Notes: - With 2FA-on-publish, npm may prompt once per package (13 of them). A granular automation token avoids that: `npm config set //registry.npmjs.org/:_authToken `. -- The wrapper refuses to run when the version is already on npm. For a fork-only re-release between upstream syncs, set a suffixed version in `packages/opencode/package.json` (e.g. `1.17.13-codev.1`); the next sync takes upstream's value back. +- The wrapper refuses to run when the version is already on npm. For a fork-only re-release between upstream syncs, set the **next** upstream patch with a `-codev.N` prerelease in `packages/opencode/package.json` (e.g. `1.17.17-codev.1` while on 1.17.16) — it sorts above the already-published base release but below upstream's real next patch, and never collides with an upstream version string; the next sync takes upstream's value back. - Verify after publishing: `npm view codev-code` and `npm install -g codev-code && codev --version`. ## Syncing with upstream diff --git a/packages/opencode/script/release.ts b/packages/opencode/script/release.ts index ce0cf88cdd..f984d90d69 100644 --- a/packages/opencode/script/release.ts +++ b/packages/opencode/script/release.ts @@ -7,8 +7,10 @@ import pkg from "../package.json" // The version is read from package.json — the single source of truth. That // field stays upstream-synced (their release pipeline rewrites it), so fork // releases track the upstream version they were built from. For a fork-only -// re-release between upstream syncs, bump with a suffix (e.g. 1.17.13-codev.1) -// and let the next sync take upstream's value back. +// re-release between upstream syncs, bump to the NEXT upstream patch with a +// -codev.N prerelease (e.g. 1.17.17-codev.1 while on 1.17.16 — a base-version +// suffix like 1.17.16-codev.1 would sort BELOW the published 1.17.16) and let +// the next sync take upstream's value back. // // Channel is the npm dist-tag and defaults to `latest`; pass e.g. `beta` for // pre-releases. `--skip-build` publishes an existing dist/ after verifying it From 11b560caf58c9b9f84643d4a7a156f79938e5bac Mon Sep 17 00:00:00 2001 From: minhn4 Date: Fri, 10 Jul 2026 11:06:47 +0700 Subject: [PATCH 3/3] docs: fork re-releases use numeric revisions (1.17.16-1) Supersedes the next-patch-prerelease idea: the version field stays on the upstream release the fork was built from, with a Debian-style numeric revision for fork-only builds. Installs follow the latest dist-tag, so the prerelease-sorts-below-base quirk is harmless. Co-Authored-By: Claude Fable 5 --- DIVERGENCES.md | 4 ++-- README.md | 2 +- packages/opencode/script/release.ts | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 98959d5ed1..b0ec9815c7 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -71,8 +71,8 @@ upstream maintainers — see README → Syncing with upstream for why and how. therefore PUBLIC on npmjs (like `codev-ai`). Local-only for now (no CI workflow): run `bun run release [channel] [--skip-build]` from `packages/opencode` with npm publish auth in place. The version comes from package.json (upstream-synced — releases track - the upstream version the fork was built from; next-patch prerelease like - `1.17.17-codev.1` for fork-only re-releases, see README → Publishing). + the upstream version the fork was built from; numeric revision like + `1.17.16-1` for fork-only re-releases, see README → Publishing). Docker/AUR/Homebrew/GitHub-release channels are upstream-only and disabled. The binary inside platform packages is still named `opencode` (cosmetic). - **UI branding**: TUI banner, default-theme accent, desktop/web app names, and favicon/PWA diff --git a/README.md b/README.md index 337d2ce040..e2208036e5 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ bun release --skip-build # reuse an existing dist/ (must match the package.js Notes: - With 2FA-on-publish, npm may prompt once per package (13 of them). A granular automation token avoids that: `npm config set //registry.npmjs.org/:_authToken `. -- The wrapper refuses to run when the version is already on npm. For a fork-only re-release between upstream syncs, set the **next** upstream patch with a `-codev.N` prerelease in `packages/opencode/package.json` (e.g. `1.17.17-codev.1` while on 1.17.16) — it sorts above the already-published base release but below upstream's real next patch, and never collides with an upstream version string; the next sync takes upstream's value back. +- The wrapper refuses to run when the version is already on npm. For a fork-only re-release between upstream syncs, add a numeric revision to the version in `packages/opencode/package.json` (e.g. `1.17.16-1`, then `1.17.16-2`) — the Nth fork build of that upstream release; the next sync takes upstream's value back. Semver sorts the suffixed form below the bare `1.17.16`, but installs follow the `latest` dist-tag, so that quirk is harmless. - Verify after publishing: `npm view codev-code` and `npm install -g codev-code && codev --version`. ## Syncing with upstream diff --git a/packages/opencode/script/release.ts b/packages/opencode/script/release.ts index f984d90d69..462f382dc5 100644 --- a/packages/opencode/script/release.ts +++ b/packages/opencode/script/release.ts @@ -7,10 +7,10 @@ import pkg from "../package.json" // The version is read from package.json — the single source of truth. That // field stays upstream-synced (their release pipeline rewrites it), so fork // releases track the upstream version they were built from. For a fork-only -// re-release between upstream syncs, bump to the NEXT upstream patch with a -// -codev.N prerelease (e.g. 1.17.17-codev.1 while on 1.17.16 — a base-version -// suffix like 1.17.16-codev.1 would sort BELOW the published 1.17.16) and let -// the next sync take upstream's value back. +// re-release between upstream syncs, add a numeric revision (1.17.16-1, then +// 1.17.16-2 — the Nth fork build of that upstream release; installs follow +// the latest dist-tag, so the prerelease-sorts-below-base quirk is harmless) +// and let the next sync take upstream's value back. // // Channel is the npm dist-tag and defaults to `latest`; pass e.g. `beta` for // pre-releases. `--skip-build` publishes an existing dist/ after verifying it