From 7ce72db7ca2fd6aa3a35d2b3a05bc9be15df5005 Mon Sep 17 00:00:00 2001 From: minhn4 Date: Tue, 14 Jul 2026 16:43:17 +0700 Subject: [PATCH 1/2] fix(opencode): uninstall the codev-code npm package, not opencode-ai `codev uninstall` ran `npm uninstall -g opencode-ai` (and the pnpm/bun/yarn equivalents), which is a silent no-op for every npm-installed fork user while the fork stays on disk. Point the npm-family display + exec command maps at the fork's published package name. brew/choco/scoop names and the curl `.opencode` markers are left as-is (no fork formula exists for those; the curl markers match upstream install-script artifacts). Co-Authored-By: Claude Opus 4.8 (1M context) --- DIVERGENCES.md | 14 ++++++++++---- packages/opencode/src/cli/cmd/uninstall.ts | 16 ++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 5926f05b63..5f4135469a 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -96,6 +96,7 @@ from the squash message first, or use a plain merge. | `packages/tui/src/config/keybind.ts`, `packages/tui/src/routes/session/question.tsx`, `packages/tui/src/ui/toast.tsx`, `packages/tui/test/app-lifecycle.test.tsx`, `packages/web/src/content/docs/keybinds.mdx` (+ `es/`) | Double-press Ctrl+C to quit. keybind.ts: `app_exit` `ctrl+c,ctrl+d,q` → `ctrl+d,q`, added `app_exit_confirm: "ctrl+c"` definition + its `app.exit.confirm` CommandMap entry. question.tsx: a local `app.exit.confirm` command mirroring its `app.exit` reject, with the confirm binding gathered in both option branches (Ctrl+C still rejects the question — single press). toast.tsx: `ToastOptions.variant` union gains `"secondary"` (resolves to `theme.secondary`, the banner brand color, for the confirm toast). app-lifecycle.test.tsx: added the "app.exit.confirm requires two presses to exit" test. Docs (en + es `keybinds.mdx`): split the `app_exit` default and added `app_exit_confirm: "ctrl+c"`. See also the `app.tsx`, `dialog.tsx`, and `permission.tsx` rows for their `app.exit.confirm` handlers. | A stray Ctrl+C on an empty/unfocused prompt no longer quits instantly: the first press shows a "Press Ctrl+C again to exit" toast (1.5 s window), the second within that window quits. Ctrl+D, `q`, and the `/exit` slash commands stay immediate. | Keep our binding split, the `app_exit_confirm`/`app.exit.confirm` definition + mapping, the local confirm commands + gathered bindings, the toast `"secondary"` variant, the test, and the doc defaults; take upstream's surrounding changes. If upstream re-adds `ctrl+c` to `app_exit`, keep it removed. | | `packages/tui/src/config/keybind.ts`, `packages/web/src/content/docs/keybinds.mdx` (+ `es/`), `packages/opencode/test/cli/run/footer.view.test.tsx` | `sidebar_toggle` default `"b"` → `"ctrl+b,b"` (ctrl+b first so single-binding displays — the prompt-footer sidebar hint, the sidebar tip — resolve to it); `ctrl+b`'s former jobs move to `ctrl+o`: `input_move_left` `"left,ctrl+b"` → `"left,ctrl+o"`, `session_background` `"ctrl+b"` → `"ctrl+o"`; docs defaults updated to match (docs don't list `session_background`); footer.view.test.tsx asserts the run-CLI footer background hint as `"ctrl+o background"` (was `"ctrl+b background"`) since it resolves the real `session_background` default | Single-chord sidebar toggle on `ctrl+b` (tmux/VS Code sidebar muscle memory); its displaced bindings land on `ctrl+o`, which was unbound in every scope and free of terminal-encoding collisions (unlike `ctrl+h`/`ctrl+i`/`ctrl+m`) and flow control (`ctrl+s`/`ctrl+q`). | Keep our defaults on all three keybinds, the doc lines, and the footer hint assertion; take upstream's surrounding changes. If upstream binds `ctrl+o` to something else, re-audit and pick a new free key. | | `packages/opencode/src/installation/index.ts` | Updater detects/queries/installs `codev-code` (npm-family); GitHub fallback → quickbeard/codev-code | `codev-code upgrade` and the update notification target OUR npm package, never stock opencode. brew/choco/scoop probes never match (no such packages). | Keep our package names. | +| `packages/opencode/src/cli/cmd/uninstall.ts` | npm-family uninstall commands (display + exec maps) `opencode-ai` → `codev-code` | `codev uninstall` must remove the fork's actual npm package; the old name was a silent no-op for every npm-installed fork user. NOT renamed: brew/choco/scoop package names (`opencode` — the fork publishes no such formula/package, and `method()` never resolves to those for a fork install) and the curl `.opencode/bin` + `# opencode` shell markers (they match upstream install-script artifacts, not the fork's). | Keep our `codev-code` names; take upstream's surrounding changes. | | `packages/opencode/src/config/config.ts` | `share` defaults to `"disabled"` when unset | Sharing publishes sessions to upstream's share service; internal users must opt in via config. | Keep our default block. | | Config-file rename: `packages/opencode/src/config/{config,managed,tui-migrate}.ts`, `packages/core/src/config.ts`, `packages/opencode/src/plugin/install.ts`, `packages/opencode/src/cli/cmd/{mcp,plug,providers,error}.ts`, user-facing strings (`packages/{tui,app}` dialogs/tips/i18n, skill descriptions in `packages/core/src/plugin/skill.ts` + `packages/opencode/src/skill/index.ts`), bundled prompts (`customize-opencode.md`, `initialize.txt`), tests seeding config fixtures, docs (`packages/web/src/content/docs` en + es), stragglers (`.gitignore` root ignore entry, `packages/tui/src/component/dialog-provider.tsx` credential-dialog strings, `packages/tui/src/util/error.ts` model-not-found hint, `packages/opencode/script/run-workspace-server` header comment, `specs/v2/config.md` discovery prose) | Config file `opencode.json(c)` → `codev.json(c)` everywhere (global, project walk-up, config dirs, managed); global `config.json` support and the legacy TOML `config` migration removed; managed config dir `/Library/Application Support/opencode`→`…/codev`, `/etc/opencode`→`/etc/codev`, `%ProgramData%\opencode`→`…\codev` | The fork's config surface uses the fork's name; hard rename, no legacy fallback. NOT renamed: the `$schema` URL `https://opencode.ai/config.json`, `@opencode-ai/*` packages, theme asset files named `opencode.json`, brew/scoop manifest URLs. | Keep our file names; take upstream's surrounding logic. Rename any new upstream `opencode.json`/global-`config.json` reference to `codev.json` (watch the not-renamed list). | | `.opencode/` (repo root, whole directory) | Renamed to `.codev/`; inner `opencode.jsonc` → `codev.jsonc`; internal `.opencode/` path mentions in `glossary/README.md`, `skills/effect/SKILL.md`, `command/translate.md` updated; the `opencode-local` reference → `codev-local` pointing at `~/.local/share/codev` | This is the repo's own dogfooding config dir; after the config-dir rename row below, the agent only discovers `.codev/`. | Keep our directory; re-apply upstream's `.opencode/**` changes into `.codev/` (sync surfaces them as modify/delete or add conflicts). | @@ -141,10 +142,15 @@ from the squash message first, or use a plain merge. - **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 `CODEV_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). + the agent with `CODEV_DISABLE_AUTOUPDATE=1` so the hub owns updates. Remaining gap: + `upgradeCurl` (`installation/index.ts`) still fetches upstream's `https://opencode.ai/install` + script. This is not reachable for a genuine fork install — the fork ships no curl channel + (npm is the only live one), and `method()` only returns `"curl"` when the binary sits in + `~/.opencode/bin` / `~/.local/bin`, i.e. an upstream install. The only way to hit it is to + install stock opencode via curl, swap in the fork binary, then `codev upgrade` — which would + silently reinstall upstream. Before shipping a fork curl channel, either point the URL at a + fork-hosted script or make the `curl` upgrade branch fail safe (tell the user to reinstall via + `npm i -g codev-code`). The `uninstall.ts` `opencode-ai` bug is fixed (see table row). - **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/packages/opencode/src/cli/cmd/uninstall.ts b/packages/opencode/src/cli/cmd/uninstall.ts index 0a004d53cd..99cef0654e 100644 --- a/packages/opencode/src/cli/cmd/uninstall.ts +++ b/packages/opencode/src/cli/cmd/uninstall.ts @@ -129,10 +129,10 @@ async function showRemovalSummary(targets: RemovalTargets, method: Installation. if (method !== "curl" && method !== "unknown") { const cmds: Record = { - 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 codev-code", + pnpm: "pnpm uninstall -g codev-code", + bun: "bun remove -g codev-code", + yarn: "yarn global remove codev-code", brew: "brew uninstall opencode", choco: "choco uninstall opencode", scoop: "scoop uninstall opencode", @@ -180,10 +180,10 @@ async function executeUninstall(method: Installation.Method, targets: RemovalTar if (method !== "curl" && method !== "unknown") { const cmds: Record = { - 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", "codev-code"], + pnpm: ["pnpm", "uninstall", "-g", "codev-code"], + bun: ["bun", "remove", "-g", "codev-code"], + yarn: ["yarn", "global", "remove", "codev-code"], brew: ["brew", "uninstall", "opencode"], choco: ["choco", "uninstall", "opencode"], scoop: ["scoop", "uninstall", "opencode"], From 4a54cd4088031076d7dfb11c077f3814ed4b183d Mon Sep 17 00:00:00 2001 From: minhn4 Date: Tue, 14 Jul 2026 16:54:25 +0700 Subject: [PATCH 2/2] minor changes --- CHANGELOG.md | 94 ++++++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cabf79b51..c64063cf2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,45 +9,16 @@ file is the human-readable summary of what changed and why. ## 1.17.18-1 — 2026-07-14 -### Provider setup - -- **In-app provider setup** — a first-run setup dialog (also reachable anytime - via `/configure`, or `codev configure` from the shell) configures a provider - without the hub, offering three paths. **Login with SSO** runs a PKCE flow - against the CoDev SSO wrapper (browser handoff plus manual paste-back for - headless machines, silent refresh on re-runs); the backend then mints the - gateway key and supplies the gateway URL, you pick a default model from the - gateway's model list, and the hub-shaped `provider.aigateway` block is written - to the global `codev.json` while the session and key land in the hub-shared - `~/.codev/auth.json`, so a hub installed later reuses them. **Custom provider** - takes a provider id and API key, then an optional OpenAI-compatible base URL: - with one, the available models are discovered from `/v1/models` and a keyless - `provider.` block is written to `codev.json` (the key stays in - `~/.codev/auth.json`, merged in by id); with none, only the credential is - stored. **Connect provider** opens the built-in provider dialog for Anthropic, - OpenAI, and 75+ others. The same Custom-provider flow also backs that dialog's - "Other" entry. - ([#29](https://github.com/quickbeard/codev-code/pull/29), - [#75](https://github.com/quickbeard/codev-code/pull/75), - [#76](https://github.com/quickbeard/codev-code/pull/76)) - -### Session screen +### App lifecycle -- **Scrollback-style layout** — the codev logo + tip render top-left as the - transcript's first entry and the prompt rides directly below the last message, - instead of a centered banner with a bottom-anchored input and a void between - them. Once the conversation fills the screen, the prompt pins to the bottom - and the transcript sticky-scrolls as before; paging up reaches the banner at - the top of the scrollback. - ([#55](https://github.com/quickbeard/codev-code/pull/55)) -- **Start in a session, not the home screen** — running `codev` lands directly in - the session layout with a new empty session instead of the home screen. Empty - leftover sessions are reused (at most one per directory), `session.new` - (`ctrl+x n`, `/new`, `/clear`) opens a fresh session instead of navigating - home, and `--continue` skips empty auto-created sessions to land on the last - real conversation. Also fixed a startup "Unexpected server error" toast caused - by the route switch fetching the `"dummy"` placeholder session ID. - ([#48](https://github.com/quickbeard/codev-code/pull/48)) +- **Double `Ctrl+C` to quit** — pressing `Ctrl+C` on an empty/unfocused prompt + shows "Press Ctrl+C again to exit" and only quits on a second press within 2s. + `Ctrl+D`, `q`, and `/exit`·`/quit`·`/q` still quit immediately; with + text in the prompt, `Ctrl+C` still just clears it, and modal question/permission + prompts keep their single-press cancel behavior. Submitted upstream as + [anomalyco/opencode#36613](https://github.com/anomalyco/opencode/pull/36613); + if it lands there, this entry retires. + ([#51](https://github.com/quickbeard/codev-code/pull/51)) ### Sidebar @@ -73,6 +44,24 @@ file is the human-readable summary of what changed and why. brand line is gone; the `cwd:branch` path now sits at the bottom of the sidebar. ([#53](https://github.com/quickbeard/codev-code/pull/53)) +### Session screen + +- **Scrollback-style layout** — the codev logo + tip render top-left as the + transcript's first entry and the prompt rides directly below the last message, + instead of a centered banner with a bottom-anchored input and a void between + them. Once the conversation fills the screen, the prompt pins to the bottom + and the transcript sticky-scrolls as before; paging up reaches the banner at + the top of the scrollback. + ([#55](https://github.com/quickbeard/codev-code/pull/55)) +- **Start in a session, not the home screen** — running `codev` lands directly in + the session layout with a new empty session instead of the home screen. Empty + leftover sessions are reused (at most one per directory), `session.new` + (`ctrl+x n`, `/new`, `/clear`) opens a fresh session instead of navigating + home, and `--continue` skips empty auto-created sessions to land on the last + real conversation. Also fixed a startup "Unexpected server error" toast caused + by the route switch fetching the `"dummy"` placeholder session ID. + ([#48](https://github.com/quickbeard/codev-code/pull/48)) + ### Prompt - **`cwd:branch` in the prompt footer** — the prompt footer shows the abbreviated @@ -89,13 +78,24 @@ file is the human-readable summary of what changed and why. so they remain reachable without scrolling; Enter accepts the top file match. ([#56](https://github.com/quickbeard/codev-code/pull/56)) -### App lifecycle +### Provider setup -- **Double `Ctrl+C` to quit** — pressing `Ctrl+C` on an empty/unfocused prompt - shows "Press Ctrl+C again to exit" and only quits on a second press within 2s. - `Ctrl+D`, `q`, and `/exit`·`/quit`·`/q` still quit immediately; with - text in the prompt, `Ctrl+C` still just clears it, and modal question/permission - prompts keep their single-press cancel behavior. Submitted upstream as - [anomalyco/opencode#36613](https://github.com/anomalyco/opencode/pull/36613); - if it lands there, this entry retires. - ([#51](https://github.com/quickbeard/codev-code/pull/51)) +- **In-app provider setup** — a first-run setup dialog (also reachable anytime + via `/configure`, or `codev configure` from the shell) configures a provider + without the hub, offering three paths. **Login with SSO** runs a PKCE flow + against the CoDev SSO wrapper (browser handoff plus manual paste-back for + headless machines, silent refresh on re-runs); the backend then mints the + gateway key and supplies the gateway URL, you pick a default model from the + gateway's model list, and the hub-shaped `provider.aigateway` block is written + to the global `codev.json` while the session and key land in the hub-shared + `~/.codev/auth.json`, so a hub installed later reuses them. **Custom provider** + takes a provider id and API key, then an optional OpenAI-compatible base URL: + with one, the available models are discovered from `/v1/models` and a keyless + `provider.` block is written to `codev.json` (the key stays in + `~/.codev/auth.json`, merged in by id); with none, only the credential is + stored. **Connect provider** opens the built-in provider dialog for Anthropic, + OpenAI, and 75+ others. The same Custom-provider flow also backs that dialog's + "Other" entry. + ([#29](https://github.com/quickbeard/codev-code/pull/29), + [#75](https://github.com/quickbeard/codev-code/pull/75), + [#76](https://github.com/quickbeard/codev-code/pull/76))