Skip to content

Commit 481ac6f

Browse files
quickbeardclaude
andcommitted
chore: rebrand platform binary to codev and add release workflow
Close the "Publishing" rebrand gap: platform packages now ship bin/codev instead of bin/opencode (build outfile, publish stub, and postinstall copy all renamed), and a fork-only release workflow publishes to npm from CI and creates the v<version> GitHub release with codev-<platform> binaries for the latest channel — making the install docs' Releases link and the updater's GitHub fallback real. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 9770f8b commit 481ac6f

6 files changed

Lines changed: 94 additions & 21 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Fork-only workflow: publishes codev-code (+ platform packages) to npm and,
2+
# for the latest channel, creates the v<version> GitHub release with the
3+
# platform binaries attached (the install docs and the updater's GitHub
4+
# fallback in src/installation/index.ts point at these releases).
5+
#
6+
# Requires the NPM_TOKEN repository secret: a granular npm automation token
7+
# with read/write access to the codev-code packages (bypasses 2FA prompts).
8+
#
9+
# The version comes from packages/opencode/package.json — bump it first for a
10+
# fork-only re-release (see README → Publishing); script/release.ts refuses to
11+
# republish an existing version.
12+
name: release
13+
14+
on:
15+
workflow_dispatch:
16+
inputs:
17+
channel:
18+
description: "npm dist-tag to publish under"
19+
type: string
20+
required: false
21+
default: "latest"
22+
23+
# Never cancel a publish mid-flight; queue instead.
24+
concurrency:
25+
group: release
26+
cancel-in-progress: false
27+
28+
permissions:
29+
contents: write
30+
31+
env:
32+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
33+
34+
jobs:
35+
release:
36+
runs-on: ubuntu-latest
37+
timeout-minutes: 90
38+
steps:
39+
- name: Checkout repository
40+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
41+
42+
- name: Setup Bun
43+
uses: ./.github/actions/setup-bun
44+
45+
- name: Authenticate npm
46+
run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
47+
env:
48+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
49+
50+
- name: Build and publish to npm
51+
working-directory: packages/opencode
52+
run: bun run release "${{ inputs.channel }}"
53+
54+
# dist/ holds one opencode-<platform>/ directory per target (the dist
55+
# names stay pkg.name-derived — see script/build.ts) plus the main
56+
# opencode/ package dir; only the platform dirs carry real binaries.
57+
- name: Package release binaries
58+
if: inputs.channel == 'latest'
59+
working-directory: packages/opencode/dist
60+
run: |
61+
for dir in opencode-*/bin; do
62+
key="${dir%/bin}"
63+
artifact="codev-${key#opencode-}"
64+
case "$key" in
65+
*linux*) (cd "$dir" && tar -czf "../../$artifact.tar.gz" *) ;;
66+
*) (cd "$dir" && zip -r "../../$artifact.zip" *) ;;
67+
esac
68+
done
69+
70+
- name: Create GitHub release
71+
if: inputs.channel == 'latest'
72+
env:
73+
GH_TOKEN: ${{ github.token }}
74+
run: |
75+
VERSION=$(jq -r .version packages/opencode/package.json)
76+
gh release view "v$VERSION" >/dev/null 2>&1 || gh release create "v$VERSION" --title "v$VERSION" --generate-notes
77+
gh release upload "v$VERSION" packages/opencode/dist/*.tar.gz packages/opencode/dist/*.zip --clobber

‎DIVERGENCES.md‎

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ from the squash message first, or use a plain merge.
7272
| `packages/tui/src/ui/dialog.tsx` | Added a `persistent` store flag (with `setPersistent`/`persistent` accessors): escape and the click-outside backdrop no-op while set, and ctrl+c dispatches `app.exit.confirm` (base-mode-only, so suppressed under modal) instead of closing; every `replace`/`clear` resets it to false | The CoDev gateway configure flow is a non-dismissable first-run gate; ctrl+c stays the quit escape hatch (double-press — see the double-Ctrl+C row). Default-false keeps every other dialog dismissable. | Keep our persistent flag, the escape/backdrop guards, the ctrl+c `app.exit.confirm` dispatch, and the reset lines; take upstream's surrounding changes. |
7373
| `packages/tui/src/ui/dialog-select.tsx` | Added a `persistent?` prop that hides the top-right `esc` hint | A non-dismissable select shouldn't advertise `esc` (the dialog store's persistent flag blocks the actual close). | Keep our prop + the `Show` wrapper around the esc label; take upstream's surrounding changes. |
7474
| `packages/tui/src/ui/dialog-prompt.tsx` | Added `persistent?` (hides the `esc` hint + `DialogPrompt.show` re-arms the store flag), `onInput?` (fires on textarea content change), and `ref?` props | The configure flow's prompts (SSO login, manual credentials) are non-dismissable, and the SSO view watches `onInput` for the lone-`c` copy shortcut on the paste-back link (needs the `ref` to clear the field). | Keep our three props, the `Show` around the esc label, the textarea `onContentChange`, and the `.show` re-arm; take upstream's surrounding changes. |
75-
| `packages/opencode/script/build.ts` | Platform packages' `package.json` name `codev-code-<platform>` (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. |
76-
| `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. |
75+
| `packages/opencode/script/build.ts` | Platform packages' `package.json` name `codev-code-<platform>` (dist dir names unchanged — the bun compile target derives from them); compiled binary emitted as `bin/codev` (was `bin/opencode`; smoke-test path follows) | npm publishing under the fork's names; the binary inside platform packages carries the fork's name (postinstall.mjs copies it into the `codev` bin shim). The `Script.release` upload block stays upstream-shaped and unused — the fork's `.github/workflows/release.yml` packages and uploads GitHub-release artifacts itself. | Keep our `name:` line and `bin/codev` paths; take upstream's surrounding changes. |
76+
| `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 `codev` → `./bin/codev.exe` (postinstall stub file renamed from `${pkg.name}.exe`, matching the renamed platform binary); 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 mapping + early exit; take upstream's npm-section changes above the exit. |
7777
| `packages/opencode/bin/opencode` | `base` prefix `opencode-` → `codev-code-` | Runtime platform-binary lookup must match the published names. | Keep our prefix. |
78-
| `packages/opencode/script/postinstall.mjs` | `base` prefix `opencode-` → `codev-code-` | Install-time platform-binary fetch must match the published names. | Keep our prefix. |
78+
| `packages/opencode/script/postinstall.mjs` | `base` prefix `opencode-` → `codev-code-`; source/target binary names `opencode`/`opencode.exe` → `codev`/`codev.exe` (matches build.ts's `bin/codev` and publish.ts's `bin/codev.exe` stub); temp-dir prefix and failure message rebranded | Install-time platform-binary fetch must match the published package and binary names. | Keep our prefix and binary names. |
7979
| `packages/tui/src/logo.ts` | Pixel glyphs "open"+"code" → "co"+"dev"; added composed `wordmark` (plain lines) and `ansiWordmark` (bold brand teal + drop shadow) exports for CLI banners | Branded wordmark art; `ansiWordmark` feeds the CLI help banner and session epilogue. | Keep our glyphs + exports; take upstream's surrounding changes. |
8080
| `packages/tui/src/component/logo.tsx` | Renders the lowercase codev wordmark in the theme's `secondary` color (bold, with a `tint`-derived drop shadow) instead of upstream's two-tone "open"+"code" | Home banner shows the brand wordmark in the active theme's brand color (teal in dark, purple in light). | Keep our version wholesale. |
8181
| `packages/tui/src/theme/assets/codev.json` (new file), `packages/tui/src/theme/index.ts`, `packages/tui/src/context/theme.tsx` | Added the `codev` theme — upstream's `opencode.json` palette with `darkSecondary` → `#0891b2` (brand teal) — registered it in the theme index, and made it the default/fallback theme (`"opencode"` → `"codev"` in the store default, kv fallback, and load-failure fallbacks). `theme/assets/opencode.json` itself matches upstream again. | Brand accent lives in a fork-owned theme instead of edits to upstream's palette; the default theme carries the brand. | Keep our theme file, its index registration, and the fallback strings; when upstream changes the opencode palette, mirror it into `codev.json` (keeping our `darkSecondary`). |
@@ -143,14 +143,6 @@ from the squash message first, or use a plain merge.
143143

144144
## Known rebrand gaps
145145

146-
- **Publishing**: npm packages publish as `codev-code` / `codev-code-<platform>` — unscoped,
147-
therefore PUBLIC on npmjs (like `codev-ai`). Local-only for now (no CI workflow): run
148-
`bun run release [channel] [--skip-build]` from `packages/opencode` with npm publish
149-
auth in place. The version comes from package.json (upstream-synced — releases track
150-
the upstream version the fork was built from; numeric revision like
151-
`1.17.16-1` for fork-only re-releases, see README → Publishing).
152-
Docker/AUR/Homebrew/GitHub-release channels are upstream-only and
153-
disabled. The binary inside platform packages is still named `opencode` (cosmetic).
154146
- **UI branding**: TUI banner, default-theme accent, desktop/web app names, and favicon/PWA
155147
assets are rebranded (see table). Still upstream-branded, deliberately: in-app i18n strings
156148
mentioning "OpenCode" (now only in the `en`/`es` locale files — see the locale-trim rows above;

‎README.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ Notes:
5353
- The wrapper refuses to run when the version is already on npm — for a fork-only re-release, bump the revision suffix first (see [Bumping the version](#bumping-the-version) above).
5454
- Verify after publishing: `npm view codev-code` and `npm i -g codev-code && codev --version`.
5555

56+
### Publishing from CI
57+
58+
The `release` workflow (GitHub → Actions → release → Run workflow) runs the same `bun run release [channel]` on a GitHub runner, and for the `latest` channel it also creates the `v<version>` GitHub release with the platform binaries attached (`codev-<platform>-<arch>.tar.gz`/`.zip`) — the install docs and the updater's GitHub fallback point at those releases. It needs an `NPM_TOKEN` repository secret: a granular npm automation token with read/write access to the `codev-code` packages.
59+
5660
## Syncing and divergences
5761

5862
The upstream sync procedure and the divergence policy live in [DIVERGENCES.md](DIVERGENCES.md).

‎packages/opencode/script/build.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ for (const item of targets) {
180180
autoloadTsconfig: true,
181181
autoloadPackageJson: true,
182182
target: name.replace(pkg.name, "bun") as any,
183-
outfile: `dist/${name}/bin/opencode`,
183+
outfile: `dist/${name}/bin/codev`,
184184
execArgv: [`--user-agent=opencode/${Script.version}`, "--use-system-ca", "--"],
185185
windows: {},
186186
},
@@ -200,7 +200,7 @@ for (const item of targets) {
200200

201201
// Smoke test: only run if binary is for current platform
202202
if (item.os === process.platform && item.arch === process.arch && !item.abi) {
203-
const binaryPath = `dist/${name}/bin/opencode`
203+
const binaryPath = `dist/${name}/bin/codev`
204204
console.log(`Running smoke test: ${binaryPath} --version`)
205205
try {
206206
const versionOutput = await $`${binaryPath} --version`.text()

‎packages/opencode/script/postinstall.mjs‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ const archMap = {
2424

2525
const platform = platformMap[os.platform()] ?? os.platform()
2626
const arch = archMap[os.arch()] ?? os.arch()
27-
// Fork: platform binary packages are published as codev-code-<platform>
28-
// (must match bin/opencode and script/publish.ts).
27+
// Fork: platform binary packages are published as codev-code-<platform>,
28+
// each shipping bin/codev (must match script/build.ts and script/publish.ts).
2929
const base = `codev-code-${platform}-${arch}`
30-
const sourceBinary = platform === "windows" ? "opencode.exe" : "opencode"
31-
const targetBinary = path.join(__dirname, "bin", "opencode.exe")
30+
const sourceBinary = platform === "windows" ? "codev.exe" : "codev"
31+
const targetBinary = path.join(__dirname, "bin", "codev.exe")
3232

3333
function supportsAvx2() {
3434
if (arch !== "x64") return false
@@ -129,7 +129,7 @@ function installPackage(name) {
129129
const version = packageJson.optionalDependencies?.[name]
130130
if (!version) return
131131

132-
const temp = fs.mkdtempSync(path.join(os.tmpdir(), "opencode-install-"))
132+
const temp = fs.mkdtempSync(path.join(os.tmpdir(), "codev-install-"))
133133
try {
134134
const result = childProcess.spawnSync(
135135
"npm",
@@ -177,7 +177,7 @@ function main() {
177177
}
178178

179179
throw new Error(
180-
`It seems your package manager failed to install the right opencode CLI package. Try manually installing ${packageNames()
180+
`It seems your package manager failed to install the right codev CLI package. Try manually installing ${packageNames()
181181
.map((name) => JSON.stringify(name))
182182
.join(" or ")}.`,
183183
)

‎packages/opencode/script/publish.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ await Bun.file(`./dist/${pkg.name}/README.md`).write(
6565
"",
6666
].join("\n"),
6767
)
68-
await Bun.file(`./dist/${pkg.name}/bin/${pkg.name}.exe`).write(
68+
await Bun.file(`./dist/${pkg.name}/bin/codev.exe`).write(
6969
[
7070
`echo "Error: ${PUBLISH_NAME}'s postinstall script was not run." >&2`,
7171
'echo "" >&2',
@@ -91,7 +91,7 @@ await Bun.file(`./dist/${pkg.name}/package.json`).write(
9191
url: "git+https://github.com/quickbeard/codev-code.git",
9292
},
9393
bin: {
94-
codev: `./bin/${pkg.name}.exe`,
94+
codev: "./bin/codev.exe",
9595
},
9696
scripts: {
9797
postinstall: "node ./postinstall.mjs",

0 commit comments

Comments
 (0)