diff --git a/AGENTS.md b/AGENTS.md index bc4a0bd409..205b0cd6f7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ - After changing the public Protocol or Server `HttpApi`, run `bun run generate` from `packages/client`. Do not edit `src/generated` or `src/generated-effect` directly. - Keep runtime dependencies directed from Schema to Core and Protocol, then from Core and Protocol to Server. Client runtime code may depend on Schema and Protocol but never Core or Server; `sdk-next` composes Client, Core, and Server. - The default branch in this repo is `main`; use `main` or `origin/main` for diffs. (Upstream opencode's default is `dev`; this fork does not have that branch.) -- This repo is a fork of upstream opencode. Every deliberate change to an upstream file must get a row in `DIVERGENCES.md` (file, change, why, on-conflict guidance) in the same PR — an unlisted divergence is a bug. Fork-only new files are not tracked there. If the change alters documented behavior (e.g. a keybind default), record it in `CHANGELOG.md` — the user-facing docs live in the separate `codev-landing-page` repo (`content/docs/code`) and are synced from there. +- This repo is a fork of upstream opencode. Every deliberate change to an upstream file must get a row in `DIVERGENCES.md` (file, change, why, on-conflict guidance) in the same PR — an unlisted divergence is a bug. Fork-only new files are not tracked there. If the change alters documented behavior (e.g. a keybind default), record it in `CHANGELOG.md` — the user-facing docs live in the separate `codev-landing-page` repo (`content/docs/code`) and are synced from there. `packages/web/src/content/docs/*.mdx` in this repo is **not** those docs: it is the rebranded upstream merge base that makes upstream doc changes surface during a sync (see `packages/web/FORK-DOCS.md`). Never treat it as the place to document a fork feature. - Before adding a feature, read Divergence policy in `DIVERGENCES.md` and prefer the lowest tier that works: config/plugins/skills/agents first, new `packages/codev-*` workspace packages second, upstream-file edits last. When asked to sync with upstream, follow Syncing with upstream in `DIVERGENCES.md` — do not `git merge` upstream refs. ## Branch Names diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 725ee85a54..af77e20766 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -43,7 +43,8 @@ git add -A # docs packages — see the table below) hard-error and roll back the entire patch, # so filter them out first. A path is skipped only if it existed in FROM and is # deliberately absent from HEAD; files new in TO still come through. -git diff --name-only $FROM $TO -- . ':(exclude)bun.lock' | +git diff --name-only $FROM $TO -- . ':(exclude)bun.lock' \ + ':(exclude,glob)packages/web/src/content/docs/*/**' | while IFS= read -r f; do git cat-file -e "$FROM:$f" 2>/dev/null && ! git cat-file -e "HEAD:$f" 2>/dev/null || printf '%s\n' "$f" @@ -60,6 +61,25 @@ git commit -m "chore: sync upstream $TO" `git apply -3` leaves ordinary conflict markers where our divergences overlap upstream changes — the same conflict surface the old merge had. +The extra `packages/web` exclude keeps upstream's translated docs from reappearing: the +deleted-path filter only skips paths that existed at `FROM`, so a locale file **new in +`TO`** would otherwise come through. The same hole applies to any other file upstream adds +under `packages/web/` — after applying, check `git status` for new files there outside +`src/content/docs/*.mdx` and `git rm` them. + +**Then port the doc changes.** `packages/web/src/content/docs/*.mdx` is a merge base, not a +published artifact — nothing in this repo builds it. The docs users actually read live in +[codev-landing-page](https://github.com/quickbeard/codev-landing-page) (`content/docs/code/{en,vi}`), +converted to that site's MDX pipeline, so the two cannot be merged mechanically: + +```sh +git diff $FROM $TO -- packages/web/src/content/docs # what upstream actually changed +``` + +Carry the substance of that diff into the landing-page repo by hand, in both locales, and +skip the pages that repo does not publish (`zen`, `go`, `share`, `ecosystem`, `enterprise`, +`custom-tools`, `sdk`, `server`, `plugins`). + **Keep history single-author.** Sync commits are authored only by whoever runs the sync (a `git apply`'d patch carries no upstream authorship), which is why the repo's contributor list stays clean. If you ever squash-merge a branch containing commits by others, GitHub @@ -123,14 +143,14 @@ from the squash message first, or use a plain merge. | `packages/tui/src/routes/session/permission.tsx`, `packages/opencode/src/cli/cmd/run/permission.shared.ts`, `packages/opencode/test/cli/run/permission.shared.test.ts`, `packages/tui/src/component/error-component.tsx`, `packages/opencode/src/cli/cmd/run/splash.ts` | Visible sentences/badges "OpenCode"/"opencode" → "CoDev Code"/"codev-code" (incl. the permission always-allow copy and its test expectations); permission.tsx also registers a local `app.exit.confirm` command mirroring its `app.exit` reject and gathers the confirm binding (double-press Ctrl+C — see the double-Ctrl+C row) | User-facing copy; keep Ctrl+C rejecting the permission prompt as before. | Keep our strings; keep permission.tsx's `app.exit.confirm` command + binding. | | `packages/opencode/src/cli/cmd/run/splash.ts` | The `--mini` entry and exit splashes badge with `badge` (the "c" of the codev wordmark) instead of `go.right.slice(1)` (the "o" of the `go` mark) — the import and both `const mark = …` lines; header comment "full opencode entry logo and a compact [O] exit badge" → "full codev entry logo and a compact [C] exit badge". The badge glyphs draw with `input.theme.mark` (brand red) via the local `mark_fg` binding, not the muted `left`/`leftShadow` that upstream uses for the whole banner, and with no shadow — `draw`'s `shadow` param is now optional and the badge calls omit it, so the flat brand-colored outline has no interior fill. | The splash badge is the brand mark users see entering and leaving `codev --mini`; an "o" is upstream's, and the muted grey read as chrome rather than branding. `go` itself is untouched — `packages/tui/src/component/bg-pulse-render.ts` still draws the full "go" wordmark from it. | Keep the `badge` import, both `mark` assignments, the `mark_fg` badge fg, and the optional-`shadow` `draw` signature; take upstream's surrounding splash changes. If upstream restructures the badge rendering, feed it `badge` in the brand `mark` color rather than reverting to `go`/`left`. | | `packages/opencode/src/cli/cmd/run/theme.ts`, `packages/opencode/test/cli/run/theme.test.ts` | `RunSplashTheme` gains a `mark` field (brand badge color for the mini splash — no shadow color, the badge is a flat outline). `splashTheme` sets `mark` to the `BRAND_MARK` constant (`rgba(brand.red)` — `#ee0033`, imported from `@/cli/logo`) as **truecolor, not quantized**, in both light and dark; `RUN_THEME_FALLBACK.splash` seeds `mark` from the same constant. theme.test.ts asserts `mark` is exactly `[238,0,51]`. Deliberately NOT the run theme's own `secondary` (that is derived from the terminal palette — magenta — and quantizing it gives a dull, off-brand cell). | The badge renders the same "C" glyph as the landing page's compact mark (`codev-landing-page` `app/icon.svg`), which is brand red in both modes — so the mini splash, the favicon, and the wordmark's red "dev" all agree. The rest of the splash stays palette-matched; the brand mark is a deliberate truecolor exception. Mode-independent, so `splashTheme` keeps upstream's `(theme, indexed)` signature. | Keep the `RunSplashTheme.mark` field, the `BRAND_MARK` constant + `brand` import, the fallback seed, and the test assertion; take upstream's surrounding theme changes. | -| `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` | 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. 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, and the test; take upstream's surrounding changes. If upstream re-adds `ctrl+c` to `app_exit`, keep it removed. | -| `packages/tui/src/config/keybind.ts`, `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"`; 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 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/tui/src/config/keybind.ts`, `packages/tui/src/component/prompt/index.tsx`, `packages/tui/src/app.tsx` | Single-press Ctrl+C interrupt. keybind.ts: added `session_interrupt_now: "ctrl+c"` + its `session.interrupt.now` CommandMap entry (`session_interrupt` keeps `escape`; its description gains "(press twice)"). prompt/index.tsx: added the `session.interrupt.now` command — same guards as upstream's `session.interrupt` but it aborts on the first press, and its `enabled` requires a busy session AND an empty prompt so ctrl+c falls through to `prompt.clear` (draft present) or `app.exit.confirm` (idle) instead of racing them on layer order; gathered the command in the `prompt.palette` binding list; the busy footer hint reads `interruptShortcut()` (resolves `session.interrupt`, mapping `escape` → `esc` and falling back to the `session.interrupt.now` label when escape is unbound) instead of the hardcoded `esc`. app.tsx: split `app_exit_confirm` out of the shared exit `useBindings` into its own layer whose `enabled` also requires `sync.data.session_status[route.data.sessionID]` to be idle, so ctrl+c can't arm the quit confirm mid-turn (`app_exit` keeps the shared predicate). Covered by the fork-only `packages/tui/test/interrupt.view.test.tsx`. See also the double-Ctrl+C row above, whose scope this narrows. | Ctrl+C is what many users reach for to stop a running agent, so it interrupts too; `escape` stays the advertised one in the busy footer and the home tip. Gating on `enabled` rather than binding order keeps the ctrl+c precedence (clear draft → interrupt → exit confirm) deterministic, since same-priority layers resolve by registration order and `useBindings` re-registers on every reactive change. | Keep the `session_interrupt_now` definition + mapping, the `session.interrupt.now` command and its `enabled` predicate, the footer shortcut memos, the split exit layer, and the test; take upstream's surrounding changes. If upstream binds `ctrl+c` to something else in the prompt, re-audit the precedence chain end to end. | +| `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` | 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. 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, and the test; 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`, `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"`; 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 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/tui/src/config/keybind.ts`, `packages/tui/src/component/prompt/index.tsx`, `packages/tui/src/app.tsx`, `packages/web/src/content/docs/keybinds.mdx` | Single-press Ctrl+C interrupt. keybind.ts: added `session_interrupt_now: "ctrl+c"` + its `session.interrupt.now` CommandMap entry (`session_interrupt` keeps `escape`; its description gains "(press twice)"). prompt/index.tsx: added the `session.interrupt.now` command — same guards as upstream's `session.interrupt` but it aborts on the first press, and its `enabled` requires a busy session AND an empty prompt so ctrl+c falls through to `prompt.clear` (draft present) or `app.exit.confirm` (idle) instead of racing them on layer order; gathered the command in the `prompt.palette` binding list; the busy footer hint reads `interruptShortcut()` (resolves `session.interrupt`, mapping `escape` → `esc` and falling back to the `session.interrupt.now` label when escape is unbound) instead of the hardcoded `esc`. app.tsx: split `app_exit_confirm` out of the shared exit `useBindings` into its own layer whose `enabled` also requires `sync.data.session_status[route.data.sessionID]` to be idle, so ctrl+c can't arm the quit confirm mid-turn (`app_exit` keeps the shared predicate). Covered by the fork-only `packages/tui/test/interrupt.view.test.tsx`. See also the double-Ctrl+C row above, whose scope this narrows. | Ctrl+C is what many users reach for to stop a running agent, so it interrupts too; `escape` stays the advertised one in the busy footer and the home tip. Gating on `enabled` rather than binding order keeps the ctrl+c precedence (clear draft → interrupt → exit confirm) deterministic, since same-priority layers resolve by registration order and `useBindings` re-registers on every reactive change. | Keep the `session_interrupt_now` definition + mapping, the `session.interrupt.now` command and its `enabled` predicate, the footer shortcut memos, the split exit layer, and the test; take upstream's surrounding changes. If upstream binds `ctrl+c` to something else in the prompt, re-audit the precedence chain end to end. | | `packages/tui/src/app.tsx`, `packages/tui/src/context/epilogue.tsx`, `packages/tui/src/routes/session/index.tsx`, `packages/tui/test/app-lifecycle.test.tsx` | Exit transcript. epilogue.tsx: the epilogue setter accepts `string \| (() => string)`. app.tsx: the `renderer.once("destroy")` listener materializes a thunk epilogue before resolving `shutdown` (it runs before `@opentui/solid`'s own destroy listener, so the reactive tree and sync store are still alive), and the `EpilogueProvider` setter ignores writes once `renderer.isDestroyed` — fixing a pre-existing race where the session route's `onCleanup(() => setEpilogue())` ran during Solid dispose and clobbered the epilogue before `run()` printed it. routes/session/index.tsx: the epilogue effect sets a thunk that prepends a compact transcript of the session (fork-only `util/exit-transcript.ts` + `test/util/exit-transcript.test.ts`, not tracked here) to `sessionEpilogue`, painted with the active theme's colors (truecolor ANSI; error-status tools get the error color, and assistant text gets a line-based markdown approximation of the session's `` renderable — headings/bold/italic/inline code/fences/lists/links styled with the theme's `markdown*` colors), reading `messages()`/parts/theme only inside the thunk so message updates don't rebuild it. app-lifecycle.test.tsx: the epilogue test seeds a session with messages and asserts the transcript prints; its session id is `ses_demo` because `dummy` collides with the fork's placeholder route id and the Session route never mounts for it (this collision is why the test failed before), with session-scoped endpoints and a paid model stubbed and a frame-poll wait for the session view before dispatching `app.exit`. | Quitting the TUI restored the alternate screen and threw the conversation away; now the transcript (user `>` prompts, assistant text, dim `⏺ Tool(arg)` one-liners — no thinking, no tool output) survives in terminal scrollback like Claude Code, followed by the usual epilogue. | Keep the thunk union, the destroy-listener materialization, the `isDestroyed` setter guard, the thunk-producing effect, and the test's `ses_demo` id + stubs; take upstream's surrounding changes. | | `packages/opencode/src/installation/index.ts` | Updater detects/queries/installs `codev-code` (npm-family); GitHub fallback → quickbeard/codev-code. `method()` drops upstream's `~/.local/bin` → `curl` check, keeping only `~/.opencode/bin`. The `curl` upgrade branch refuses instead of running upstream's install script: `upgradeCurl` + `upgradeScriptShell` + the `Stream` import are removed, and `case "curl"` returns `UpgradeFailedError` pointing at `npm i -g 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). A `curl`-detected binary (in `~/.opencode/bin`) is a stock opencode install; piping upstream's `opencode.ai/install` script would silently replace the fork with stock opencode. `~/.local/bin` is dropped because it's also a common npm/bun global-bin prefix, so a legitimate package-manager install there was misdetected as curl (now falls through to the manager probes). | Keep our package names, the `~/.local/bin` removal, and the curl refusal; keep `upgradeCurl`/`upgradeScriptShell`/`Stream` deleted (take upstream's changes elsewhere). | | `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, 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). | +| 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`), 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). | | Config-dir rename: `packages/opencode/src/config/{paths,config,tui}.ts`, `packages/core/src/config.ts`, `packages/opencode/src/plugin/install.ts`, `packages/opencode/src/plugin/tui/runtime.ts`, `packages/tui/src/context/theme.tsx`, `packages/opencode/src/cli/cmd/{agent,mcp}.ts`, `packages/opencode/src/session/session.ts`, plan permission patterns (`packages/opencode/src/agent/agent.ts`, `packages/core/src/plugin/agent.ts`), TUI tips, skill descriptions, `customize-opencode.md`, `specs/tui-plugins.md`, tests creating `.opencode` fixtures, docs (en + es) | Config directory `.opencode` → `.codev` (project walk-up, `~/.codev`, plans dir, theme/plugin discovery) | The fork's config surface uses the fork's name; hard rename, no legacy fallback. NOT renamed: `~/.opencode/bin` install paths (binary location — see installation/uninstall rows), the `ai.opencode.managed` plist domain, identifiers like provider id `opencode` and theme asset keys. | Keep our dir name; take upstream's surrounding logic. Rename any new upstream `.opencode` dir reference to `.codev` (leave `~/.opencode/bin`). | | `packages/tui/src/component/dialog-provider.tsx`, `packages/tui/src/component/dialog-model.tsx`, `packages/opencode/src/cli/cmd/providers.ts` | Filter `opencode`/`opencode-go` out of provider pickers and the `/model` dialog (model list + Favorites/Recent; the model dialog's opencode-first sort became a plain name sort) | Upstream's hosted offerings (Zen/Go) are detours for gateway users. | Keep our filters. | @@ -171,10 +191,12 @@ from the squash message first, or use a plain merge. | `README.*.md` (21 translations) | Deleted | Upstream marketing translations, irrelevant to the fork. | Keep deleted (`git rm` the upstream side of modify/delete conflicts). | | `screenshot-uk.png` | Deleted | Orphaned README-translation asset; referenced by nothing. | Keep deleted. | | `artifacts/` (whole directory) | Deleted | Upstream's Remotion marketing-video project (`glm52-rise-video`) with rendered MP4/PNG binaries committed; irrelevant to the fork and bloats every clone. | Keep deleted (`git rm` the upstream side of modify/delete conflicts); delete new upstream additions under `artifacts/` too. | -| `packages/web/` + `packages/docs/` (whole directories) | Deleted | The Astro/Starlight docs site — which also carried upstream's marketing lander and the `/s/` share viewer, neither deployed by the fork — and an untouched Mintlify starter kit that nothing referenced. The fork's user-facing docs live in the [codev-landing-page](https://github.com/quickbeard/codev-landing-page) repo (`content/docs/code`), which every in-app docs link already points at (see the browser-opened docs-links row). The `sst.cloudflare.x.Astro("Web")` block in `infra/app.ts` was removed with it. | Keep deleted (`git rm` the upstream side of modify/delete conflicts); delete any new upstream files under these directories too. | +| `packages/web/` **except** `src/content/docs/*.mdx`, plus `packages/docs/` (whole directory) | Deleted — the Astro site scaffolding (`astro.config.mjs`, `config.mjs`, `package.json`, `src/{components,pages,assets,styles,i18n,types}`, `public/`, `middleware.ts`, `content.config.ts`), every translated docs directory including `es/`, `src/content/i18n/`, and the untouched Mintlify starter kit. The 36 English `.mdx` doc sources are **kept** — see the web-docs rebrand row. The `sst.cloudflare.x.Astro("Web")` block in `infra/app.ts` stays removed. | The site itself is never built or deployed by the fork — it also carried upstream's marketing lander and the `/s/` share viewer — and the published docs live in the [codev-landing-page](https://github.com/quickbeard/codev-landing-page) repo (`content/docs/code`), which every in-app docs link points at. But deleting the doc **sources** made upstream doc changes invisible: the sync runbook's filter skips any path that existed at `FROM` and is absent from `HEAD`, so between v1.18.3 and v1.18.4 the fork silently dropped upstream's doc edits instead of conflicting on them. Keeping the English sources at their upstream paths restores that signal. Because nothing builds them, their Starlight component imports, `config.mjs` import and `../../assets/**` image references are deliberately dangling. | Keep the scaffolding, the translated docs dirs and `packages/docs/` deleted (`git rm` the upstream side of modify/delete conflicts); delete any new upstream file that lands under those paths, including any new locale directory. Keep the English `.mdx` sources — never delete them again to silence a conflict; a conflict there is the point. | +| Web docs, repo-wide (36 English files under `packages/web/src/content/docs/`) | Product-brand prose "OpenCode" → "CoDev Code" and built-CLI examples `opencode ` → `codev ` (incl. bare `opencode` invocations); XDG data/cache/config path examples corrected to match `Global.Path` (`app = "codev"` in `packages/core/src/global.ts`): `~/.local/share/opencode`→`…/codev`, `~/.cache/opencode`→`…/codev`, `$XDG_CONFIG_HOME/opencode/themes`→`…/codev/themes`, and the `%USERPROFILE%\…` Windows forms. **Install docs rewritten to the fork's real distribution** (`index.mdx`, `windows-wsl.mdx`, `gitlab.mdx` CI): the fork ships only as the npm package `codev-code` (npm/bun/pnpm/yarn) with GitHub release binaries at `quickbeard/codev-code` — matches `packages/opencode/src/installation/index.ts`. Removed the channels the fork does not publish (upstream's `curl … opencode.ai/install` script, `brew install anomalyco/tap/opencode`, Arch pacman/AUR, Chocolatey, Scoop, Mise `github:anomalyco/opencode`, `docker … ghcr.io/anomalyco/opencode`) and the `anomalyco/opencode/releases` link. `ide.mdx` Manual Install rewritten from "search **OpenCode** in the Extension Marketplace" to building the `.vsix` from a checkout (`cd sdks/vscode && bun install && bun run vsix`, then `code --install-extension`) — the fork's extension has no Marketplace listing. NOT renamed (load-bearing / not ours): "OpenCode Zen" and "OpenCode Go" (+ their team refs and `opencode.ai/zen/...` URLs / `opencode`,`opencode-go` provider+model ids), every `opencode.ai` URL incl. the `$schema` values (`config.json`/`tui.json`/`theme.json`), `@opencode-ai/*` SDK/plugin packages, GitLab integration (third-party `nagyv/gitlab-opencode` component, its `@opencode` trigger, `anomalyco/opencode` repo refs; the GitHub integration is rebranded — see the `github.mdx` row), runtime defaults that still match code (`opencode.local` mDNS, `.well-known/opencode`, theme id/sound-pack `opencode`, default basic-auth username `opencode`), and third-party project names (`opencode.nvim`, `opencode-helicone-session`, `awesome-opencode`, etc.) These sources are **not published from this repo** — nothing builds them and the reader-facing copies live in codev-landing-page (`content/docs/code/{en,vi}`), converted to that site's MDX pipeline. They exist so an upstream doc change surfaces as a conflict here; port the substance across by hand, it cannot be merged. | The published docs should name the fork's product and its `codev` CLI, and copy-pasteable commands/paths must work against the fork (binary `codev`, npm package `codev-code`, XDG dir `codev`); documenting install channels the fork doesn't publish sends users to stock opencode. The kept items are external products, real URLs/packages/integration identifiers, or runtime values that must match unchanged code. | Keep our brand/CLI/path/install strings; take upstream's structural doc changes. Rebrand any new upstream `opencode `/"OpenCode" prose and stale `opencode` XDG path, leaving the NOT-renamed list. If upstream re-adds brew/curl/choco/scoop/mise/docker install methods, drop them unless the fork actually publishes to that channel. | +| `packages/web/src/content/docs/github.mdx` | GitHub-integration docs rebrand: trigger `/opencode`/`/oc` → `/codev`, workflow examples `.github/workflows/opencode*.yml` → `codev*.yml` with `uses: quickbeard/codev-code/github@main` and `GITHUB_TOKEN` in `env`; the "Install the GitHub app" manual-setup step removed (GITHUB_TOKEN auth is the default; `use_github_token`/`mentions` documented, upstream App documented as the opt-out `use_github_token: false` path); `share` documented as defaulting to false; example permissions swap `id-token: write` for the `contents`/`issues`/`pull-requests: write` the token path needs. | Docs must match the rebranded CLI handler + action defaults (rows above); documenting upstream's `/opencode` trigger and GitHub App would mislead fork users. | Keep our triggers, action ref, auth model, and defaults; take upstream's structural doc changes. | | `github/` (whole directory) | Deleted — `action.yml` was a composite action living in this repo, so `uses: quickbeard/codev-code/github@main` resolved for nobody outside it; its only job was installing the public `codev-code` npm package and running `codev github run`, which the documented workflow now does inline (see the `github.handler.ts` row). With the action gone the rest of the directory was orphaned: `index.ts` was a standalone duplicate of the `githubRun` logic that `action.yml` never invoked, and the package was not a member of the root `workspaces` list, so nothing built, tested, or imported it. `README.md` content now lives in the fork's docs at `content/docs/code/{en,vi}/github.mdx` in [codev-landing-page](https://github.com/quickbeard/codev-landing-page) | The fork's repo is private and owned by a user account, not an org, so GitHub cannot share an action in it with any other repository — every user who copied the documented workflow hit "repository not found" on their first run. The npm package is public, so inlining the steps is the only distribution path that works, and it leaves the whole directory dead. The fork has no GitHub App and its share service defaults off (config.ts row), so sharing defaults off here too | Keep deleted (`git rm` the upstream side of modify/delete conflicts); delete new upstream additions under `github/` too. If this repo ever goes public and the action is worth restoring, restore `action.yml` only and re-point the docs. | | `packages/opencode/src/cli/cmd/github.handler.ts` | CLI side of the GitHub integration rebranded to match `github/` (row above). `githubRun`: `MENTIONS` default `/opencode,/oc` → `/codev`, generated branches `opencode/*` → `codev/*`, comment footer `[opencode session]` → `[codev session]`, visible log/prompt strings "opencode" → "codev", and `USE_GITHUB_TOKEN` defaults to **true** when unset (upstream returns false). `githubInstall`: no longer installs upstream's GitHub App (browser flow + `api.opencode.ai` install poll removed); scaffolds `.github/workflows/codev.yml` (was `opencode.yml`) triggering on `/codev` with `contents`/`issues`/`pull-requests: write` permissions, an `npm install -g codev-code` step and a `codev github run` step carrying `GITHUB_TOKEN` and `MODEL` in `env` — no `uses:`, see the `github/` row; next-steps text says `/codev summarize` and links the fork's hosted docs at `/docs/code/github` (the `github/` README it used to link is deleted). | The trigger phrase, branches, footer, and scaffolded workflow are user-facing. The fork has no GitHub App to install, so OIDC token exchange can never succeed here: `USE_GITHUB_TOKEN` must default true, or an unset variable sends users down the exchange path and fails asking for `id-token: write`. Upstream's false default was masked while the composite action passed the input explicitly; deleting the action exposed it. NOT renamed: `AGENT_USERNAME` `opencode-agent[bot]` (upstream App bot identity, used for reaction cleanup in the app-token path), `api.opencode.ai` exchange endpoints, the `opencode-github-action` OIDC audience, `opencode.ai` share URLs, and the social-cards URL. | Keep our trigger/branch/footer strings, the app-less install flow, the `USE_GITHUB_TOKEN` true default, and the actionless scaffold; take upstream's surrounding logic changes. If upstream adds new user-facing "opencode" strings or workflow scaffold changes, rebrand them the same way; never let a scaffold change reintroduce `uses: quickbeard/codev-code/github@main`. | -| Project-repo links: `packages/tui/src/component/error-component.tsx`, `SECURITY.md` | "This project's repo" links `github.com/anomalyco/opencode` → `github.com/quickbeard/codev-code`: the TUI crash screen's report-bug URL (`issues/new?template=bug-report.yml` — the fork's template keeps upstream's field ids incl. `opencode-version`, so the prefill params still work) and its auto-generated "Reported automatically from the opencode crash screen" prose → "codev"; SECURITY.md's report-a-vulnerability advisories link | Crash reports, vulnerability reports, and contributions belong on the fork's repo, not upstream's. NOT repointed (deliberate upstream references): README attribution + CHANGELOG/DIVERGENCES upstream citations, upstream issue links in code comments (`mcp/index.ts`), model-persona prompt files, test fixtures (`github-remote.test.ts`, `shared.test.ts`), tree-sitter wasm download URLs, the disabled AUR/Homebrew section of `script/publish.ts`, `packages/{cli,ui,http-recorder}` manifest metadata (unpublished by the fork), console/stats/enterprise routes (not deployed by the fork), and desktop `copy-metainfo.ts` (desktop unshipped — revisit with the desktop bucket). | Keep our URLs and crash-screen prose; take upstream's surrounding changes. Repoint any new "report/contribute here" link; leave the NOT-repointed list. | +| Project-repo links: `packages/tui/src/component/error-component.tsx`, `SECURITY.md`, `packages/web/src/content/docs/{troubleshooting,agents}.mdx` | "This project's repo" links `github.com/anomalyco/opencode` → `github.com/quickbeard/codev-code`: the TUI crash screen's report-bug URL (`issues/new?template=bug-report.yml` — the fork's template keeps upstream's field ids incl. `opencode-version`, so the prefill params still work) and its auto-generated "Reported automatically from the opencode crash screen" prose → "codev"; SECURITY.md's report-a-vulnerability advisories link | Crash reports, vulnerability reports, and contributions belong on the fork's repo, not upstream's. NOT repointed (deliberate upstream references): README attribution + CHANGELOG/DIVERGENCES upstream citations, upstream issue links in code comments (`mcp/index.ts`), model-persona prompt files, test fixtures (`github-remote.test.ts`, `shared.test.ts`), tree-sitter wasm download URLs, the disabled AUR/Homebrew section of `script/publish.ts`, `packages/{cli,ui,http-recorder}` manifest metadata (unpublished by the fork), console/stats/enterprise routes (not deployed by the fork), and desktop `copy-metainfo.ts` (desktop unshipped — revisit with the desktop bucket). | Keep our URLs and crash-screen prose; take upstream's surrounding changes. Repoint any new "report/contribute here" link; leave the NOT-repointed list. | | `.github/TEAM_MEMBERS` | Deleted | Upstream's team roster. The five workflows that read it (pr-standards, pr-management, triage, duplicate-issues, compliance-close) fetch it from a `dev` branch this fork doesn't have, so they are already inert here. | Keep deleted. | | `packages/script/src/index.ts` | Guard the `.github/TEAM_MEMBERS` read: fall back to an empty team list when the file is absent instead of throwing at module load | This module is imported by the publish path (`publish.ts`); the deleted `TEAM_MEMBERS` (row above) made `bun run release` crash with ENOENT. `Script.team` has no consumers in the fork. | Keep our `exists()` guard; take upstream's surrounding changes. | | `.github/workflows/` — 22 upstream workflows deleted (beta, close-issues, close-prs, compliance-close, containers, deploy, docs-locale-sync, docs-update, duplicate-issues, generate, nix-hashes, notify-discord, opencode, pr-management, pr-standards, publish, publish-github-action, publish-vscode, release-github-action, review, stats, triage) | Deleted | All inert or upstream-only here: gated on `anomalyco/opencode`, publish/deploy to upstream infra, need upstream secrets (`OPENCODE_APP_SECRET`, `OPENCODE_API_KEY`, marketplace/Discord/PostHog tokens), trigger only on a `dev` branch the fork lacks, or read the deleted `TEAM_MEMBERS`. | Keep deleted; delete new upstream workflows too unless they're generic self-contained CI. | @@ -187,7 +209,7 @@ from the squash message first, or use a plain merge. | `sdks/vscode/package.json`, `sdks/vscode/src/extension.ts`, `sdks/vscode/README.md` | `name` `opencode` → `codev-code` (the extension ID is `publisher.name`); `displayName` "opencode" → "CoDev Code"; `publisher` `sst-dev` → `CoDev` (PLACEHOLDER — no such Marketplace publisher is registered; the mixed-case `CoDev` also isn't a valid Marketplace publisher id, which must be lowercase — fine for the sideloaded `.vsix` the fork ships, but replace with the real fork-owned lowercase publisher id before any `vsce publish`, and keep it in sync with the CLI auto-install target); `description` "opencode for VS Code" → "CoDev Code for VS Code"; `icon` `images/icon.png` is a fork-local generated PNG of the CoDev "c" badge (brand red `#ee0033` — the "dev" half of the wordmark, see `packages/tui/src/logo.ts` — on `#0a0a0a`), with `images/icon.svg` as its source of record — replacing the earlier symlink to the shared `packages/identity` bracket mark; the two per-theme command `icon` objects (`{light,dark}` → `images/button-{dark,light}.svg`) collapse to a single `"images/button.svg"` string and `extension.ts`'s terminal `iconPath` object collapses to a single `Uri`, both pointing at a fork-local transparent brand-red `#ee0033` "c" glyph that reads on light+dark themes (replacing the two `packages/identity` bracket-mark symlinks, now deleted); `repository.url` → `github.com/quickbeard/codev-code`; command IDs `opencode.*` → `codev.*` across `contributes.commands`/`menus`/`keybindings` and the `registerCommand` calls; command/keybinding titles "Open opencode…"/"Run opencode"/"opencode: Insert At-Mentioned" → "Open CoDev Code…"/"Run CoDev Code"/"CoDev Code: Insert At-Mentioned" (keys unchanged); `TERMINAL_NAME` `opencode` → `codev` and the terminal launches `codev --port `; scripts gain `"vsix"` (`vsce package --no-dependencies --skip-license -o dist/`) with `@vscode/vsce` added as a pinned devDependency; README body rebranded and trimmed to the details-panel essentials — CoDev Code intro linking the fork repo, `npm install -g codev-code` prerequisite, and feature prose only; upstream's Support and Development/Making-Changes sections are dropped (they're contributor-facing, not end-user extension description) | The fork ships this extension as an installable `.vsix`, so every user-visible surface — palette titles, command IDs, terminal name, launched binary, details-panel README — must say codev, and the launched binary must be the fork's `codev` CLI. Distinct `codev.*` IDs also avoid clashing with upstream's extension if both are installed. `--no-dependencies` because the bundle is self-contained (no runtime deps, bun-managed lockfile); `--skip-license` because `sdks/vscode` has no LICENSE file and vsce aborts without it. | Keep our name + displayName + publisher + repository + description, command IDs + titles, `TERMINAL_NAME`, the `codev --port` launch line, the `vsix` script + `@vscode/vsce` devDependency, and the trimmed README (branding + dropped Support/Development sections); take upstream's extension-logic and manifest-structure changes. | | `packages/opencode/src/ide/index.ts` | IDE auto-install target `sst-dev.opencode` → `CoDev.codev-code` (`publisher.name` from `sdks/vscode/package.json`) | The CLI must install the fork's extension ID (`publisher.name` from `sdks/vscode/package.json`), not upstream's Marketplace listing. `Ide.install` currently has no runtime caller (only its test imports the module), and the install only resolves once the extension is actually published — until then the local `.vsix` is the supported install path. | Keep our extension ID (and re-sync it if the registered publisher id changes); take upstream's install/detection logic changes. | | Env-var rename, repo-wide (~230 files): both flag registries (`packages/core/src/flag/flag.ts`, `packages/opencode/src/effect/runtime-flags.ts`), every `process.env`/`Bun.env` read+set site across `packages/*`, `sdks/vscode`, `infra/enterprise.ts`, `nix/opencode.nix`, `turbo.json`, `.github/workflows/test.yml`, test preloads/fixtures/snapshots, docs (en + es), `SECURITY.md`, specs | `OPENCODE_*` env vars → `CODEV_*` (hard cutover, no legacy fallback), including the bundler define identifiers (`CODEV_VERSION`, `CODEV_CHANNEL`, `CODEV_MODELS_DEV`, `CODEV_LIBC`, `CODEV_CLI_NAME`, `CODEV_WORKER_PATH`), `VITE_OPENCODE_*` → `VITE_CODEV_*`, `import.meta.env.OPENCODE_CHANNEL` → `CODEV_CHANNEL`, the VSCode extension's `OPENCODE_CALLER`/`_EXTENSION_OPENCODE_PORT`, and the bare `OPENCODE=1` marker → `CODEV=1` | The fork's env surface uses the fork's name (reverses the earlier "internal names stay upstream" decision for env vars). NOT renamed: `__OPENCODE_PHOTON_WASM_PATH` and `__OPENCODE__` globals (not env vars; the photon name is baked into `patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch`), `patches/install-korean-ime-fix.sh` script-local shell vars, upstream secret names in workflow-deletion notes, lowercase identifiers (`@opencode-ai/*`, URLs, provider id) | Keep our names; rename any new upstream `OPENCODE_*` env var (or define/`VITE_` name) to `CODEV_*` when syncing. | -| Locale dicts in `packages/{ui,app}/src/i18n/`, `packages/desktop/src/renderer/i18n/`, `packages/console/app/src/i18n/`, `packages/stats/app/src/i18n/` | Deleted every locale except `en`/`es` (incl. `packages/app/src/i18n/parity.test.ts`) | Fork ships English + Spanish only. | Keep deleted (`git rm` the upstream side of modify/delete conflicts); also delete any locale files upstream adds. | +| Locale dicts in `packages/{ui,app}/src/i18n/`, `packages/desktop/src/renderer/i18n/`, `packages/console/app/src/i18n/`, `packages/stats/app/src/i18n/`, `packages/web/src/content/i18n/`; every translated docs dir in `packages/web/src/content/docs/` | Deleted every locale except `en`/`es` (incl. `packages/app/src/i18n/parity.test.ts`) | Fork ships English + Spanish only. | Keep deleted (`git rm` the upstream side of modify/delete conflicts); also delete any locale files upstream adds. | | `packages/app/src/context/language.tsx`, `packages/app/src/entry.tsx`, `packages/desktop/src/renderer/i18n/index.ts`, `packages/console/app/src/i18n/index.ts`, `packages/console/app/src/lib/language.ts`, `packages/console/app/src/component/footer.tsx`, `packages/stats/app/src/i18n.ts`, `packages/enterprise/src/app.tsx`, `packages/app/e2e/regression/session-timeline-locale-projection.spec.ts` | Locale registries trimmed to `en` + `es`: `Locale` types, LOCALES/LABEL/TAG/DOCS maps, dict loaders, accept-language matchers; enterprise/entry `zh` special cases now use `es`; console footer always links Discord (Feishu was zh-only); e2e locale-projection spec tests `es` ("Explorado") instead of de/ar | Fork ships English + Spanish only. | Keep our trimmed lists; take upstream's structural changes and re-trim any new locale entries. | | `packages/tui/src/component/prompt/autocomplete.tsx`, `packages/app/src/components/prompt-input.tsx`, `packages/opencode/src/cli/cmd/run/footer.prompt.tsx`, `packages/core/src/filesystem/search.ts`, `packages/tui/test/fixture/tui-sdk.ts`, `packages/opencode/test/cli/run/footer.view.test.tsx`, `packages/core/test/filesystem/search.test.ts` | `@` mention autocomplete lists file/directory results before references/agents/MCP resources; TUI and run-CLI menus cap the leading files so up to 3 non-file matches stay in the first visible page; web app group rank reordered to recent → file → reference → agent → resource (extracted into fork-only `prompt-input/at-options.ts`). TUI and run-CLI file resources track menu visibility so opening on an empty query fetches (previously nothing refetched until the query changed); core's ripgrep-fallback `find` returns its first entries for an empty query to mirror fff. Tests: tui-sdk fixture's `FetchHandler` gains an optional `method` arg, `renderFooter` accepts `findFiles`/`agents` overrides + a mention-menu ordering test, core search tests cover the fallback's empty query (fork-only test files: `packages/tui/test/prompt-autocomplete.test.tsx`, `packages/app/test-browser/prompt-at-options.test.ts`, `packages/app/src/components/prompt-input/at-options{,.test}.ts`) | Files are the dominant `@` use case; they should rank first and appear on a bare `@`. | Keep our ordering/reserve logic, resource source tracking, empty-query branch, fixture/test additions; take upstream's surrounding changes. | | `packages/slack/.gitignore`, `sdks/vscode/.gitignore` | Added the missing trailing newline (content unchanged) | Upstream's copies end without a newline; POSIX text files should end with one, and tools that concatenate or append to these files misbehave without it. | Whitespace-only: keep the trailing newline; take upstream's entries. | diff --git a/packages/web/FORK-DOCS.md b/packages/web/FORK-DOCS.md new file mode 100644 index 0000000000..9bf4e2abc2 --- /dev/null +++ b/packages/web/FORK-DOCS.md @@ -0,0 +1,43 @@ +# Upstream doc sources — merge base only + +`src/content/docs/*.mdx` are the fork's rebranded copies of upstream's English +documentation, pinned to the upstream release named by `version` in +`packages/opencode/package.json`. **Nothing here is built, served, or published.** + +## Why they exist + +They are a change detector for `git apply -3`. The sync runbook in +[`DIVERGENCES.md`](../../DIVERGENCES.md) drops any path that existed at `FROM` and is +absent from `HEAD`, so while these files were deleted (PR #122) every upstream doc edit +was skipped in silence rather than raising a conflict — the fork went from v1.18.3 to +v1.18.4 without seeing upstream's doc changes at all. With the sources back at their +upstream paths, those edits surface the same way any other divergence does. + +## Where the real docs are + +The documentation users read lives in +[codev-landing-page](https://github.com/quickbeard/codev-landing-page), under +`content/docs/code/{en,vi}`, converted to that site's MDX pipeline. + +**Edit those, not these.** When a sync raises a conflict in this directory, resolve it +here to keep the merge base honest, then carry the substance across by hand. The two +cannot be merged mechanically: the landing-page pages are restructured, use their own +components, and cover a different page set (no `zen`, `go`, `share`, `ecosystem`, +`enterprise`, `custom-tools`, `sdk`, `server` or `plugins`; plus a `desktop` page upstream +has never had). + +Because these files track upstream rather than the published site, they will drift behind +it for fork-only features documented after PR #122. That is expected — their job is to +tell you what *upstream* changed. + +## What was not restored + +Everything else in this package: `astro.config.mjs`, `config.mjs`, `package.json`, +`public/`, `src/{components,pages,assets,styles,i18n,types}`, `middleware.ts`, +`content.config.ts`, and every translated docs directory. Without them the surviving +`.mdx` files have dangling imports — Starlight components, `../../../config.mjs`, +`../../assets/**` images. That is deliberate; nothing resolves them because nothing +compiles these files. + +This directory is also not a workspace member. There is no `package.json`, so `bun +install`, `turbo typecheck` and the release pipeline all ignore it. diff --git a/packages/web/src/content/docs/acp.mdx b/packages/web/src/content/docs/acp.mdx new file mode 100644 index 0000000000..2e32e03e24 --- /dev/null +++ b/packages/web/src/content/docs/acp.mdx @@ -0,0 +1,156 @@ +--- +title: ACP Support +description: Use CoDev Code in any ACP-compatible editor. +--- + +CoDev Code supports the [Agent Client Protocol](https://agentclientprotocol.com) or (ACP), allowing you to use it directly in compatible editors and IDEs. + +:::tip +For a list of editors and tools that support ACP, check out the [ACP progress report](https://zed.dev/blog/acp-progress-report#available-now). +::: + +ACP is an open protocol that standardizes communication between code editors and AI coding agents. + +--- + +## Configure + +To use CoDev Code via ACP, configure your editor to run the `codev acp` command. + +The command starts CoDev Code as an ACP-compatible subprocess that communicates with your editor over JSON-RPC via stdio. + +Below are examples for popular editors that support ACP. + +--- + +### Zed + +Add to your [Zed](https://zed.dev) configuration (`~/.config/zed/settings.json`): + +```json title="~/.config/zed/settings.json" +{ + "agent_servers": { + "CoDev Code": { + "command": "codev", + "args": ["acp"] + } + } +} +``` + +To open it, use the `agent: new thread` action in the **Command Palette**. + +You can also bind a keyboard shortcut by editing your `keymap.json`: + +```json title="keymap.json" +[ + { + "bindings": { + "cmd-alt-o": [ + "agent::NewExternalAgentThread", + { + "agent": { + "custom": { + "name": "CoDev Code", + "command": { + "command": "codev", + "args": ["acp"] + } + } + } + } + ] + } + } +] +``` + +--- + +### JetBrains IDEs + +Add to your [JetBrains IDE](https://www.jetbrains.com/) acp.json according to the [documentation](https://www.jetbrains.com/help/ai-assistant/acp.html): + +```json title="acp.json" +{ + "agent_servers": { + "CoDev Code": { + "command": "/absolute/path/bin/codev", + "args": ["acp"] + } + } +} +``` + +To open it, use the new 'CoDev Code' agent in the AI Chat agent selector. + +--- + +### Avante.nvim + +Add to your [Avante.nvim](https://github.com/yetone/avante.nvim) configuration: + +```lua +{ + acp_providers = { + ["opencode"] = { + command = "codev", + args = { "acp" } + } + } +} +``` + +If you need to pass environment variables: + +```lua {6-8} +{ + acp_providers = { + ["opencode"] = { + command = "codev", + args = { "acp" }, + env = { + CODEV_API_KEY = os.getenv("CODEV_API_KEY") + } + } + } +} +``` + +--- + +### CodeCompanion.nvim + +To use CoDev Code as an ACP agent in [CodeCompanion.nvim](https://github.com/olimorris/codecompanion.nvim), add the following to your Neovim config: + +```lua +require("codecompanion").setup({ + interactions = { + chat = { + adapter = { + name = "opencode", + model = "claude-sonnet-4", + }, + }, + }, +}) +``` + +This config sets up CodeCompanion to use CoDev Code as the ACP agent for chat. + +If you need to pass environment variables (like `CODEV_API_KEY`), refer to [Configuring Adapters: Environment Variables](https://codecompanion.olimorris.dev/getting-started#setting-an-api-key) in the CodeCompanion.nvim documentation for full details. + +## Support + +CoDev Code works the same via ACP as it does in the terminal. All features are supported: + +:::note +Some built-in slash commands like `/undo` and `/redo` are currently unsupported. +::: + +- Built-in tools (file operations, terminal commands, etc.) +- Custom tools and slash commands +- MCP servers configured in your CoDev Code config +- Project-specific rules from `AGENTS.md` +- Custom formatters and linters +- Agents and permissions system diff --git a/packages/web/src/content/docs/agents.mdx b/packages/web/src/content/docs/agents.mdx new file mode 100644 index 0000000000..35742b3c3d --- /dev/null +++ b/packages/web/src/content/docs/agents.mdx @@ -0,0 +1,781 @@ +--- +title: Agents +description: Configure and use specialized agents. +--- + +Agents are specialized AI assistants that can be configured for specific tasks and workflows. They allow you to create focused tools with custom prompts, models, and tool access. + +:::tip +Use the plan agent to analyze code and review suggestions without making any code changes. +::: + +You can switch between agents during a session or invoke them with the `@` mention. + +--- + +## Types + +There are two types of agents in CoDev Code; primary agents and subagents. + +--- + +### Primary agents + +Primary agents are the main assistants you interact with directly. You can cycle through them using the **Tab** key, or your configured `switch_agent` keybind. These agents handle your main conversation. Tool access is configured via permissions — for example, Build has all tools enabled while Plan is restricted. + +:::tip +You can use the **Tab** key to switch between primary agents during a session. +::: + +CoDev Code comes with two built-in primary agents, **Build** and **Plan**. We'll +look at these below. + +--- + +### Subagents + +Subagents are specialized assistants that primary agents can invoke for specific tasks. You can also manually invoke them by **@ mentioning** them in your messages. + +CoDev Code comes with three built-in subagents, **General**, **Explore**, and **Scout**. We'll look at this below. + +--- + +## Built-in + +CoDev Code comes with two built-in primary agents and three built-in subagents. + +--- + +### Use build + +_Mode_: `primary` + +Build is the **default** primary agent with all tools enabled. This is the standard agent for development work where you need full access to file operations and system commands. + +--- + +### Use plan + +_Mode_: `primary` + +A restricted agent designed for planning and analysis. We use a permission system to give you more control and prevent unintended changes. +By default, all of the following are set to `ask`: + +- `file edits`: All writes, patches, and edits +- `bash`: All bash commands + +This agent is useful when you want the LLM to analyze code, suggest changes, or create plans without making any actual modifications to your codebase. + +--- + +### Use general + +_Mode_: `subagent` + +A general-purpose agent for researching complex questions and executing multi-step tasks. Has full tool access (except todo), so it can make file changes when needed. Use this to run multiple units of work in parallel. + +--- + +### Use explore + +_Mode_: `subagent` + +A fast, read-only agent for exploring codebases. Cannot modify files. Use this when you need to quickly find files by patterns, search code for keywords, or answer questions about the codebase. + +--- + +### Use scout + +_Mode_: `subagent` + +A read-only agent for external docs and dependency research. Use this when you need to clone a dependency repository into CoDev Code's managed cache, inspect library source, or cross-reference local code against upstream implementations without modifying your workspace. + +--- + +### Use compaction + +_Mode_: `primary` + +Hidden system agent that compacts long context into a smaller summary. It runs automatically when needed and is not selectable in the UI. + +--- + +### Use title + +_Mode_: `primary` + +Hidden system agent that generates short session titles. It runs automatically and is not selectable in the UI. + +--- + +### Use summary + +_Mode_: `primary` + +Hidden system agent that creates session summaries. It runs automatically and is not selectable in the UI. + +--- + +## Usage + +1. For primary agents, use the **Tab** key to cycle through them during a session. You can also use your configured `switch_agent` keybind. + +2. Subagents can be invoked: + - **Automatically** by primary agents for specialized tasks based on their descriptions. + - Manually by **@ mentioning** a subagent in your message. For example. + + ```txt frame="none" + @general help me search for this function + ``` + +3. **Navigation between sessions**: When subagents create child sessions, use `session_child_first` (default: **\+Down**) to enter the first child session from the parent. + +4. Once you are in a child session, use: + - `session_child_cycle` (default: **Right**) to cycle to the next child session + - `session_child_cycle_reverse` (default: **Left**) to cycle to the previous child session + - `session_parent` (default: **Up**) to return to the parent session + + This lets you switch between the main conversation and specialized subagent work. + +--- + +## Configure + +You can customize the built-in agents or create your own through configuration. Agents can be configured in two ways: + +--- + +### JSON + +Configure agents in your `codev.json` config file: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "agent": { + "build": { + "mode": "primary", + "model": "anthropic/claude-sonnet-4-20250514", + "prompt": "{file:./prompts/build.txt}", + "permission": { + "edit": "allow", + "bash": "allow" + } + }, + "plan": { + "mode": "primary", + "model": "anthropic/claude-haiku-4-20250514", + "permission": { + "edit": "deny", + "bash": "deny" + } + }, + "code-reviewer": { + "description": "Reviews code for best practices and potential issues", + "mode": "subagent", + "model": "anthropic/claude-sonnet-4-20250514", + "prompt": "You are a code reviewer. Focus on security, performance, and maintainability.", + "permission": { + "edit": "deny" + } + } + } +} +``` + +--- + +### Markdown + +You can also define agents using markdown files. Place them in: + +- Global: `~/.config/codev/agents/` +- Per-project: `.codev/agents/` + +```markdown title="~/.config/codev/agents/review.md" +--- +description: Reviews code for quality and best practices +mode: subagent +model: anthropic/claude-sonnet-4-20250514 +temperature: 0.1 +permission: + edit: deny + bash: deny +--- + +You are in code review mode. Focus on: + +- Code quality and best practices +- Potential bugs and edge cases +- Performance implications +- Security considerations + +Provide constructive feedback without making direct changes. +``` + +The markdown file name becomes the agent name. For example, `review.md` creates a `review` agent. + +--- + +## Options + +Let's look at these configuration options in detail. + +--- + +### Description + +Use the `description` option to provide a brief description of what the agent does and when to use it. + +```json title="codev.json" +{ + "agent": { + "review": { + "description": "Reviews code for best practices and potential issues" + } + } +} +``` + +This is a **required** config option. + +--- + +### Temperature + +Control the randomness and creativity of the LLM's responses with the `temperature` config. + +Lower values make responses more focused and deterministic, while higher values increase creativity and variability. + +```json title="codev.json" +{ + "agent": { + "plan": { + "temperature": 0.1 + }, + "creative": { + "temperature": 0.8 + } + } +} +``` + +Temperature values typically range from 0.0 to 1.0: + +- **0.0-0.2**: Very focused and deterministic responses, ideal for code analysis and planning +- **0.3-0.5**: Balanced responses with some creativity, good for general development tasks +- **0.6-1.0**: More creative and varied responses, useful for brainstorming and exploration + +```json title="codev.json" +{ + "agent": { + "analyze": { + "temperature": 0.1, + "prompt": "{file:./prompts/analysis.txt}" + }, + "build": { + "temperature": 0.3 + }, + "brainstorm": { + "temperature": 0.7, + "prompt": "{file:./prompts/creative.txt}" + } + } +} +``` + +If no temperature is specified, CoDev Code uses model-specific defaults; typically 0 for most models, 0.55 for Qwen models. + +--- + +### Max steps + +Control the maximum number of agentic iterations an agent can perform before being forced to respond with text only. This allows users who wish to control costs to set a limit on agentic actions. + +If this is not set, the agent will continue to iterate until the model chooses to stop or the user interrupts the session. + +```json title="codev.json" +{ + "agent": { + "quick-thinker": { + "description": "Fast reasoning with limited iterations", + "prompt": "You are a quick thinker. Solve problems with minimal steps.", + "steps": 5 + } + } +} +``` + +When the limit is reached, the agent receives a special system prompt instructing it to respond with a summarization of its work and recommended remaining tasks. + +:::caution +The legacy `maxSteps` field is deprecated. Use `steps` instead. +::: + +--- + +### Disable + +Set to `true` to disable the agent. + +```json title="codev.json" +{ + "agent": { + "review": { + "disable": true + } + } +} +``` + +--- + +### Prompt + +Specify a custom system prompt file for this agent with the `prompt` config. The prompt file should contain instructions specific to the agent's purpose. + +```json title="codev.json" +{ + "agent": { + "review": { + "prompt": "{file:./prompts/code-review.txt}" + } + } +} +``` + +This path is relative to where the config file is located. So this works for both the global CoDev Code config and the project specific config. + +--- + +### Model + +Use the `model` config to override the model for this agent. Useful for using different models optimized for different tasks. For example, a faster model for planning, a more capable model for implementation. + +:::tip +If you don’t specify a model, primary agents use the [model globally configured](/docs/config#models) while subagents will use the model of the primary agent that invoked the subagent. +::: + +```json title="codev.json" +{ + "agent": { + "plan": { + "model": "anthropic/claude-haiku-4-20250514" + } + } +} +``` + +The model ID in your CoDev Code config uses the format `provider/model-id`. For example, if you're using [OpenCode Zen](/docs/zen), you would use `opencode/gpt-5.1-codex` for GPT 5.1 Codex. + +--- + +### Tools (deprecated) + +`tools` is **deprecated**. Prefer the agent's [`permission`](#permissions) field for new configs, updates and more fine-grained control. + +Allows you to control which tools are available in this agent. You can enable or disable specific tools by setting them to `true` or `false`. In an agent's `tools` config, `true` is equivalent to `{"*": "allow"}` permission and `false` is equivalent to `{"*": "deny"}` permission. + +```json title="codev.json" {3-6,9-12} +{ + "$schema": "https://opencode.ai/config.json", + "tools": { + "write": true, + "bash": true + }, + "agent": { + "plan": { + "tools": { + "write": false, + "bash": false + } + } + } +} +``` + +:::note +The agent-specific config overrides the global config. +::: + +You can also use wildcards in legacy `tools` entries to control multiple tools at once. For example, to disable all tools from an MCP server: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "agent": { + "readonly": { + "tools": { + "mymcp_*": false, + "write": false, + "edit": false + } + } + } +} +``` + +[Learn more about tools](/docs/tools). + +--- + +### Permissions + +You can configure permissions to manage what actions an agent can take. Each permission key can be set to: + +- `"ask"` — Prompt for approval before running the tool +- `"allow"` — Allow all operations without approval +- `"deny"` — Disable the tool + +The available permission keys are: + +| Key | Tools it gates | +| -------------------- | ---------------------------------------------------------------- | +| `read` | `read` | +| `edit` | `write`, `edit`, `apply_patch` | +| `glob` | `glob` | +| `grep` | `grep` | +| `list` | `list` | +| `bash` | `bash` | +| `task` | `task` | +| `external_directory` | Any tool that reads or writes files outside the project worktree | +| `todowrite` | `todowrite`, `todoread` | +| `webfetch` | `webfetch` | +| `websearch` | `websearch` | +| `lsp` | `lsp` | +| `skill` | `skill` | +| `question` | `question` | +| `doom_loop` | Recovery prompts when an agent appears stuck | + +`read`, `edit`, `glob`, `grep`, `list`, `bash`, `task`, `external_directory`, `lsp`, and `skill` accept either a shorthand action (`"allow" | "ask" | "deny"`) or an object of glob/pattern → action for fine-grained control. The remaining keys accept the shorthand action only. + +:::note +Permission keys are matched as wildcard patterns against the underlying tool name, so the same syntax works for built-ins, custom tools, and MCP tools — for example `"mymcp_*": "deny"` denies every tool from an MCP server, and `"mymcp_search": "ask"` targets a single one. +::: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "edit": "deny" + } +} +``` + +You can override these permissions per agent. + +```json title="codev.json" {3-5,8-10} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "edit": "deny" + }, + "agent": { + "build": { + "permission": { + "edit": "ask" + } + } + } +} +``` + +You can also set permissions in Markdown agents. + +```markdown title="~/.config/codev/agents/review.md" +--- +description: Code review without edits +mode: subagent +permission: + edit: deny + bash: + "*": ask + "git diff": allow + "git log*": allow + "grep *": allow + webfetch: deny +--- + +Only analyze code and suggest changes. +``` + +You can set permissions for specific bash commands. + +```json title="codev.json" {7} +{ + "$schema": "https://opencode.ai/config.json", + "agent": { + "build": { + "permission": { + "bash": { + "git push": "ask", + "grep *": "allow" + } + } + } + } +} +``` + +This can take a glob pattern. + +```json title="codev.json" {7} +{ + "$schema": "https://opencode.ai/config.json", + "agent": { + "build": { + "permission": { + "bash": { + "git *": "ask" + } + } + } + } +} +``` + +And you can also use the `*` wildcard to manage permissions for all commands. +Since the last matching rule takes precedence, put the `*` wildcard first and specific rules after. + +```json title="codev.json" {8} +{ + "$schema": "https://opencode.ai/config.json", + "agent": { + "build": { + "permission": { + "bash": { + "*": "ask", + "git status *": "allow" + } + } + } + } +} +``` + +[Learn more about permissions](/docs/permissions). + +--- + +### Mode + +Control the agent's mode with the `mode` config. The `mode` option is used to determine how the agent can be used. + +```json title="codev.json" +{ + "agent": { + "review": { + "mode": "subagent" + } + } +} +``` + +The `mode` option can be set to `primary`, `subagent`, or `all`. If no `mode` is specified, it defaults to `all`. + +--- + +### Hidden + +Hide a subagent from the `@` autocomplete menu with `hidden: true`. Useful for internal subagents that should only be invoked programmatically by other agents via the Task tool. + +```json title="codev.json" +{ + "agent": { + "internal-helper": { + "mode": "subagent", + "hidden": true + } + } +} +``` + +This only affects user visibility in the autocomplete menu. Hidden agents can still be invoked by the model via the Task tool if permissions allow. + +:::note +Only applies to `mode: subagent` agents. +::: + +--- + +### Task permissions + +Control which subagents an agent can invoke via the Task tool with `permission.task`. Uses glob patterns for flexible matching. + +```json title="codev.json" +{ + "agent": { + "orchestrator": { + "mode": "primary", + "permission": { + "task": { + "*": "deny", + "orchestrator-*": "allow", + "code-reviewer": "ask" + } + } + } + } +} +``` + +When set to `deny`, the subagent is removed from the Task tool description entirely, so the model won't attempt to invoke it. + +:::tip +Rules are evaluated in order, and the **last matching rule wins**. In the example above, `orchestrator-planner` matches both `*` (deny) and `orchestrator-*` (allow), but since `orchestrator-*` comes after `*`, the result is `allow`. +::: + +:::tip +Users can always invoke any subagent directly via the `@` autocomplete menu, even if the agent's task permissions would deny it. +::: + +--- + +### Color + +Customize the agent's visual appearance in the UI with the `color` option. This affects how the agent appears in the interface. + +Use a valid hex color (e.g., `#FF5733`) or theme color: `primary`, `secondary`, `accent`, `success`, `warning`, `error`, `info`. + +```json title="codev.json" +{ + "agent": { + "creative": { + "color": "#ff6b6b" + }, + "code-reviewer": { + "color": "accent" + } + } +} +``` + +--- + +### Top P + +Control response diversity with the `top_p` option. Alternative to temperature for controlling randomness. + +```json title="codev.json" +{ + "agent": { + "brainstorm": { + "top_p": 0.9 + } + } +} +``` + +Values range from 0.0 to 1.0. Lower values are more focused, higher values more diverse. + +--- + +### Additional + +Any other options you specify in your agent configuration will be **passed through directly** to the provider as model options. This allows you to use provider-specific features and parameters. + +For example, with OpenAI's reasoning models, you can control the reasoning effort: + +```json title="codev.json" {6,7} +{ + "agent": { + "deep-thinker": { + "description": "Agent that uses high reasoning effort for complex problems", + "model": "openai/gpt-5", + "reasoningEffort": "high", + "textVerbosity": "low" + } + } +} +``` + +These additional options are model and provider-specific. Check your provider's documentation for available parameters. + +:::tip +Run `codev models` to see a list of the available models. +::: + +--- + +## Create agents + +You can create new agents using the following command: + +```bash +codev agent create +``` + +This interactive command will: + +1. Ask where to save the agent; global or project-specific. +2. Description of what the agent should do. +3. Generate an appropriate system prompt and identifier. +4. Let you select which permissions the agent should be allowed (anything you don't select is denied). +5. Finally, create a markdown file with the agent configuration. + +--- + +## Use cases + +Here are some common use cases for different agents. + +- **Build agent**: Full development work with all tools enabled +- **Plan agent**: Analysis and planning without making changes +- **Review agent**: Code review with read-only access plus documentation tools +- **Debug agent**: Focused on investigation with bash and read tools enabled +- **Docs agent**: Documentation writing with file operations but no system commands + +--- + +## Examples + +Here are some example agents you might find useful. + +:::tip +Do you have an agent you'd like to share? [Submit a PR](https://github.com/quickbeard/codev-code). +::: + +--- + +### Documentation agent + +```markdown title="~/.config/codev/agents/docs-writer.md" +--- +description: Writes and maintains project documentation +mode: subagent +permission: + bash: deny +--- + +You are a technical writer. Create clear, comprehensive documentation. + +Focus on: + +- Clear explanations +- Proper structure +- Code examples +- User-friendly language +``` + +--- + +### Security auditor + +```markdown title="~/.config/codev/agents/security-auditor.md" +--- +description: Performs security audits and identifies vulnerabilities +mode: subagent +permission: + edit: deny +--- + +You are a security expert. Focus on identifying potential security issues. + +Look for: + +- Input validation vulnerabilities +- Authentication and authorization flaws +- Data exposure risks +- Dependency vulnerabilities +- Configuration security issues +``` diff --git a/packages/web/src/content/docs/cli.mdx b/packages/web/src/content/docs/cli.mdx new file mode 100644 index 0000000000..66498c55d4 --- /dev/null +++ b/packages/web/src/content/docs/cli.mdx @@ -0,0 +1,733 @@ +--- +title: CLI +description: CoDev Code CLI options and commands. +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components" + +The CoDev Code CLI by default starts the [TUI](/docs/tui) when run without any arguments. + +```bash +codev +``` + +But it also accepts commands as documented on this page. This allows you to interact with CoDev Code programmatically. + +```bash +codev run "Explain how closures work in JavaScript" +``` + +--- + +### tui + +Start the CoDev Code terminal user interface. + +```bash +codev [project] +``` + +#### Flags + +| Flag | Short | Description | +| ------------------------------------------- | ----- | ----------------------------------------------------------------------- | +| {"--continue"} | `-c` | Continue the last session | +| {"--session"} | `-s` | Session ID to continue | +| {"--fork"} | | Fork the session when continuing (use with `--continue` or `--session`) | +| {"--prompt"} | | Prompt to use | +| {"--model"} | `-m` | Model to use in the form of provider/model | +| {"--agent"} | | Agent to use | +| {"--auto"} | | Auto-approve permissions that are not explicitly denied | +| {"--port"} | | Port to listen on | +| {"--hostname"} | | Hostname to listen on | +| {"--mdns"} | | Enable mDNS discovery | +| {"--mdns-domain"} | | Custom mDNS domain name | +| {"--cors"} | | Additional browser origin(s) to allow CORS | + +--- + +## Commands + +The CoDev Code CLI also has the following commands. + +--- + +### agent + +Manage agents for CoDev Code. + +```bash +codev agent [command] +``` + +--- + +#### create + +Create a new agent with custom configuration. + +```bash +codev agent create +``` + +This command will guide you through creating a new agent with a custom system prompt and permission configuration. Anything you don't allow is denied in the generated agent's frontmatter. + +#### Flags + +| Flag | Short | Description | +| ------------------------------------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| {"--path"} | | Directory to write the agent file to (defaults to global or `.codev/agent` based on the prompt) | +| {"--description"} | | What the agent should do | +| {"--mode"} | | Agent mode: `all`, `primary`, or `subagent` | +| {"--permissions"} | | Comma-separated list of permissions to allow (default: all). Available: `bash`, `read`, `edit`, `glob`, `grep`, `webfetch`, `task`, `todowrite`, `websearch`, `lsp`, `skill`. Anything omitted is denied. Alias: `--tools` | +| {"--model"} | `-m` | Model to use, in `provider/model` format | + +Passing all of `--path`, `--description`, `--mode`, and `--permissions` runs the command non-interactively. + +--- + +#### list + +List all available agents. + +```bash +codev agent list +``` + +--- + +### attach + +Attach a terminal to an already running CoDev Code backend server started via `serve` or `web` commands. + +```bash +codev attach [url] +``` + +This allows using the TUI with a remote CoDev Code backend. For example: + +```bash +# Start the backend server for web/mobile access +codev web --port 4096 --hostname 0.0.0.0 + +# In another terminal, attach the TUI to the running backend +codev attach http://10.20.30.40:4096 +``` + +#### Flags + +| Flag | Short | Description | +| ---------------------------------------- | ----- | -------------------------------------------------------------------------- | +| {"--dir"} | | Working directory to start TUI in | +| {"--continue"} | `-c` | Continue the last session | +| {"--session"} | `-s` | Session ID to continue | +| {"--fork"} | | Fork the session when continuing (use with `--continue` or `--session`) | +| {"--password"} | `-p` | Basic auth password (defaults to `CODEV_SERVER_PASSWORD`) | +| {"--username"} | `-u` | Basic auth username (defaults to `CODEV_SERVER_USERNAME` or `opencode`) | + +--- + +### auth + +Command to manage credentials and login for providers. + +```bash +codev auth [command] +``` + +--- + +#### login + +CoDev Code is powered by the provider list at [Models.dev](https://models.dev), so you can use `codev auth login` to configure API keys for any provider you'd like to use. This is stored in `~/.local/share/codev/auth.json`. + +```bash +codev auth login +``` + +When CoDev Code starts up it loads the providers from the credentials file. And if there are any keys defined in your environments or a `.env` file in your project. + +##### Flags + +| Flag | Short | Description | +| ---------------------------------------- | ----- | ---------------------------------------------------- | +| {"--provider"} | `-p` | Provider ID or name to log in to | +| {"--method"} | `-m` | Login method label to use, skipping method selection | + +--- + +#### list + +Lists all the authenticated providers as stored in the credentials file. + +```bash +codev auth list +``` + +Or the short version. + +```bash +codev auth ls +``` + +--- + +#### logout + +Logs you out of a provider by clearing it from the credentials file. + +```bash +codev auth logout +``` + +--- + +### github + +Manage the GitHub agent for repository automation. + +```bash +codev github [command] +``` + +--- + +#### install + +Install the GitHub agent in your repository. + +```bash +codev github install +``` + +This sets up the necessary GitHub Actions workflow and guides you through the configuration process. [Learn more](/docs/github). + +--- + +#### run + +Run the GitHub agent. This is typically used in GitHub Actions. + +```bash +codev github run +``` + +##### Flags + +| Flag | Description | +| ------------------------------------- | -------------------------------------- | +| {"--event"} | GitHub mock event to run the agent for | +| {"--token"} | GitHub personal access token | + +--- + +### mcp + +Manage Model Context Protocol servers. + +```bash +codev mcp [command] +``` + +--- + +#### add + +Add an MCP server to your configuration. + +```bash +codev mcp add +``` + +This command will guide you through adding either a local or remote MCP server. + +--- + +#### list + +List all configured MCP servers and their connection status. + +```bash +codev mcp list +``` + +Or use the short version. + +```bash +codev mcp ls +``` + +--- + +#### auth + +Authenticate with an OAuth-enabled MCP server. + +```bash +codev mcp auth [name] +``` + +If you don't provide a server name, you'll be prompted to select from available OAuth-capable servers. + +You can also list OAuth-capable servers and their authentication status. + +```bash +codev mcp auth list +``` + +Or use the short version. + +```bash +codev mcp auth ls +``` + +--- + +#### logout + +Remove OAuth credentials for an MCP server. + +```bash +codev mcp logout [name] +``` + +--- + +#### debug + +Debug OAuth connection issues for an MCP server. + +```bash +codev mcp debug +``` + +--- + +### models + +List all available models from configured providers. + +```bash +codev models [provider] +``` + +This command displays all models available across your configured providers in the format `provider/model`. + +This is useful for figuring out the exact model name to use in [your config](/docs/config/). + +You can optionally pass a provider ID to filter models by that provider. + +```bash +codev models anthropic +``` + +#### Flags + +| Flag | Description | +| --------------------------------------- | ------------------------------------------------------------ | +| {"--refresh"} | Refresh the models cache from models.dev | +| {"--verbose"} | Use more verbose model output (includes metadata like costs) | + +Use the `--refresh` flag to update the cached model list. This is useful when new models have been added to a provider and you want to see them in CoDev Code. + +```bash +codev models --refresh +``` + +--- + +### run + +Run CoDev Code in non-interactive mode by passing a prompt directly. + +```bash +codev run [message..] +``` + +This is useful for scripting, automation, or when you want a quick answer without launching the full TUI. For example. + +```bash "codev run" +codev run Explain the use of context in Go +``` + +You can also attach to a running `codev serve` instance to avoid MCP server cold boot times on every run: + +```bash +# Start a headless server in one terminal +codev serve + +# In another terminal, run commands that attach to it +codev run --attach http://localhost:4096 "Explain async/await in JavaScript" +``` + +#### Flags + +| Flag | Short | Description | +| ---------------------------------------- | ----- | -------------------------------------------------------------------------- | +| {"--command"} | | The command to run, use message for args | +| {"--continue"} | `-c` | Continue the last session | +| {"--session"} | `-s` | Session ID to continue | +| {"--fork"} | | Fork the session when continuing (use with `--continue` or `--session`) | +| {"--share"} | | Share the session | +| {"--model"} | `-m` | Model to use in the form of provider/model | +| {"--agent"} | | Agent to use | +| {"--file"} | `-f` | File(s) to attach to message | +| {"--format"} | | Format: default (formatted) or json (raw JSON events) | +| {"--title"} | | Title for the session (uses truncated prompt if no value provided) | +| {"--attach"} | | Attach to a running CoDev Code server (e.g., http://localhost:4096) | +| {"--password"} | `-p` | Basic auth password (defaults to `CODEV_SERVER_PASSWORD`) | +| {"--username"} | `-u` | Basic auth username (defaults to `CODEV_SERVER_USERNAME` or `opencode`) | +| {"--dir"} | | Directory to run in, or path on the remote server when attaching | +| {"--port"} | | Port for the local server (defaults to random port) | +| {"--variant"} | | Model variant (provider-specific reasoning effort) | +| {"--thinking"} | | Show thinking blocks | +| {"--auto"} | | Auto-approve permissions that are not explicitly denied | + +--- + +### serve + +Start a headless CoDev Code server for API access. Check out the [server docs](/docs/server) for the full HTTP interface. + +```bash +codev serve +``` + +This starts an HTTP server that provides API access to CoDev Code functionality without the TUI interface. Set `CODEV_SERVER_PASSWORD` to enable HTTP basic auth (username defaults to `opencode`). + +#### Flags + +| Flag | Description | +| ------------------------------------------- | ------------------------------------------ | +| {"--port"} | Port to listen on | +| {"--hostname"} | Hostname to listen on | +| {"--mdns"} | Enable mDNS discovery | +| {"--mdns-domain"} | Custom mDNS domain name | +| {"--cors"} | Additional browser origin(s) to allow CORS | + +--- + +### session + +Manage CoDev Code sessions. + +```bash +codev session [command] +``` + +--- + +#### list + +List all CoDev Code sessions. + +```bash +codev session list +``` + +##### Flags + +| Flag | Short | Description | +| ----------------------------------------- | ----- | ------------------------------------ | +| {"--max-count"} | `-n` | Limit to N most recent sessions | +| {"--format"} | | Output format: table or json (table) | + +--- + +#### delete + +Delete an CoDev Code session. + +```bash +codev session delete +``` + +--- + +### stats + +Show token usage and cost statistics for your CoDev Code sessions. + +```bash +codev stats +``` + +#### Flags + +| Flag | Description | +| --------------------------------------- | --------------------------------------------------------------------------- | +| {"--days"} | Show stats for the last N days (all time) | +| {"--tools"} | Number of tools to show (all) | +| {"--models"} | Show model usage breakdown (hidden by default). Pass a number to show top N | +| {"--project"} | Filter by project (all projects, empty string: current project) | + +--- + +### export + +Export session data as JSON. + +```bash +codev export [sessionID] +``` + +If you don't provide a session ID, you'll be prompted to select from available sessions. + +#### Flags + +| Flag | Description | +| ---------------------------------------- | ------------------------------------- | +| {"--sanitize"} | Redact sensitive transcript/file data | + +--- + +### import + +Import session data from a JSON file or CoDev Code share URL. + +```bash +codev import +``` + +You can import from a local file or an CoDev Code share URL. + +```bash +codev import session.json +codev import https://opncd.ai/s/abc123 +``` + +--- + +### web + +Start a headless CoDev Code server with a web interface. + +```bash +codev web +``` + +This starts an HTTP server and opens a web browser to access CoDev Code through a web interface. Set `CODEV_SERVER_PASSWORD` to enable HTTP basic auth (username defaults to `opencode`). + +#### Flags + +| Flag | Description | +| ------------------------------------------- | ------------------------------------------ | +| {"--port"} | Port to listen on | +| {"--hostname"} | Hostname to listen on | +| {"--mdns"} | Enable mDNS discovery | +| {"--mdns-domain"} | Custom mDNS domain name | +| {"--cors"} | Additional browser origin(s) to allow CORS | + +--- + +### acp + +Start an ACP (Agent Client Protocol) server. + +```bash +codev acp +``` + +This command starts an ACP server that communicates via stdin/stdout using nd-JSON. + +#### Flags + +| Flag | Description | +| ------------------------------------------- | ------------------------------------------ | +| {"--cwd"} | Working directory | +| {"--port"} | Port to listen on | +| {"--hostname"} | Hostname to listen on | +| {"--mdns"} | Enable mDNS discovery | +| {"--mdns-domain"} | Custom mDNS domain name | +| {"--cors"} | Additional browser origin(s) to allow CORS | + +--- + +### plugin + +Install a plugin and update your config. + +```bash +codev plugin +``` + +Or use the alias. + +```bash +codev plug +``` + +#### Flags + +| Flag | Short | Description | +| -------------------------------------- | ----- | ------------------------------- | +| {"--global"} | `-g` | Install in global config | +| {"--force"} | `-f` | Replace existing plugin version | + +--- + +### pr + +Fetch and checkout a GitHub PR branch, then run CoDev Code. + +```bash +codev pr +``` + +--- + +### db + +Database tools. + +```bash +codev db [query] +``` + +#### Flags + +| Flag | Description | +| -------------------------------------- | ------------------------------ | +| {"--format"} | Output format: `json` or `tsv` | + +--- + +#### path + +Print the database path. + +```bash +codev db path +``` + +--- + +### debug + +Debugging and troubleshooting tools. + +```bash +codev debug [command] +``` + +--- + +### uninstall + +Uninstall CoDev Code and remove all related files. + +```bash +codev uninstall +``` + +#### Flags + +| Flag | Short | Description | +| ------------------------------------------- | ----- | ------------------------------------------- | +| {"--keep-config"} | `-c` | Keep configuration files | +| {"--keep-data"} | `-d` | Keep session data and snapshots | +| {"--dry-run"} | | Show what would be removed without removing | +| {"--force"} | `-f` | Skip confirmation prompts | + +--- + +### upgrade + +Updates CoDev Code to the latest version or a specific version. + +```bash +codev upgrade [target] +``` + +To upgrade to the latest version. + +```bash +codev upgrade +``` + +To upgrade to a specific version. + +```bash +codev upgrade v0.1.48 +``` + +#### Flags + +| Flag | Short | Description | +| -------------------------------------- | ----- | ----------------------------------------------------------------- | +| {"--method"} | `-m` | The installation method that was used; curl, npm, pnpm, bun, brew | + +--- + +## Global Flags + +The CoDev Code CLI takes the following global flags. + +| Flag | Short | Description | +| ------------------------------------------ | ----- | ------------------------------------ | +| {"--help"} | `-h` | Display help | +| {"--version"} | `-v` | Print version number | +| {"--print-logs"} | | Print logs to stderr | +| {"--log-level"} | | Log level (DEBUG, INFO, WARN, ERROR) | +| {"--pure"} | | Run without external plugins | + +--- + +## Environment variables + +CoDev Code can be configured using environment variables. + +| Variable | Type | Description | +| ------------------------------------- | ------- | ------------------------------------------------- | +| `CODEV_AUTO_SHARE` | boolean | Automatically share sessions | +| `CODEV_GIT_BASH_PATH` | string | Path to Git Bash executable on Windows | +| `CODEV_CONFIG` | string | Path to config file | +| `CODEV_TUI_CONFIG` | string | Path to TUI config file | +| `CODEV_CONFIG_DIR` | string | Path to config directory | +| `CODEV_CONFIG_CONTENT` | string | Inline json config content | +| `CODEV_DISABLE_AUTOUPDATE` | boolean | Disable automatic update checks | +| `CODEV_DISABLE_PRUNE` | boolean | Disable pruning of old data | +| `CODEV_DISABLE_TERMINAL_TITLE` | boolean | Disable automatic terminal title updates | +| `CODEV_PERMISSION` | string | Inlined json permissions config | +| `CODEV_DISABLE_DEFAULT_PLUGINS` | boolean | Disable default plugins | +| `CODEV_DISABLE_LSP_DOWNLOAD` | boolean | Disable automatic LSP server downloads | +| `CODEV_ENABLE_EXPERIMENTAL_MODELS` | boolean | Enable experimental models | +| `CODEV_DISABLE_AUTOCOMPACT` | boolean | Disable automatic context compaction | +| `CODEV_DISABLE_CLAUDE_CODE` | boolean | Disable reading from `.claude` (prompt + skills) | +| `CODEV_DISABLE_CLAUDE_CODE_PROMPT` | boolean | Disable reading `~/.claude/CLAUDE.md` | +| `CODEV_DISABLE_CLAUDE_CODE_SKILLS` | boolean | Disable loading `.claude/skills` | +| `CODEV_DISABLE_MODELS_FETCH` | boolean | Disable fetching models from remote sources | +| `CODEV_DISABLE_MOUSE` | boolean | Disable mouse capture in the TUI | +| `CODEV_FAKE_VCS` | string | Fake VCS provider for testing purposes | +| `CODEV_CLIENT` | string | Client identifier (defaults to `cli`) | +| `CODEV_ENABLE_EXA` | boolean | Enable Exa web search tools | +| `CODEV_SERVER_PASSWORD` | string | Enable basic auth for `serve`/`web` | +| `CODEV_SERVER_USERNAME` | string | Override basic auth username (default `opencode`) | +| `CODEV_MODELS_URL` | string | Custom URL for fetching models configuration | + +--- + +### Experimental + +These environment variables enable experimental features that may change or be removed. + +| Variable | Type | Description | +| ----------------------------------------------- | ------- | --------------------------------------- | +| `CODEV_EXPERIMENTAL` | boolean | Enable the experimental umbrella flag | +| `CODEV_EXPERIMENTAL_ICON_DISCOVERY` | boolean | Enable icon discovery | +| `CODEV_EXPERIMENTAL_DISABLE_COPY_ON_SELECT` | boolean | Disable copy on select in TUI | +| `CODEV_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS` | number | Default timeout for bash commands in ms | +| `CODEV_EXPERIMENTAL_OUTPUT_TOKEN_MAX` | number | Max output tokens for LLM responses | +| `CODEV_EXPERIMENTAL_FILEWATCHER` | boolean | Enable file watcher for entire dir | +| `CODEV_EXPERIMENTAL_OXFMT` | boolean | Enable oxfmt formatter | +| `CODEV_EXPERIMENTAL_LSP_TOOL` | boolean | Enable experimental LSP tool | +| `CODEV_EXPERIMENTAL_DISABLE_FILEWATCHER` | boolean | Disable file watcher | +| `CODEV_EXPERIMENTAL_EXA` | boolean | Enable experimental Exa features | +| `CODEV_EXPERIMENTAL_LSP_TY` | boolean | Enable TY LSP for python files | +| `CODEV_EXPERIMENTAL_PLAN_MODE` | boolean | Enable plan mode | +| `CODEV_EXPERIMENTAL_BACKGROUND_SUBAGENTS` | boolean | Enable background subagent tasks | +| `CODEV_EXPERIMENTAL_EVENT_SYSTEM` | boolean | Enable experimental event system | +| `CODEV_EXPERIMENTAL_NATIVE_LLM` | boolean | Enable native LLM request path | +| `CODEV_EXPERIMENTAL_PARALLEL` | boolean | Enable parallel web search execution | +| `CODEV_EXPERIMENTAL_SCOUT` | boolean | Enable Scout subagent | +| `CODEV_EXPERIMENTAL_WORKSPACES` | boolean | Enable workspace support | diff --git a/packages/web/src/content/docs/commands.mdx b/packages/web/src/content/docs/commands.mdx new file mode 100644 index 0000000000..bf6f515bed --- /dev/null +++ b/packages/web/src/content/docs/commands.mdx @@ -0,0 +1,323 @@ +--- +title: Commands +description: Create custom commands for repetitive tasks. +--- + +Custom commands let you specify a prompt you want to run when that command is executed in the TUI. + +```bash frame="none" +/my-command +``` + +Custom commands are in addition to the built-in commands like `/init`, `/undo`, `/redo`, `/share`, `/help`. [Learn more](/docs/tui#commands). + +--- + +## Create command files + +Create markdown files in the `commands/` directory to define custom commands. + +Create `.codev/commands/test.md`: + +```md title=".codev/commands/test.md" +--- +description: Run tests with coverage +agent: build +model: anthropic/claude-3-5-sonnet-20241022 +--- + +Run the full test suite with coverage report and show any failures. +Focus on the failing tests and suggest fixes. +``` + +The frontmatter defines command properties. The content becomes the template. + +Use the command by typing `/` followed by the command name. + +```bash frame="none" +"/test" +``` + +--- + +## Configure + +You can add custom commands through the CoDev Code config or by creating markdown files in the `commands/` directory. + +--- + +### JSON + +Use the `command` option in your CoDev Code [config](/docs/config): + +```json title="codev.jsonc" {4-12} +{ + "$schema": "https://opencode.ai/config.json", + "command": { + // This becomes the name of the command + "test": { + // This is the prompt that will be sent to the LLM + "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.", + // This is shown as the description in the TUI + "description": "Run tests with coverage", + "agent": "build", + "model": "anthropic/claude-3-5-sonnet-20241022" + } + } +} +``` + +Now you can run this command in the TUI: + +```bash frame="none" +/test +``` + +--- + +### Markdown + +You can also define commands using markdown files. Place them in: + +- Global: `~/.config/codev/commands/` +- Per-project: `.codev/commands/` + +```markdown title="~/.config/codev/commands/test.md" +--- +description: Run tests with coverage +agent: build +model: anthropic/claude-3-5-sonnet-20241022 +--- + +Run the full test suite with coverage report and show any failures. +Focus on the failing tests and suggest fixes. +``` + +The markdown file name becomes the command name. For example, `test.md` lets +you run: + +```bash frame="none" +/test +``` + +--- + +## Prompt config + +The prompts for the custom commands support several special placeholders and syntax. + +--- + +### Arguments + +Pass arguments to commands using the `$ARGUMENTS` placeholder. + +```md title=".codev/commands/component.md" +--- +description: Create a new component +--- + +Create a new React component named $ARGUMENTS with TypeScript support. +Include proper typing and basic structure. +``` + +Run the command with arguments: + +```bash frame="none" +/component Button +``` + +And `$ARGUMENTS` will be replaced with `Button`. + +You can also access individual arguments using positional parameters: + +- `$1` - First argument +- `$2` - Second argument +- `$3` - Third argument +- And so on... + +For example: + +```md title=".codev/commands/create-file.md" +--- +description: Create a new file with content +--- + +Create a file named $1 in the directory $2 +with the following content: $3 +``` + +Run the command: + +```bash frame="none" +/create-file config.json src "{ \"key\": \"value\" }" +``` + +This replaces: + +- `$1` with `config.json` +- `$2` with `src` +- `$3` with `{ "key": "value" }` + +--- + +### Shell output + +Use _!`command`_ to inject [bash command](/docs/tui#bash-commands) output into your prompt. + +For example, to create a custom command that analyzes test coverage: + +```md title=".codev/commands/analyze-coverage.md" +--- +description: Analyze test coverage +--- + +Here are the current test results: +!`npm test` + +Based on these results, suggest improvements to increase coverage. +``` + +Or to review recent changes: + +```md title=".codev/commands/review-changes.md" +--- +description: Review recent changes +--- + +Recent git commits: +!`git log --oneline -10` + +Review these changes and suggest any improvements. +``` + +Commands run in your project's root directory and their output becomes part of the prompt. + +--- + +### File references + +Include files in your command using `@` followed by the filename. + +```md title=".codev/commands/review-component.md" +--- +description: Review component +--- + +Review the component in @src/components/Button.tsx. +Check for performance issues and suggest improvements. +``` + +The file content gets included in the prompt automatically. + +--- + +## Options + +Let's look at the configuration options in detail. + +--- + +### Template + +The `template` option defines the prompt that will be sent to the LLM when the command is executed. + +```json title="codev.json" +{ + "command": { + "test": { + "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes." + } + } +} +``` + +This is a **required** config option. + +--- + +### Description + +Use the `description` option to provide a brief description of what the command does. + +```json title="codev.json" +{ + "command": { + "test": { + "description": "Run tests with coverage" + } + } +} +``` + +This is shown as the description in the TUI when you type in the command. + +--- + +### Agent + +Use the `agent` config to optionally specify which [agent](/docs/agents) should execute this command. +If this is a [subagent](/docs/agents/#subagents) the command will trigger a subagent invocation by default. +To disable this behavior, set `subtask` to `false`. + +```json title="codev.json" +{ + "command": { + "review": { + "agent": "plan" + } + } +} +``` + +This is an **optional** config option. If not specified, defaults to your current agent. + +--- + +### Subtask + +Use the `subtask` boolean to force the command to trigger a [subagent](/docs/agents/#subagents) invocation. +This is useful if you want the command to not pollute your primary context and will **force** the agent to act as a subagent, +even if `mode` is set to `primary` on the [agent](/docs/agents) configuration. + +```json title="codev.json" +{ + "command": { + "analyze": { + "subtask": true + } + } +} +``` + +This is an **optional** config option. + +--- + +### Model + +Use the `model` config to override the default model for this command. + +```json title="codev.json" +{ + "command": { + "analyze": { + "model": "anthropic/claude-3-5-sonnet-20241022" + } + } +} +``` + +This is an **optional** config option. + +--- + +## Built-in + +CoDev Code includes several built-in commands like `/init`, `/undo`, `/redo`, `/share`, `/help`; [learn more](/docs/tui#commands). + +:::note +Custom commands can override built-in commands. +::: + +If you define a custom command with the same name, it will override the built-in command. diff --git a/packages/web/src/content/docs/config.mdx b/packages/web/src/content/docs/config.mdx new file mode 100644 index 0000000000..99bb80ce5c --- /dev/null +++ b/packages/web/src/content/docs/config.mdx @@ -0,0 +1,941 @@ +--- +title: Config +description: Using the CoDev Code JSON config. +--- + +You can configure CoDev Code using a JSON config file. + +--- + +## Format + +CoDev Code supports both **JSON** and **JSONC** (JSON with Comments) formats. + +```jsonc title="codev.jsonc" +{ + "$schema": "https://opencode.ai/config.json", + "model": "anthropic/claude-sonnet-4-5", + "autoupdate": true, + "server": { + "port": 4096, + }, +} +``` + +--- + +## Locations + +You can place your config in a couple of different locations and they have a +different order of precedence. + +:::note +Configuration files are **merged together**, not replaced. +::: + +Configuration files are merged together, not replaced. Settings from the following config locations are combined. Later configs override earlier ones only for conflicting keys. Non-conflicting settings from all configs are preserved. + +For example, if your global config sets `autoupdate: true` and your project config sets `model: "anthropic/claude-sonnet-4-5"`, the final configuration will include both settings. + +--- + +### Precedence order + +Config sources are loaded in this order (later sources override earlier ones): + +1. **Remote config** (from `.well-known/opencode`) - organizational defaults +2. **Global config** (`~/.config/codev/codev.json`) - user preferences +3. **Custom config** (`CODEV_CONFIG` env var) - custom overrides +4. **Project config** (`codev.json` in project) - project-specific settings +5. **`.codev` directories** - agents, commands, plugins +6. **Inline config** (`CODEV_CONFIG_CONTENT` env var) - runtime overrides +7. **Managed config files** (`/Library/Application Support/codev/` on macOS) - admin-controlled +8. **macOS managed preferences** (`.mobileconfig` via MDM) - highest priority, not user-overridable + +This means project configs can override global defaults, and global configs can override remote organizational defaults. Managed settings override everything. + +:::note +The `.codev` and `~/.config/codev` directories use **plural names** for subdirectories: `agents/`, `commands/`, `modes/`, `plugins/`, `skills/`, `tools/`, and `themes/`. Singular names (e.g., `agent/`) are also supported for backwards compatibility. +::: + +--- + +### Remote + +Organizations can provide default configuration via the `.well-known/opencode` endpoint. This is fetched automatically when you authenticate with a provider that supports it. + +Remote config is loaded first, serving as the base layer. All other config sources (global, project) can override these defaults. + +For example, if your organization provides MCP servers that are disabled by default: + +```json title="Remote config from .well-known/opencode" +{ + "mcp": { + "jira": { + "type": "remote", + "url": "https://jira.example.com/mcp", + "enabled": false + } + } +} +``` + +You can enable specific servers in your local config: + +```json title="codev.json" +{ + "mcp": { + "jira": { + "type": "remote", + "url": "https://jira.example.com/mcp", + "enabled": true + } + } +} +``` + +--- + +### Global + +Place your global CoDev Code config in `~/.config/codev/codev.json`. Use global config for user-wide server/runtime preferences like providers, models, and permissions. + +For TUI-specific settings, use `~/.config/codev/tui.json`. + +Global config overrides remote organizational defaults. + +--- + +### Per project + +Add `codev.json` in your project root. Project config has the highest precedence among standard config files - it overrides both global and remote configs. + +For project-specific TUI settings, add `tui.json` alongside it. + +:::tip +Place project specific config in the root of your project. +::: + +When CoDev Code starts up, it first looks for a config file in the current directory, then traverses up to the nearest Git directory. + +This is also safe to be checked into Git and uses the same schema as the global one. + +--- + +### Custom path + +Specify a custom config file path using the `CODEV_CONFIG` environment variable. + +```bash +export CODEV_CONFIG=/path/to/my/custom-config.json +codev run "Hello world" +``` + +Custom config is loaded between global and project configs in the precedence order. + +--- + +### Custom directory + +Specify a custom config directory using the `CODEV_CONFIG_DIR` +environment variable. This directory will be searched for agents, commands, +modes, and plugins just like the standard `.codev` directory, and should +follow the same structure. + +```bash +export CODEV_CONFIG_DIR=/path/to/my/config-directory +codev run "Hello world" +``` + +The custom directory is loaded after the global config and `.codev` directories, so it **can override** their settings. + +--- + +### Managed settings + +Organizations can enforce configuration that users cannot override. Managed settings are loaded at the highest priority tier. + +#### File-based + +Drop an `codev.json` or `codev.jsonc` file in the system managed config directory: + +| Platform | Path | +| -------- | ---------------------------------------- | +| macOS | `/Library/Application Support/codev/` | +| Linux | `/etc/codev/` | +| Windows | `%ProgramData%\opencode` | + +These directories require admin/root access to write, so users cannot modify them. + +#### macOS managed preferences + +On macOS, CoDev Code reads managed preferences from the `ai.opencode.managed` preference domain. Deploy a `.mobileconfig` via MDM (Jamf, Kandji, FleetDM) and the settings are enforced automatically. + +CoDev Code checks these paths: + +1. `/Library/Managed Preferences//ai.opencode.managed.plist` +2. `/Library/Managed Preferences/ai.opencode.managed.plist` + +The plist keys map directly to `codev.json` fields. MDM metadata keys (`PayloadUUID`, `PayloadType`, etc.) are stripped automatically. + +**Creating a `.mobileconfig`** + +Use the `ai.opencode.managed` PayloadType. The CoDev Code config keys go directly in the payload dict: + +```xml + + + + + PayloadContent + + + PayloadType + ai.opencode.managed + PayloadIdentifier + com.example.codev.config + PayloadUUID + GENERATE-YOUR-OWN-UUID + PayloadVersion + 1 + share + disabled + server + + hostname + 127.0.0.1 + + permission + + * + ask + bash + + * + ask + rm -rf * + deny + + + + + PayloadType + Configuration + PayloadIdentifier + com.example.codev + PayloadUUID + GENERATE-YOUR-OWN-UUID + PayloadVersion + 1 + + +``` + +Generate unique UUIDs with `uuidgen`. Customize the settings to match your organization's requirements. + +**Deploying via MDM** + +- **Jamf Pro:** Computers > Configuration Profiles > Upload > scope to target devices or smart groups +- **FleetDM:** Add the `.mobileconfig` to your gitops repo under `mdm.macos_settings.custom_settings` and run `fleetctl apply` + +**Verifying on a device** + +Double-click the `.mobileconfig` to install locally for testing (shows in System Settings > Privacy & Security > Profiles), then run: + +```bash +codev debug config +``` + +All managed preference keys appear in the resolved config and cannot be overridden by user or project configuration. + +--- + +## Schema + +The server/runtime config schema is defined in [**`opencode.ai/config.json`**](https://opencode.ai/config.json). + +TUI config uses [**`opencode.ai/tui.json`**](https://opencode.ai/tui.json). + +Your editor should be able to validate and autocomplete based on the schema. + +--- + +### TUI + +Use a dedicated `tui.json` (or `tui.jsonc`) file for TUI-specific settings. + +```json title="tui.json" +{ + "$schema": "https://opencode.ai/tui.json", + "scroll_speed": 3, + "scroll_acceleration": { + "enabled": true + }, + "diff_style": "auto", + "mouse": true, + "attention": { + "enabled": true, + "notifications": true, + "sound": true, + "volume": 0.4 + } +} +``` + +Use `CODEV_TUI_CONFIG` to point to a custom TUI config file. + +Set `attention.enabled` to turn on TUI desktop notifications and sounds. See [TUI attention](/docs/tui#attention). + +Legacy `theme`, `keybinds`, and `tui` keys in `codev.json` are deprecated and automatically migrated when possible. + +--- + +### Server + +You can configure server settings for the `codev serve` and `codev web` commands through the `server` option. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "server": { + "port": 4096, + "hostname": "0.0.0.0", + "mdns": true, + "mdnsDomain": "myproject.local", + "cors": ["http://localhost:5173"] + } +} +``` + +Available options: + +- `port` - Port to listen on. +- `hostname` - Hostname to listen on. When `mdns` is enabled and no hostname is set, defaults to `0.0.0.0`. +- `mdns` - Enable mDNS service discovery. This allows other devices on the network to discover your CoDev Code server. +- `mdnsDomain` - Custom domain name for mDNS service. Defaults to `opencode.local`. Useful for running multiple instances on the same network. +- `cors` - Additional origins to allow for CORS when using the HTTP server from a browser-based client. Values must be full origins (scheme + host + optional port), eg `https://app.example.com`. + +[Learn more about the server here](/docs/server). + +--- + +### Shell + +You can configure the shell used for the interactive terminal using the `shell` option. Compatible shells are also used for agent tool calls. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "shell": "pwsh" +} +``` + +If not specified, CoDev Code will automatically discover and use a sensible default based on your operating system (e.g. `pwsh` or `cmd.exe` on Windows, `/bin/zsh` or `/bin/bash` on macOS/Linux). You can provide an absolute path or a short name. + +--- + +### Tools + +You can manage the tools an LLM can use through the `tools` option. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "tools": { + "write": false, + "bash": false + } +} +``` + +[Learn more about tools here](/docs/tools). + +--- + +### Models + +You can configure the providers and models you want to use in your CoDev Code config through the `provider`, `model` and `small_model` options. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "provider": {}, + "model": "anthropic/claude-sonnet-4-5", + "small_model": "anthropic/claude-haiku-4-5" +} +``` + +The `small_model` option configures a separate model for lightweight tasks like title generation. By default, CoDev Code tries to use a cheaper model if one is available from your provider, otherwise it falls back to your main model. + +Provider options can include `timeout`, `chunkTimeout`, and `setCacheKey`: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "anthropic": { + "options": { + "timeout": 600000, + "chunkTimeout": 30000, + "setCacheKey": true + } + } + } +} +``` + +- `timeout` - Request timeout in milliseconds (default: 300000). Set to `false` to disable. +- `chunkTimeout` - Timeout in milliseconds between streamed response chunks. If no chunk arrives in time, the request is aborted. +- `setCacheKey` - Ensure a cache key is always set for designated provider. + +You can also configure [local models](/docs/models#local). [Learn more](/docs/models). + +--- + +### Policies + +Use the `experimental.policies` option to allow or deny CoDev Code actions on configured resources. Currently, policies can control which providers CoDev Code may use. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "experimental": { + "policies": [ + { + "effect": "deny", + "action": "provider.use", + "resource": "openai" + } + ] + } +} +``` + +[Learn more about policies here](/docs/policies). + +--- + +### Image attachments + +CoDev Code normalizes image attachments before sending them to the model. By default, images are resized when they exceed `2000x2000` pixels or `5242880` base64 bytes. + +Configure image attachment limits with the `attachment.image` option: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "attachment": { + "image": { + "auto_resize": true, + "max_width": 2000, + "max_height": 2000, + "max_base64_bytes": 5242880 + } + } +} +``` + +- `auto_resize` - Resize images that exceed the configured limits before provider requests. Set to `false` to reject oversized images instead. +- `max_width` - Maximum image width in pixels before resizing or rejection. +- `max_height` - Maximum image height in pixels before resizing or rejection. +- `max_base64_bytes` - Maximum encoded image payload size. This is the base64 payload size, not the original file size. + +If an image still cannot fit after resizing, CoDev Code omits oversized tool-result images or fails oversized user-provided images with an image size error. + +--- + +#### Provider-Specific Options + +Some providers support additional configuration options beyond the generic `timeout` and `apiKey` settings. + +##### Amazon Bedrock + +Amazon Bedrock supports AWS-specific configuration: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "amazon-bedrock": { + "options": { + "region": "us-east-1", + "profile": "my-aws-profile", + "endpoint": "https://bedrock-runtime.us-east-1.vpce-xxxxx.amazonaws.com" + } + } + } +} +``` + +- `region` - AWS region for Bedrock (defaults to `AWS_REGION` env var or `us-east-1`) +- `profile` - AWS named profile from `~/.aws/credentials` (defaults to `AWS_PROFILE` env var) +- `endpoint` - Custom endpoint URL for VPC endpoints. This is an alias for the generic `baseURL` option using AWS-specific terminology. If both are specified, `endpoint` takes precedence. + +:::note +Bearer tokens (`AWS_BEARER_TOKEN_BEDROCK` or `/connect`) take precedence over profile-based authentication. See [authentication precedence](/docs/providers#authentication-precedence) for details. +::: + +[Learn more about Amazon Bedrock configuration](/docs/providers#amazon-bedrock). + +--- + +### Themes + +Set your UI theme in `tui.json`. + +```json title="tui.json" +{ + "$schema": "https://opencode.ai/tui.json", + "theme": "tokyonight" +} +``` + +[Learn more here](/docs/themes). + +--- + +### Agents + +You can configure specialized agents for specific tasks through the `agent` option. + +```jsonc title="codev.jsonc" +{ + "$schema": "https://opencode.ai/config.json", + "agent": { + "code-reviewer": { + "description": "Reviews code for best practices and potential issues", + "model": "anthropic/claude-sonnet-4-5", + "prompt": "You are a code reviewer. Focus on security, performance, and maintainability.", + "tools": { + // Disable file modification tools for review-only agent + "write": false, + "edit": false, + }, + }, + }, +} +``` + +You can also define agents using markdown files in `~/.config/codev/agents/` or `.codev/agents/`. [Learn more here](/docs/agents). + +--- + +### Default agent + +You can set the default agent using the `default_agent` option. This determines which agent is used when none is explicitly specified. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "default_agent": "plan" +} +``` + +The default agent must be a primary agent (not a subagent). This can be a built-in agent like `"build"` or `"plan"`, or a [custom agent](/docs/agents) you've defined. If the specified agent doesn't exist or is a subagent, CoDev Code will fall back to `"build"` with a warning. + +This setting applies across all interfaces: TUI, CLI (`codev run`), desktop app, and GitHub Action. + +--- + +### Subagent depth + +You can control how deeply subagents can invoke other subagents using the `subagent_depth` option. + +```json title="opencode.json" +{ + "$schema": "https://opencode.ai/config.json", + "subagent_depth": 2 +} +``` + +The default is `1`, which allows primary agents to launch subagents but prevents those subagents from launching additional subagents. Set it to `2` to allow one additional level of nested subagents, or `0` to prevent all subagent launches. + +--- + +### Sharing + +You can configure the [share](/docs/share) feature through the `share` option. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "share": "manual" +} +``` + +This takes: + +- `"manual"` - Allow manual sharing via commands (default) +- `"auto"` - Automatically share new conversations +- `"disabled"` - Disable sharing entirely + +By default, sharing is set to manual mode where you need to explicitly share conversations using the `/share` command. + +--- + +### Commands + +You can configure custom commands for repetitive tasks through the `command` option. + +```jsonc title="codev.jsonc" +{ + "$schema": "https://opencode.ai/config.json", + "command": { + "test": { + "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.", + "description": "Run tests with coverage", + "agent": "build", + "model": "anthropic/claude-haiku-4-5", + }, + "component": { + "template": "Create a new React component named $ARGUMENTS with TypeScript support.\nInclude proper typing and basic structure.", + "description": "Create a new component", + }, + }, +} +``` + +You can also define commands using markdown files in `~/.config/codev/commands/` or `.codev/commands/`. [Learn more here](/docs/commands). + +--- + +### Keybinds + +Customize TUI keyboard shortcuts in `tui.json` with `keybinds`. + +```json title="tui.json" +{ + "$schema": "https://opencode.ai/tui.json", + "keybinds": { + "command_list": "ctrl+p" + } +} +``` + +`keybinds` is merged with built-in defaults, so you only need to configure the shortcuts you want to change. + +[Learn more here](/docs/keybinds). + +--- + +### Snapshot + +CoDev Code uses snapshots to track file changes during agent operations, enabling you to undo and revert changes within a session. Snapshots are enabled by default. + +For large repositories or projects with many submodules, the snapshot system can cause slow indexing and significant disk usage as it tracks all changes using an internal git repository. You can disable snapshots using the `snapshot` option. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "snapshot": false +} +``` + +Note that disabling snapshots means changes made by the agent cannot be rolled back through the UI. + +--- + +### Autoupdate + +CoDev Code will automatically download any new updates when it starts up. You can disable this with the `autoupdate` option. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "autoupdate": false +} +``` + +If you don't want updates but want to be notified when a new version is available, set `autoupdate` to `"notify"`. +Notice that this only works if it was not installed using a package manager such as Homebrew. + +--- + +### Formatters + +You can enable and configure code formatters through the `formatter` option. Omit it to keep formatters disabled. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "formatter": true +} +``` + +Use an object to keep built-ins enabled while configuring overrides or custom formatters. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "formatter": { + "prettier": { + "disabled": true + }, + "custom-prettier": { + "command": ["npx", "prettier", "--write", "$FILE"], + "environment": { + "NODE_ENV": "development" + }, + "extensions": [".js", ".ts", ".jsx", ".tsx"] + } + } +} +``` + +[Learn more about formatters here](/docs/formatters). + +--- + +### LSP Servers + +You can enable and configure LSP servers through the `lsp` option. Omit it to keep LSP disabled. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "lsp": true +} +``` + +Use an object to keep built-ins enabled while configuring overrides or custom LSP servers. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "lsp": { + "typescript": { + "disabled": true + } + } +} +``` + +[Learn more about LSP servers here](/docs/lsp). + +--- + +### Permissions + +By default, CoDev Code **allows all operations** without requiring explicit approval. You can change this using the `permission` option. + +For example, to ensure that the `edit` and `bash` tools require user approval: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "edit": "ask", + "bash": "ask" + } +} +``` + +[Learn more about permissions here](/docs/permissions). + +--- + +### Compaction + +You can control context compaction behavior through the `compaction` option. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "compaction": { + "auto": true, + "prune": false, + "reserved": 10000 + } +} +``` + +- `auto` - Automatically compact the session when context is full (default: `true`). +- `prune` - Remove old tool outputs to save tokens (default: `false`). Set to `true` to enable pruning. +- `reserved` - Token buffer for compaction. Leaves enough window to avoid overflow during compaction. + +--- + +### Watcher + +You can configure file watcher ignore patterns through the `watcher` option. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "watcher": { + "ignore": ["node_modules/**", "dist/**", ".git/**"] + } +} +``` + +Patterns follow glob syntax. Use this to exclude noisy directories from file watching. + +--- + +### MCP servers + +You can configure MCP servers you want to use through the `mcp` option. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "mcp": {} +} +``` + +[Learn more here](/docs/mcp-servers). + +--- + +### Plugins + +[Plugins](/docs/plugins) extend CoDev Code with custom tools, hooks, and integrations. + +Place plugin files in `.codev/plugins/` or `~/.config/codev/plugins/`. You can also load plugins from npm through the `plugin` option. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "plugin": ["opencode-helicone-session", "@my-org/custom-plugin"] +} +``` + +[Learn more here](/docs/plugins). + +--- + +### Instructions + +You can configure the instructions for the model you're using through the `instructions` option. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "instructions": ["CONTRIBUTING.md", "docs/guidelines.md", ".cursor/rules/*.md"] +} +``` + +This takes an array of paths and glob patterns to instruction files. [Learn more +about rules here](/docs/rules). + +--- + +### Disabled providers + +You can disable providers that are loaded automatically through the `disabled_providers` option. This is useful when you want to prevent certain providers from being loaded even if their credentials are available. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "disabled_providers": ["openai", "gemini"] +} +``` + +:::note +The `disabled_providers` takes priority over `enabled_providers`. +::: + +The `disabled_providers` option accepts an array of provider IDs. When a provider is disabled: + +- It won't be loaded even if environment variables are set. +- It won't be loaded even if API keys are configured through the `/connect` command. +- The provider's models won't appear in the model selection list. + +--- + +### Enabled providers + +You can specify an allowlist of providers through the `enabled_providers` option. When set, only the specified providers will be enabled and all others will be ignored. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "enabled_providers": ["anthropic", "openai"] +} +``` + +This is useful when you want to restrict CoDev Code to only use specific providers rather than disabling them one by one. + +:::note +The `disabled_providers` takes priority over `enabled_providers`. +::: + +If a provider appears in both `enabled_providers` and `disabled_providers`, the `disabled_providers` takes priority for backwards compatibility. + +--- + +### Experimental + +The `experimental` key contains options that are under active development. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "experimental": {} +} +``` + +:::caution +Experimental options are not stable. They may change or be removed without notice. +::: + +--- + +## Variables + +You can use variable substitution in your config files to reference environment variables and file contents. + +--- + +### Env vars + +Use `{env:VARIABLE_NAME}` to substitute environment variables: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "model": "{env:CODEV_MODEL}", + "provider": { + "anthropic": { + "models": {}, + "options": { + "apiKey": "{env:ANTHROPIC_API_KEY}" + } + } + } +} +``` + +If the environment variable is not set, it will be replaced with an empty string. + +--- + +### Files + +Use `{file:path/to/file}` to substitute the contents of a file: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "instructions": ["./custom-instructions.md"], + "provider": { + "openai": { + "options": { + "apiKey": "{file:~/.secrets/openai-key}" + } + } + } +} +``` + +File paths can be: + +- Relative to the config file directory +- Or absolute paths starting with `/` or `~` + +These are useful for: + +- Keeping sensitive data like API keys in separate files. +- Including large instruction files without cluttering your config. +- Sharing common configuration snippets across multiple config files. diff --git a/packages/web/src/content/docs/custom-tools.mdx b/packages/web/src/content/docs/custom-tools.mdx new file mode 100644 index 0000000000..2f59023494 --- /dev/null +++ b/packages/web/src/content/docs/custom-tools.mdx @@ -0,0 +1,196 @@ +--- +title: Custom Tools +description: Create tools the LLM can call in CoDev Code. +--- + +Custom tools are functions you create that the LLM can call during conversations. They work alongside CoDev Code's [built-in tools](/docs/tools) like `read`, `write`, and `bash`. + +--- + +## Creating a tool + +Tools are defined as **TypeScript** or **JavaScript** files. However, the tool definition can invoke scripts written in **any language** — TypeScript or JavaScript is only used for the tool definition itself. + +--- + +### Location + +They can be defined: + +- Locally by placing them in the `.codev/tools/` directory of your project. +- Or globally, by placing them in `~/.config/codev/tools/`. + +--- + +### Structure + +The easiest way to create tools is using the `tool()` helper which provides type-safety and validation. + +```ts title=".codev/tools/database.ts" {1} +import { tool } from "@opencode-ai/plugin" + +export default tool({ + description: "Query the project database", + args: { + query: tool.schema.string().describe("SQL query to execute"), + }, + async execute(args) { + // Your database logic here + return `Executed query: ${args.query}` + }, +}) +``` + +The **filename** becomes the **tool name**. The above creates a `database` tool. + +--- + +#### Multiple tools per file + +You can also export multiple tools from a single file. Each export becomes **a separate tool** with the name **`_`**: + +```ts title=".codev/tools/math.ts" +import { tool } from "@opencode-ai/plugin" + +export const add = tool({ + description: "Add two numbers", + args: { + a: tool.schema.number().describe("First number"), + b: tool.schema.number().describe("Second number"), + }, + async execute(args) { + return (args.a + args.b).toString() + }, +}) + +export const multiply = tool({ + description: "Multiply two numbers", + args: { + a: tool.schema.number().describe("First number"), + b: tool.schema.number().describe("Second number"), + }, + async execute(args) { + return (args.a * args.b).toString() + }, +}) +``` + +This creates two tools: `math_add` and `math_multiply`. + +--- + +#### Name collisions with built-in tools + +Custom tools are keyed by tool name. If a custom tool uses the same name as a built-in tool, the custom tool takes precedence. + +For example, this file replaces the built-in `bash` tool: + +```ts title=".codev/tools/bash.ts" +import { tool } from "@opencode-ai/plugin" + +export default tool({ + description: "Restricted bash wrapper", + args: { + command: tool.schema.string(), + }, + async execute(args) { + return `blocked: ${args.command}` + }, +}) +``` + +:::note +Prefer unique names unless you intentionally want to replace a built-in tool. If you want to disable a built in tool but not override it, use [permissions](/docs/permissions). +::: + +--- + +### Arguments + +You can use `tool.schema`, which is just [Zod](https://zod.dev), to define argument types. + +```ts "tool.schema" +args: { + query: tool.schema.string().describe("SQL query to execute") +} +``` + +You can also import [Zod](https://zod.dev) directly and return a plain object: + +```ts {6} +import { z } from "zod" + +export default { + description: "Tool description", + args: { + param: z.string().describe("Parameter description"), + }, + async execute(args, context) { + // Tool implementation + return "result" + }, +} +``` + +--- + +### Context + +Tools receive context about the current session: + +```ts title=".codev/tools/project.ts" {8} +import { tool } from "@opencode-ai/plugin" + +export default tool({ + description: "Get project information", + args: {}, + async execute(args, context) { + // Access context information + const { agent, sessionID, messageID, directory, worktree } = context + return `Agent: ${agent}, Session: ${sessionID}, Message: ${messageID}, Directory: ${directory}, Worktree: ${worktree}` + }, +}) +``` + +Use `context.directory` for the session working directory. +Use `context.worktree` for the git worktree root. + +--- + +## Examples + +### Write a tool in Python + +You can write your tools in any language you want. Here's an example that adds two numbers using Python. + +First, create the tool as a Python script: + +```python title=".codev/tools/add.py" +import sys + +a = int(sys.argv[1]) +b = int(sys.argv[2]) +print(a + b) +``` + +Then create the tool definition that invokes it: + +```ts title=".codev/tools/python-add.ts" {10} +import { tool } from "@opencode-ai/plugin" +import path from "path" + +export default tool({ + description: "Add two numbers using Python", + args: { + a: tool.schema.number().describe("First number"), + b: tool.schema.number().describe("Second number"), + }, + async execute(args, context) { + const script = path.join(context.worktree, ".codev/tools/add.py") + const result = await Bun.$`python3 ${script} ${args.a} ${args.b}`.text() + return result.trim() + }, +}) +``` + +Here we are using the [`Bun.$`](https://bun.com/docs/runtime/shell) utility to run the Python script. diff --git a/packages/web/src/content/docs/ecosystem.mdx b/packages/web/src/content/docs/ecosystem.mdx new file mode 100644 index 0000000000..74e5137928 --- /dev/null +++ b/packages/web/src/content/docs/ecosystem.mdx @@ -0,0 +1,83 @@ +--- +title: Ecosystem +description: Projects and integrations built with CoDev Code. +--- + +A collection of community projects built on CoDev Code. + +:::note +Want to add your CoDev Code related project to this list? Submit a PR. +::: + +You can also check out [awesome-opencode](https://github.com/awesome-opencode/awesome-opencode) and [opencode.cafe](https://opencode.cafe), a community that aggregates the ecosystem and community. + +--- + +## Plugins + +| Name | Description | +| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| [opencode-daytona](https://github.com/daytonaio/daytona/tree/main/libs/opencode-plugin) | Automatically run CoDev Code sessions in isolated Daytona sandboxes with git sync and live previews | +| [opencode-helicone-session](https://github.com/H2Shami/opencode-helicone-session) | Automatically inject Helicone session headers for request grouping | +| [opencode-type-inject](https://github.com/nick-vi/opencode-type-inject) | Auto-inject TypeScript/Svelte types into file reads with lookup tools | +| [opencode-openai-codex-auth](https://github.com/numman-ali/opencode-openai-codex-auth) | Use your ChatGPT Plus/Pro subscription instead of API credits | +| [opencode-gemini-auth](https://github.com/jenslys/opencode-gemini-auth) | Use your existing Gemini plan instead of API billing | +| [opencode-antigravity-auth](https://github.com/NoeFabris/opencode-antigravity-auth) | Use Antigravity's free models instead of API billing | +| [opencode-devcontainers](https://github.com/athal7/opencode-devcontainers) | Multi-branch devcontainer isolation with shallow clones and auto-assigned ports | +| [opencode-google-antigravity-auth](https://github.com/shekohex/opencode-google-antigravity-auth) | Google Antigravity OAuth Plugin, with support for Google Search, and more robust API handling | +| [opencode-dynamic-context-pruning](https://github.com/Tarquinen/opencode-dynamic-context-pruning) | Optimize token usage by pruning obsolete tool outputs | +| [opencode-vibeguard](https://github.com/inkdust2021/opencode-vibeguard) | Redact secrets/PII into VibeGuard-style placeholders before LLM calls; restore locally | +| [opencode-websearch-cited](https://github.com/ghoulr/opencode-websearch-cited.git) | Add native websearch support for supported providers with Google grounded style | +| [opencode-pty](https://github.com/shekohex/opencode-pty.git) | Enables AI agents to run background processes in a PTY, send interactive input to them. | +| [opencode-shell-strategy](https://github.com/JRedeker/opencode-shell-strategy) | Instructions for non-interactive shell commands - prevents hangs from TTY-dependent operations | +| [opencode-wakatime](https://github.com/angristan/opencode-wakatime) | Track CoDev Code usage with Wakatime | +| [opencode-md-table-formatter](https://github.com/franlol/opencode-md-table-formatter/tree/main) | Clean up markdown tables produced by LLMs | +| [opencode-morph-fast-apply](https://github.com/JRedeker/opencode-morph-fast-apply) | 10x faster code editing with Morph Fast Apply API and lazy edit markers | +| [opencode-morph-plugin](https://github.com/morphllm/opencode-morph-plugin) | Fast Apply editing, WarpGrep codebase search, and context compaction via Morph | +| [oh-my-opencode](https://github.com/code-yeongyu/oh-my-opencode) | Background agents, pre-built LSP/AST/MCP tools, curated agents, Claude Code compatible | +| [opencode-notificator](https://github.com/panta82/opencode-notificator) | Desktop notifications and sound alerts for CoDev Code sessions | +| [opencode-notifier](https://github.com/mohak34/opencode-notifier) | Desktop notifications and sound alerts for permission, completion, and error events | +| [opencode-zellij-namer](https://github.com/24601/opencode-zellij-namer) | AI-powered automatic Zellij session naming based on CoDev Code context | +| [opencode-skillful](https://github.com/zenobi-us/opencode-skillful) | Allow CoDev Code agents to lazy load prompts on demand with skill discovery and injection | +| [opencode-supermemory](https://github.com/supermemoryai/opencode-supermemory) | Persistent memory across sessions using Supermemory | +| [@plannotator/opencode](https://github.com/backnotprop/plannotator/tree/main/apps/opencode-plugin) | Interactive plan review with visual annotation and private/offline sharing | +| [@openspoon/subtask2](https://github.com/spoons-and-mirrors/subtask2) | Extend CoDev Code /commands into a powerful orchestration system with granular flow control | +| [opencode-scheduler](https://github.com/different-ai/opencode-scheduler) | Schedule recurring jobs using launchd (Mac) or systemd (Linux) with cron syntax | +| [opencode-conductor](https://github.com/derekbar90/opencode-conductor) | Protocol-Driven Workflow: Automation of the Context -> Spec -> Plan -> Implement lifecycle. | +| [micode](https://github.com/vtemian/micode) | Structured Brainstorm → Plan → Implement workflow with session continuity | +| [octto](https://github.com/vtemian/octto) | Interactive browser UI for AI brainstorming with multi-question forms | +| [opencode-background-agents](https://github.com/kdcokenny/opencode-background-agents) | Claude Code-style background agents with async delegation and context persistence | +| [opencode-notify](https://github.com/kdcokenny/opencode-notify) | Native OS notifications for CoDev Code – know when tasks complete | +| [opencode-workspace](https://github.com/kdcokenny/opencode-workspace) | Bundled multi-agent orchestration harness – 16 components, one install | +| [opencode-worktree](https://github.com/kdcokenny/opencode-worktree) | Zero-friction git worktrees for CoDev Code | +| [opencode-sentry-monitor](https://github.com/stolinski/opencode-sentry-monitor) | Trace and debug your AI agents with Sentry AI Monitoring | +| [opencode-firecrawl](https://github.com/firecrawl/opencode-firecrawl) | Web scraping, crawling, and search via the Firecrawl CLI | +| [opencode-jfrog-plugin](https://github.com/jfrog/opencode-jfrog-plugin) | JFrog Plugin for seamless integration of CoDev Code users to JFrog platform | +| [opencode-goal-plugin](https://github.com/willytop8/OpenCode-goal-plugin) | Session-scoped `/goal` workflow that keeps objectives in context and auto-continues until complete | + +--- + +## Projects + +| Name | Description | +| ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- | +| [kimaki](https://github.com/remorses/kimaki) | Discord bot to control CoDev Code sessions, built on the SDK | +| [opencode.nvim](https://github.com/NickvanDyke/opencode.nvim) | Neovim plugin for editor-aware prompts, built on the API | +| [portal](https://github.com/hosenur/portal) | Mobile-first web UI for CoDev Code over Tailscale/VPN | +| [opencode plugin template](https://github.com/zenobi-us/opencode-plugin-template/) | Template for building CoDev Code plugins | +| [opencode.nvim](https://github.com/sudo-tee/opencode.nvim) | Neovim frontend for CoDev Code - a terminal-based AI coding agent | +| [ai-sdk-provider-opencode-sdk](https://github.com/ben-vargas/ai-sdk-provider-opencode-sdk) | Vercel AI SDK provider for using CoDev Code via @opencode-ai/sdk | +| [OpenChamber](https://github.com/btriapitsyn/openchamber) | Web / Desktop App and VS Code Extension for CoDev Code | +| [OpenCode-Obsidian](https://github.com/mtymek/opencode-obsidian) | Obsidian plugin that embeds CoDev Code in Obsidian's UI | +| [OpenWork](https://github.com/different-ai/openwork) | An open-source alternative to Claude Cowork, powered by CoDev Code | +| [ocx](https://github.com/kdcokenny/ocx) | CoDev Code extension manager with portable, isolated profiles. | +| [CodeNomad](https://github.com/NeuralNomadsAI/CodeNomad) | Desktop, Web, Mobile and Remote Client App for CoDev Code | + +--- + +## Agents + +| Name | Description | +| ----------------------------------------------------------------- | ------------------------------------------------------------ | +| [Agentic](https://github.com/Cluster444/agentic) | Modular AI agents and commands for structured development | +| [opencode-agents](https://github.com/darrenhinde/opencode-agents) | Configs, prompts, agents, and plugins for enhanced workflows | diff --git a/packages/web/src/content/docs/enterprise.mdx b/packages/web/src/content/docs/enterprise.mdx new file mode 100644 index 0000000000..9e469fd842 --- /dev/null +++ b/packages/web/src/content/docs/enterprise.mdx @@ -0,0 +1,169 @@ +--- +title: Enterprise +description: Using CoDev Code securely in your organization. +--- + +export const enterprise = "https://opencode.ai/enterprise" + +CoDev Code Enterprise is for organizations that want to ensure that their code and data never leaves their infrastructure. It can do this by using a centralized config that integrates with your SSO and internal AI gateway. + +:::note +CoDev Code does not store any of your code or context data. +::: + +To get started with CoDev Code Enterprise: + +1. Do a trial internally with your team. +2. **Contact us** to discuss pricing and implementation options. + +--- + +## Trial + +CoDev Code is open source and does not store any of your code or context data, so your developers can simply [get started](/docs/) and carry out a trial. + +--- + +### Data handling + +**CoDev Code does not store your code or context data.** All processing happens locally or through direct API calls to your AI provider. + +This means that as long as you are using a provider you trust, or an internal +AI gateway, you can use CoDev Code securely. + +The only caveat here is the optional `/share` feature. + +--- + +#### Sharing conversations + +If a user enables the `/share` feature, the conversation and the data associated with it are sent to the service we use to host these share pages at opencode.ai. + +The data is currently served through our CDN's edge network, and is cached on the edge near your users. + +We recommend you disable this for your trial. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "share": "disabled" +} +``` + +[Learn more about sharing](/docs/share). + +--- + +### Code ownership + +**You own all code produced by CoDev Code.** There are no licensing restrictions or ownership claims. + +--- + +## Pricing + +We use a per-seat model for CoDev Code Enterprise. If you have your own LLM gateway, we do not charge for tokens used. For further details about pricing and implementation options, **contact us**. + +--- + +## Deployment + +Once you have completed your trial and you are ready to use CoDev Code at +your organization, you can **contact us** to discuss +pricing and implementation options. + +--- + +### Central Config + +We can set up CoDev Code to use a single central config for your entire organization. + +This centralized config can integrate with your SSO provider and ensures all users access only your internal AI gateway. + +--- + +### SSO integration + +Through the central config, CoDev Code can integrate with your organization's SSO provider for authentication. + +This allows CoDev Code to obtain credentials for your internal AI gateway through your existing identity management system. + +--- + +### Internal AI gateway + +With the central config, CoDev Code can also be configured to use only your internal AI gateway. + +You can also disable all other AI providers, ensuring all requests go through your organization's approved infrastructure. + +--- + +### Self-hosting + +While we recommend disabling the share pages to ensure your data never leaves +your organization, we can also help you self-host them on your infrastructure. + +This is currently on our roadmap. If you're interested, **let us know**. + +--- + +## FAQ + +
+What is CoDev Code Enterprise? + +CoDev Code Enterprise is for organizations that want to ensure that their code and data never leaves their infrastructure. It can do this by using a centralized config that integrates with your SSO and internal AI gateway. + +
+ +
+How do I get started with CoDev Code Enterprise? + +Simply start with an internal trial with your team. CoDev Code by default does not store your code or context data, making it easy to get started. + +Then **contact us** to discuss pricing and implementation options. + +
+ +
+How does enterprise pricing work? + +We offer per-seat enterprise pricing. If you have your own LLM gateway, we do not charge for tokens used. For further details, **contact us** for a custom quote based on your organization's needs. + +
+ +
+Is my data secure with CoDev Code Enterprise? + +Yes. CoDev Code does not store your code or context data. All processing happens locally or through direct API calls to your AI provider. With central config and SSO integration, your data remains secure within your organization's infrastructure. + +
+ +
+Can we use our own private NPM registry? + +CoDev Code supports private npm registries through Bun's native `.npmrc` file support. If your organization uses a private registry, such as JFrog Artifactory, Nexus, or similar, ensure developers are authenticated before running CoDev Code. + +To set up authentication with your private registry: + +```bash +npm login --registry=https://your-company.jfrog.io/api/npm/npm-virtual/ +``` + +This creates `~/.npmrc` with authentication details. CoDev Code will automatically +pick this up. + +:::caution +You must be logged into the private registry before running CoDev Code. +::: + +Alternatively, you can manually configure a `.npmrc` file: + +```bash title="~/.npmrc" +registry=https://your-company.jfrog.io/api/npm/npm-virtual/ +//your-company.jfrog.io/api/npm/npm-virtual/:_authToken=${NPM_AUTH_TOKEN} +``` + +Developers must be logged into the private registry before running CoDev Code to ensure packages can be installed from your enterprise registry. + +
diff --git a/packages/web/src/content/docs/formatters.mdx b/packages/web/src/content/docs/formatters.mdx new file mode 100644 index 0000000000..9938fd03b7 --- /dev/null +++ b/packages/web/src/content/docs/formatters.mdx @@ -0,0 +1,143 @@ +--- +title: Formatters +description: CoDev Code uses language specific formatters. +--- + +CoDev Code can format files after they are written or edited using language-specific formatters. Formatters are disabled by default; enable them in your config before CoDev Code will run them. + +--- + +## Built-in + +CoDev Code comes with several built-in formatters for popular languages and frameworks. Below is a list of the formatters, supported file extensions, and commands or config options it needs. + +| Formatter | Extensions | Requirements | +| -------------------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| air | .R | `air` command available | +| biome | .js, .jsx, .ts, .tsx, .html, .css, .md, .json, .yaml, and [more](https://biomejs.dev/) | `biome.json(c)` config file | +| cargofmt | .rs | `cargo fmt` command available | +| clang-format | .c, .cpp, .h, .hpp, .ino, and [more](https://clang.llvm.org/docs/ClangFormat.html) | `.clang-format` config file | +| cljfmt | .clj, .cljs, .cljc, .edn | `cljfmt` command available | +| dart | .dart | `dart` command available | +| dfmt | .d | `dfmt` command available | +| gleam | .gleam | `gleam` command available | +| gofmt | .go | `gofmt` command available | +| htmlbeautifier | .erb, .html.erb | `htmlbeautifier` command available | +| ktlint | .kt, .kts | `ktlint` command available | +| mix | .ex, .exs, .eex, .heex, .leex, .neex, .sface | `mix` command available | +| nixfmt | .nix | `nixfmt` command available | +| ocamlformat | .ml, .mli | `ocamlformat` command available and `.ocamlformat` config file | +| ormolu | .hs | `ormolu` command available | +| oxfmt (Experimental) | .js, .jsx, .ts, .tsx | `oxfmt` dependency in `package.json` and an [experimental env variable flag](/docs/cli/#experimental) | +| pint | .php | `laravel/pint` dependency in `composer.json` | +| prettier | .js, .jsx, .ts, .tsx, .html, .css, .md, .json, .yaml, and [more](https://prettier.io/docs/en/index.html) | `prettier` dependency in `package.json` | +| rubocop | .rb, .rake, .gemspec, .ru | `rubocop` command available | +| ruff | .py, .pyi | `ruff` command available with config | +| rustfmt | .rs | `rustfmt` command available | +| shfmt | .sh, .bash | `shfmt` command available | +| standardrb | .rb, .rake, .gemspec, .ru | `standardrb` command available | +| terraform | .tf, .tfvars | `terraform` command available | +| uv | .py, .pyi | `uv` command available | +| zig | .zig, .zon | `zig` command available | + +When formatters are enabled, CoDev Code will use `prettier` for matching files if your project has `prettier` in `package.json`. + +--- + +## How it works + +When CoDev Code writes or edits a file and formatters are enabled, it: + +1. Checks the file extension against all enabled formatters. +2. Runs the appropriate formatter command on the file. +3. Applies the formatting changes. + +This process happens in the background for enabled formatters. + +--- + +## Configure + +You can enable and customize formatters through the `formatter` section in your CoDev Code config. + +To enable all built-in formatters, set `formatter` to `true`. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "formatter": true +} +``` + +Use an object to keep built-ins enabled while configuring overrides or custom formatters. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "formatter": {} +} +``` + +Each formatter configuration supports the following: + +| Property | Type | Description | +| ------------- | -------- | ------------------------------------------------------------------------------------------ | +| `disabled` | boolean | Set this to `true` to disable the formatter | +| `command` | string[] | The command to run for formatting. Required for custom formatters; optional for built-ins. | +| `environment` | object | Environment variables to set when running the formatter | +| `extensions` | string[] | File extensions this formatter should handle | + +Let's look at some examples. + +--- + +### Disabling formatters + +If `formatter` is omitted, all formatters are disabled. To disable all formatters after another config enabled them, set `formatter` to `false`: + +```json title="codev.json" {3} +{ + "$schema": "https://opencode.ai/config.json", + "formatter": false +} +``` + +To disable a **specific** formatter, set `disabled` to `true`: + +```json title="codev.json" {5} +{ + "$schema": "https://opencode.ai/config.json", + "formatter": { + "prettier": { + "disabled": true + } + } +} +``` + +--- + +### Custom formatters + +You can configure built-in formatters with options like `environment` or `extensions`. To add a custom formatter, specify a `command` and `extensions`: + +```json title="codev.json" {4-14} +{ + "$schema": "https://opencode.ai/config.json", + "formatter": { + "prettier": { + "command": ["npx", "prettier", "--write", "$FILE"], + "environment": { + "NODE_ENV": "development" + }, + "extensions": [".js", ".ts", ".jsx", ".tsx"] + }, + "custom-markdown-formatter": { + "command": ["deno", "fmt", "$FILE"], + "extensions": [".md"] + } + } +} +``` + +The **`$FILE` placeholder** in the command will be replaced with the path to the file being formatted. diff --git a/packages/web/src/content/docs/github.mdx b/packages/web/src/content/docs/github.mdx new file mode 100644 index 0000000000..c4fd525e27 --- /dev/null +++ b/packages/web/src/content/docs/github.mdx @@ -0,0 +1,314 @@ +--- +title: GitHub +description: Use CoDev Code in GitHub issues and pull-requests. +--- + +CoDev Code integrates with your GitHub workflow. Mention `/codev` in your comment, and CoDev Code will execute tasks within your GitHub Actions runner. + +--- + +## Features + +- **Triage issues**: Ask CoDev Code to look into an issue and explain it to you. +- **Fix and implement**: Ask CoDev Code to fix an issue or implement a feature. And it will work in a new branch and submits a PR with all the changes. +- **Secure**: CoDev Code runs inside your GitHub's runners. + +--- + +## Installation + +Run the following command in a project that is in a GitHub repo: + +```bash +codev github install +``` + +This will walk you through creating the workflow file and setting up secrets. + +--- + +### Manual Setup + +Or you can set it up manually. + +1. **Add the workflow** + + Add the following workflow file to `.github/workflows/codev.yml` in your repo. Make sure to set the appropriate `model` and required API keys in `env`. + + ```yml title=".github/workflows/codev.yml" {25,30} + name: codev + + on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + + jobs: + codev: + if: contains(github.event.comment.body, '/codev') + runs-on: ubuntu-latest + permissions: + contents: write + issues: write + pull-requests: write + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 1 + persist-credentials: false + + - name: Run CoDev Code + uses: quickbeard/codev-code/github@main + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + model: anthropic/claude-sonnet-4-20250514 + ``` + + The action authenticates with the workflow's [built-in `GITHUB_TOKEN`](https://docs.github.com/en/actions/tutorials/authenticate-with-github_token) by default, so no GitHub App install is needed. Commits, comments, and pull requests appear as coming from `github-actions[bot]`. + +2. **Store the API keys in secrets** + + In your organization or project **settings**, expand **Secrets and variables** on the left and select **Actions**. And add the required API keys. + +--- + +## Configuration + +- `model`: The model to use with CoDev Code. Takes the format of `provider/model`. This is **required**. +- `agent`: The agent to use. Must be a primary agent. Falls back to `default_agent` from config or `"build"` if not found. +- `share`: Whether to share the CoDev Code session. Defaults to **false**; sharing publishes the session to upstream's share service. +- `prompt`: Optional custom prompt to override the default behavior. Use this to customize how CoDev Code processes requests. +- `mentions`: Comma-separated list of trigger phrases (case-insensitive). Defaults to `/codev`. +- `use_github_token`: Whether to authenticate with the workflow's `GITHUB_TOKEN`. Defaults to **true**. Make sure to grant the required permissions in your workflow: + + ```yaml + permissions: + contents: write + pull-requests: write + issues: write + ``` + + Set it to `false` only if the upstream [opencode-agent GitHub App](https://github.com/apps/opencode-agent) is installed on the repository; the action then exchanges an OIDC token for an app token (this requires `id-token: write` permission), and activity appears as coming from the app. + +--- + +## Supported Events + +CoDev Code can be triggered by the following GitHub events: + +| Event Type | Triggered By | Details | +| ----------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------- | +| `issue_comment` | Comment on an issue or PR | Mention `/codev` in your comment. CoDev Code reads context and can create branches, open PRs, or reply. | +| `pull_request_review_comment` | Comment on specific code lines in a PR | Mention `/codev` while reviewing code. CoDev Code receives file path, line numbers, and diff context. | +| `issues` | Issue opened or edited | Automatically trigger CoDev Code when issues are created or modified. Requires `prompt` input. | +| `pull_request` | PR opened or updated | Automatically trigger CoDev Code when PRs are opened, synchronized, or reopened. Useful for automated reviews. | +| `schedule` | Cron-based schedule | Run CoDev Code on a schedule. Requires `prompt` input. Output goes to logs and PRs (no issue to comment on). | +| `workflow_dispatch` | Manual trigger from GitHub UI | Trigger CoDev Code on demand via Actions tab. Requires `prompt` input. Output goes to logs and PRs. | + +### Schedule Example + +Run CoDev Code on a schedule to perform automated tasks: + +```yaml title=".github/workflows/codev-scheduled.yml" +name: Scheduled CoDev Code Task + +on: + schedule: + - cron: "0 9 * * 1" # Every Monday at 9am UTC + +jobs: + codev: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + issues: write + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Run CoDev Code + uses: quickbeard/codev-code/github@main + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + model: anthropic/claude-sonnet-4-20250514 + prompt: | + Review the codebase for any TODO comments and create a summary. + If you find issues worth addressing, open an issue to track them. +``` + +For scheduled events, the `prompt` input is **required** since there's no comment to extract instructions from. Scheduled workflows run without a user context to permission-check, so the workflow must grant `contents: write` and `pull-requests: write` if you expect CoDev Code to create branches or PRs. + +--- + +### Pull Request Example + +Automatically review PRs when they are opened or updated: + +```yaml title=".github/workflows/codev-review.yml" +name: codev-review + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + +jobs: + review: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + issues: write + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: quickbeard/codev-code/github@main + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + model: anthropic/claude-sonnet-4-20250514 + prompt: | + Review this pull request: + - Check for code quality issues + - Look for potential bugs + - Suggest improvements +``` + +For `pull_request` events, if no `prompt` is provided, CoDev Code defaults to reviewing the pull request. + +--- + +### Issues Triage Example + +Automatically triage new issues. This example filters to accounts older than 30 days to reduce spam: + +```yaml title=".github/workflows/codev-triage.yml" +name: Issue Triage + +on: + issues: + types: [opened] + +jobs: + triage: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + issues: write + steps: + - name: Check account age + id: check + uses: actions/github-script@v7 + with: + script: | + const user = await github.rest.users.getByUsername({ + username: context.payload.issue.user.login + }); + const created = new Date(user.data.created_at); + const days = (Date.now() - created) / (1000 * 60 * 60 * 24); + return days >= 30; + result-encoding: string + + - uses: actions/checkout@v6 + if: steps.check.outputs.result == 'true' + with: + persist-credentials: false + + - uses: quickbeard/codev-code/github@main + if: steps.check.outputs.result == 'true' + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + model: anthropic/claude-sonnet-4-20250514 + prompt: | + Review this issue. If there's a clear fix or relevant docs: + - Provide documentation links + - Add error handling guidance for code examples + Otherwise, do not comment. +``` + +For `issues` events, the `prompt` input is **required** since there's no comment to extract instructions from. + +--- + +## Custom prompts + +Override the default prompt to customize CoDev Code's behavior for your workflow. + +```yaml title=".github/workflows/codev.yml" +- uses: quickbeard/codev-code/github@main + with: + model: anthropic/claude-sonnet-4-5 + prompt: | + Review this pull request: + - Check for code quality issues + - Look for potential bugs + - Suggest improvements +``` + +This is useful for enforcing specific review criteria, coding standards, or focus areas relevant to your project. + +--- + +## Examples + +Here are some examples of how you can use CoDev Code in GitHub. + +- **Explain an issue** + + Add this comment in a GitHub issue. + + ``` + /codev explain this issue + ``` + + CoDev Code will read the entire thread, including all comments, and reply with a clear explanation. + +- **Fix an issue** + + In a GitHub issue, say: + + ``` + /codev fix this + ``` + + And CoDev Code will create a new branch, implement the changes, and open a PR with the changes. + +- **Review PRs and make changes** + + Leave the following comment on a GitHub PR. + + ``` + Delete the attachment from S3 when the note is removed /codev + ``` + + CoDev Code will implement the requested change and commit it to the same PR. + +- **Review specific code lines** + + Leave a comment directly on code lines in the PR's "Files" tab. CoDev Code automatically detects the file, line numbers, and diff context to provide precise responses. + + ``` + [Comment on specific lines in Files tab] + /codev add error handling here + ``` + + When commenting on specific lines, CoDev Code receives: + - The exact file being reviewed + - The specific lines of code + - The surrounding diff context + - Line number information + + This allows for more targeted requests without needing to specify file paths or line numbers manually. diff --git a/packages/web/src/content/docs/gitlab.mdx b/packages/web/src/content/docs/gitlab.mdx new file mode 100644 index 0000000000..7188f0560f --- /dev/null +++ b/packages/web/src/content/docs/gitlab.mdx @@ -0,0 +1,195 @@ +--- +title: GitLab +description: Use CoDev Code in GitLab issues and merge requests. +--- + +CoDev Code integrates with your GitLab workflow through your GitLab CI/CD pipeline or with GitLab Duo. + +In both cases, CoDev Code will run on your GitLab runners. + +--- + +## GitLab CI + +CoDev Code works in a regular GitLab pipeline. You can build it into a pipeline as a [CI component](https://docs.gitlab.com/ee/ci/components/) + +Here we are using a community-created CI/CD component for CoDev Code — [nagyv/gitlab-opencode](https://gitlab.com/nagyv/gitlab-opencode). + +--- + +### Features + +- **Use custom configuration per job**: Configure CoDev Code with a custom configuration directory, for example `./config/#custom-directory` to enable or disable functionality per CoDev Code invocation. +- **Minimal setup**: The CI component sets up CoDev Code in the background, you only need to create the CoDev Code configuration and the initial prompt. +- **Flexible**: The CI component supports several inputs for customizing its behavior + +--- + +### Setup + +1. Store your CoDev Code authentication JSON as a File type CI environment variables under **Settings** > **CI/CD** > **Variables**. Make sure to mark them as "Masked and hidden". +2. Add the following to your `.gitlab-ci.yml` file. + + ```yaml title=".gitlab-ci.yml" + include: + - component: $CI_SERVER_FQDN/nagyv/gitlab-opencode/opencode@2 + inputs: + config_dir: ${CI_PROJECT_DIR}/opencode-config + auth_json: $CODEV_AUTH_JSON # The variable name for your CoDev Code authentication JSON + command: optional-custom-command + message: "Your prompt here" + ``` + +For more inputs and use cases [check out the docs](https://gitlab.com/explore/catalog/nagyv/gitlab-opencode) for this component. + +--- + +## GitLab Duo + +CoDev Code integrates with your GitLab workflow. +Mention `@opencode` in a comment, and CoDev Code will execute tasks within your GitLab CI pipeline. + +--- + +### Features + +- **Triage issues**: Ask CoDev Code to look into an issue and explain it to you. +- **Fix and implement**: Ask CoDev Code to fix an issue or implement a feature. + It will create a new branch and raise a merge request with the changes. +- **Secure**: CoDev Code runs on your GitLab runners. + +--- + +### Setup + +CoDev Code runs in your GitLab CI/CD pipeline, here's what you'll need to set it up: + +:::tip +Check out the [**GitLab docs**](https://docs.gitlab.com/user/duo_agent_platform/agent_assistant/) for up to date instructions. +::: + +1. Configure your GitLab environment +2. Set up CI/CD +3. Get an AI model provider API key +4. Create a service account +5. Configure CI/CD variables +6. Create a flow config file, here's an example: + +
+ + Flow configuration + + ```yaml + image: node:22-slim + commands: + - echo "Installing CoDev Code" + - npm install --global codev-code + - echo "Installing glab" + - export GITLAB_TOKEN=$GITLAB_TOKEN_OPENCODE + - apt-get update --quiet && apt-get install --yes curl wget gpg git && rm --recursive --force /var/lib/apt/lists/* + - curl --silent --show-error --location "https://raw.githubusercontent.com/upciti/wakemeops/main/assets/install_repository" | bash + - apt-get install --yes glab + - echo "Configuring glab" + - echo $GITLAB_HOST + - echo "Creating CoDev Code auth configuration" + - mkdir --parents ~/.local/share/codev + - | + cat > ~/.local/share/codev/auth.json << EOF + { + "anthropic": { + "type": "api", + "key": "$ANTHROPIC_API_KEY" + } + } + EOF + - echo "Configuring git" + - git config --global user.email "opencode@gitlab.com" + - git config --global user.name "CoDev Code" + - echo "Testing glab" + - glab issue list + - echo "Running CoDev Code" + - | + codev run " + You are an AI assistant helping with GitLab operations. + + Context: $AI_FLOW_CONTEXT + Task: $AI_FLOW_INPUT + Event: $AI_FLOW_EVENT + + Please execute the requested task using the available GitLab tools. + Be thorough in your analysis and provide clear explanations. + + + Please use the glab CLI to access data from GitLab. The glab CLI has already been authenticated. You can run the corresponding commands. + + If you are asked to summarize an MR or issue or asked to provide more information then please post back a note to the MR/Issue so that the user can see it. + You don't need to commit or push up changes, those will be done automatically based on the file changes you make. + + " + - git checkout --branch $CI_WORKLOAD_REF origin/$CI_WORKLOAD_REF + - echo "Checking for git changes and pushing if any exist" + - | + if ! git diff --quiet || ! git diff --cached --quiet || [ --not --zero "$(git ls-files --others --exclude-standard)" ]; then + echo "Git changes detected, adding and pushing..." + git add . + if git diff --cached --quiet; then + echo "No staged changes to commit" + else + echo "Committing changes to branch: $CI_WORKLOAD_REF" + git commit --message "Codex changes" + echo "Pushing changes up to $CI_WORKLOAD_REF" + git push https://gitlab-ci-token:$GITLAB_TOKEN@$GITLAB_HOST/gl-demo-ultimate-dev-ai-epic-17570/test-java-project.git $CI_WORKLOAD_REF + echo "Changes successfully pushed" + fi + else + echo "No git changes detected, skipping push" + fi + variables: + - ANTHROPIC_API_KEY + - GITLAB_TOKEN_OPENCODE + - GITLAB_HOST + ``` + +
+ +You can refer to the [GitLab CLI agents docs](https://docs.gitlab.com/user/duo_agent_platform/agent_assistant/) for detailed instructions. + +--- + +### Examples + +Here are some examples of how you can use CoDev Code in GitLab. + +:::tip +You can configure to use a different trigger phrase than `@opencode`. +::: + +- **Explain an issue** + + Add this comment in a GitLab issue. + + ``` + @opencode explain this issue + ``` + + CoDev Code will read the issue and reply with a clear explanation. + +- **Fix an issue** + + In a GitLab issue, say: + + ``` + @opencode fix this + ``` + + CoDev Code will create a new branch, implement the changes, and open a merge request with the changes. + +- **Review merge requests** + + Leave the following comment on a GitLab merge request. + + ``` + @opencode review this merge request + ``` + + CoDev Code will review the merge request and provide feedback. diff --git a/packages/web/src/content/docs/go.mdx b/packages/web/src/content/docs/go.mdx new file mode 100644 index 0000000000..5594f0a5cf --- /dev/null +++ b/packages/web/src/content/docs/go.mdx @@ -0,0 +1,233 @@ +--- +title: Go +description: Low cost subscription for open coding models. +--- + +import config from "../../../config.mjs" +export const console = config.console +export const email = `mailto:${config.email}` + +OpenCode Go is a low cost subscription — **$5 for your first month**, then **$10/month** — that gives you reliable access to popular open coding models. + +Go works like any other provider in CoDev Code. You subscribe to OpenCode Go and +get your API key. It's **completely optional** and you don't need to use it to +use CoDev Code. + +It is designed primarily for international users, with models hosted in the US, EU, and Singapore for stable global access. + +--- + +## Background + +Open models have gotten really good. They now reach performance close to +proprietary models for coding tasks. And because many providers can serve them +competitively, they are usually far cheaper. + +However, getting reliable, low latency access to them can be difficult. Providers +vary in quality and availability. + +:::tip +We tested a select group of models and providers that work well with CoDev Code. +::: + +To fix this, we did a couple of things: + +1. We tested a select group of open models and talked to their teams about how to + best run them. +2. We then worked with a few providers to make sure these were being served + correctly. +3. Finally, we benchmarked the combination of the model/provider and came up + with a list that we feel good recommending. + +OpenCode Go gives you access to these models for **$5 for your first month**, then **$10/month**. + +--- + +## How it works + +OpenCode Go works like any other provider in CoDev Code. + +1. You sign in to **OpenCode Zen**, subscribe to Go, and + copy your API key. +2. You run the `/connect` command in the TUI, select `OpenCode Go`, and paste + your API key. +3. Run `/models` in the TUI to see the list of models available through Go. + +:::note +Only one member per workspace can subscribe to OpenCode Go. +::: + +The current list of models includes: + +- **Grok 4.5** +- **GLM-5.2** +- **GLM-5.1** +- **Kimi K3** +- **Kimi K2.7 Code** +- **Kimi K2.6** +- **MiMo-V2.5** +- **MiMo-V2.5-Pro** +- **MiniMax M3** +- **MiniMax M2.7** +- **Qwen3.7 Max** +- **Qwen3.7 Plus** +- **Qwen3.6 Plus** +- **DeepSeek V4 Pro** +- **DeepSeek V4 Flash** + +The list of models may change as we test and add new ones. + +--- + +## Usage limits + +OpenCode Go includes the following limits: + +- **5 hour limit** — $12 of usage +- **Weekly limit** — $30 of usage +- **Monthly limit** — $60 of usage + +Limits are defined in dollar value. This means your actual request count depends on the model you use. Cheaper models like DeepSeek V4 Flash allow for more requests, while higher-cost models like GLM-5.2 allow for fewer. + +The table below provides an estimated request count based on typical Go usage patterns: + +| Model | requests per 5 hour | requests per week | requests per month | +| ----------------- | ------------------- | ----------------- | ------------------ | +| Grok 4.5 | 120 | 300 | 600 | +| GLM-5.2 | 880 | 2,150 | 4,300 | +| GLM-5.1 | 880 | 2,150 | 4,300 | +| Kimi K3 | 110 | 250 | 490 | +| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 | +| Kimi K2.6 | 1,150 | 2,880 | 5,750 | +| MiMo-V2.5 | 30,100 | 75,200 | 150,400 | +| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 | +| MiniMax M3 | 3,200 | 8,000 | 16,000 | +| MiniMax M2.7 | 3,400 | 8,500 | 17,000 | +| Qwen3.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 | +| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 | +| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 | +| DeepSeek V4 Flash | 31,650 | 79,050 | 158,150 | + +The estimates are based on observed request patterns: + +- Grok 4.5 — 1,100 input, 71,500 cached, 220 output tokens per request +- GLM-5.2/5.1 — 700 input, 52,000 cached, 150 output tokens per request +- Kimi K3 — 1,050 input, 76,500 cached, 300 output tokens per request +- Kimi K2.7/K2.6 — 870 input, 55,000 cached, 200 output tokens per request +- DeepSeek V4 Pro — 750 input, 82,000 cached, 290 output tokens per request +- DeepSeek V4 Flash — 790 input, 68,000 cached, 280 output tokens per request +- MiniMax M3 — 510 input, 56,000 cached, 190 output tokens per request +- MiniMax M2.7 — 300 input, 55,000 cached, 125 output tokens per request +- MiMo-V2.5 — 830 input, 71,500 cached, 295 output tokens per request +- MiMo-V2.5-Pro — 790 input, 86,000 cached, 305 output tokens per request +- Qwen3.7 Max — 420 input, 66,000 cached, 200 output tokens per request +- Qwen3.7 Plus — 500 input, 57,000 cached, 190 output tokens per request +- Qwen3.6 Plus — 500 input, 57,000 cached, 190 output tokens per request + +The estimates are also based on the following prices per 1M tokens and the monthly usage included with each model: + +| Model | Input | Output | Cached Read | Cached Write | Usage | +| ---------------------------- | ------ | ------ | ----------- | ------------ | ----- | +| Grok 4.5 | $2.00 | $6.00 | $0.30 | - | $15 | +| GLM-5.2 | $1.40 | $4.40 | $0.26 | - | $60 | +| GLM-5.1 | $1.40 | $4.40 | $0.26 | - | $60 | +| Kimi K3 | $3.00 | $15.00 | $0.30 | - | $15 | +| Kimi K2.7 Code | $0.95 | $4.00 | $0.19 | - | $60 | +| Kimi K2.6 | $0.95 | $4.00 | $0.16 | - | $60 | +| MiMo V2.5 | $0.14 | $0.28 | $0.0028 | - | $60 | +| MiMo V2.5 Pro | $0.435 | $0.87 | $0.003625 | - | $15 | +| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 | +| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 | +| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 | +| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 | +| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 | +| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 | +| Qwen3.6 Plus (≤ 256K tokens) | $0.50 | $3.00 | $0.05 | $0.625 | $60 | +| Qwen3.6 Plus (> 256K tokens) | $2.00 | $6.00 | $0.20 | $2.50 | $60 | +| DeepSeek V4 Pro | $0.435 | $0.87 | $0.003625 | - | $15 | +| DeepSeek V4 Flash | $0.14 | $0.28 | $0.0028 | - | $60 | + +You can track your current usage in the **console**. + +:::tip +If you reach the usage limit, you can continue using the free models. +::: + +Usage limits may change as we learn from early usage and feedback. + +--- + +### Usage beyond limits + +If you also have credits on your Zen balance, you can enable the **Use balance** +option in the console. When enabled, Go will fall back to your Zen balance +after you've reached your usage limits instead of blocking requests. + +--- + +### Why some models have lower usage + +With Go, you pay $10/month and we aim to give you 6x that in usage. + +For most models, we make this work through bulk discounts and reserved GPU capacity. We then pass those savings on to you through the 6x multiplier. + +For some models, we haven't had the opportunity to negotiate a discount or host them at a lower cost, either because the model is new or because their public pricing is already discounted. + +For these models, you still get a little more than if you paid the model providers directly; this is why their usage mulitplier is lower in the table above. + +--- + +## Endpoints + +You can also access Go models through the following API endpoints. + +| Model | Model ID | Endpoint | AI SDK Package | +| ----------------- | ----------------- | ------------------------------------------------ | --------------------------- | +| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM-5.2 | glm-5.2 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| Kimi K3 | kimi-k3 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| Kimi K2.7 Code | kimi-k2.7-code | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| Kimi K2.6 | kimi-k2.6 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| DeepSeek V4 Pro | deepseek-v4-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| DeepSeek V4 Flash | deepseek-v4-flash | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| MiMo-V2.5 | mimo-v2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| MiMo-V2.5-Pro | mimo-v2.5-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` | +| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` | +| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` | +| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` | +| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` | +| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` | + +The [model id](/docs/config/#models) in your CoDev Code config +uses the format `opencode-go/`. For example, for Kimi K3, you would +use `opencode-go/kimi-k3` in your config. + +--- + +### Models + +You can fetch the full list of available models and their metadata from: + +``` +https://opencode.ai/zen/go/v1/models +``` + +--- + +## Privacy + +The plan is designed primarily for international users, with models hosted in the US, EU, and Singapore for stable global access. Our providers follow a zero-retention policy and do not use your data for model training. + +--- + +## Goals + +We created OpenCode Go to: + +1. Make AI coding **accessible** to more people with a low cost subscription. +2. Provide **reliable** access to the best open coding models. +3. Curate models that are **tested and benchmarked** for coding agent use. +4. Have **no lock-in** by allowing you to use any other provider with CoDev Code as well. diff --git a/packages/web/src/content/docs/ide.mdx b/packages/web/src/content/docs/ide.mdx new file mode 100644 index 0000000000..320bc4c95f --- /dev/null +++ b/packages/web/src/content/docs/ide.mdx @@ -0,0 +1,55 @@ +--- +title: IDE +description: The CoDev Code extension for VS Code, Cursor, and other IDEs +--- + +CoDev Code integrates with VS Code, Cursor, or any IDE that supports a terminal. Just run `codev` in the terminal to get started. + +--- + +## Usage + +- **Quick Launch**: Use `Cmd+Esc` (Mac) or `Ctrl+Esc` (Windows/Linux) to open CoDev Code in a split terminal view, or focus an existing terminal session if one is already running. +- **New Session**: Use `Cmd+Shift+Esc` (Mac) or `Ctrl+Shift+Esc` (Windows/Linux) to start a new CoDev Code terminal session, even if one is already open. You can also click the CoDev Code button in the UI. +- **Context Awareness**: Automatically share your current selection or tab with CoDev Code. +- **File Reference Shortcuts**: Use `Cmd+Option+K` (Mac) or `Alt+Ctrl+K` (Linux/Windows) to insert file references. For example, `@File#L37-42`. + +--- + +## Installation + +To install CoDev Code on VS Code and popular forks like Cursor, Windsurf, VSCodium: + +1. Open VS Code +2. Open the integrated terminal +3. Run `codev` - the extension installs automatically + +If on the other hand you want to use your own IDE when you run `/editor` or `/export` from the TUI, you'll need to set `export EDITOR="code --wait"`. [Learn more](/docs/tui/#editor-setup). + +--- + +### Manual Install + +The extension is not listed on the Extension Marketplace. Build the `.vsix` from a checkout and install it manually: + +```bash +cd sdks/vscode +bun install +bun run vsix +code --install-extension dist/codev-code-.vsix +``` + +--- + +### Troubleshooting + +If the extension fails to install automatically: + +- Ensure you’re running `codev` in the integrated terminal. +- Confirm the CLI for your IDE is installed: + - For VS Code: `code` command + - For Cursor: `cursor` command + - For Windsurf: `windsurf` command + - For VSCodium: `codium` command + - If not, run `Cmd+Shift+P` (Mac) or `Ctrl+Shift+P` (Windows/Linux) and search for "Shell Command: Install 'code' command in PATH" (or the equivalent for your IDE) +- Ensure VS Code has permission to install extensions diff --git a/packages/web/src/content/docs/index.mdx b/packages/web/src/content/docs/index.mdx new file mode 100644 index 0000000000..68f5952e4c --- /dev/null +++ b/packages/web/src/content/docs/index.mdx @@ -0,0 +1,302 @@ +--- +title: Intro +description: Get started with CoDev Code. +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components" +import config from "../../../config.mjs" +export const console = config.console + +[**CoDev Code**](/) is an open source AI coding agent. It's available as a terminal-based interface, desktop app, or IDE extension. + +![CoDev Code TUI with the opencode theme](../../assets/lander/screenshot.png) + +Let's get started. + +--- + +#### Prerequisites + +To use CoDev Code in your terminal, you'll need: + +1. A modern terminal emulator like: + - [WezTerm](https://wezterm.org), cross-platform + - [Alacritty](https://alacritty.org), cross-platform + - [Ghostty](https://ghostty.org), Linux and macOS + - [Kitty](https://sw.kovidgoyal.net/kitty/), Linux and macOS + +2. API keys for the LLM providers you want to use. + +--- + +## Install + +CoDev Code is distributed as the `codev-code` package on npm. Install it globally with your Node.js package manager to get the `codev` command. + + + + ```bash + npm install -g codev-code + ``` + + + ```bash + bun install -g codev-code + ``` + + + ```bash + pnpm install -g codev-code + ``` + + + ```bash + yarn global add codev-code + ``` + + + +#### Windows + +:::tip[Recommended: Use WSL] +For the best experience on Windows, we recommend using [Windows Subsystem for Linux (WSL)](/docs/windows-wsl). It provides better performance and full compatibility with CoDev Code's features. +::: + +On Windows, install the same way with npm (or another Node.js package manager): + +```bash +npm install -g codev-code +``` + +You can also grab the binary from the [Releases](https://github.com/quickbeard/codev-code/releases). + +--- + +## Configure + +With CoDev Code you can use any LLM provider by configuring their API keys. + +If you are new to using LLM providers, we recommend using [OpenCode Zen](/docs/zen). +It's a curated list of models that have been tested and verified by the OpenCode +team. + +1. Run the `/connect` command in the TUI, select opencode, and head to [opencode.ai/auth](https://opencode.ai/auth). + + ```txt + /connect + ``` + +2. Sign in, add your billing details, and copy your API key. + +3. Paste your API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +Alternatively, you can select one of the other providers. [Learn more](/docs/providers#directory). + +--- + +## Initialize + +Now that you've configured a provider, you can navigate to a project that +you want to work on. + +```bash +cd /path/to/project +``` + +And run CoDev Code. + +```bash +codev +``` + +Next, initialize CoDev Code for the project by running the following command. + +```bash frame="none" +/init +``` + +This will get CoDev Code to analyze your project and create an `AGENTS.md` file in +the project root. + +:::tip +You should commit your project's `AGENTS.md` file to Git. +::: + +This helps CoDev Code understand the project structure and the coding patterns +used. + +--- + +## Usage + +You are now ready to use CoDev Code to work on your project. Feel free to ask it +anything! + +If you are new to using an AI coding agent, here are some examples that might +help. + +--- + +### Ask questions + +You can ask CoDev Code to explain the codebase to you. + +:::tip +Use the `@` key to fuzzy search for files in the project. +::: + +```txt frame="none" "@packages/functions/src/api/index.ts" +How is authentication handled in @packages/functions/src/api/index.ts +``` + +This is helpful if there's a part of the codebase that you didn't work on. + +--- + +### Add features + +You can ask CoDev Code to add new features to your project. Though we first recommend asking it to create a plan. + +1. **Create a plan** + + CoDev Code has a _Plan mode_ that disables its ability to make changes and + instead suggest _how_ it'll implement the feature. + + Switch to it using the **Tab** key. You'll see an indicator for this in the lower right corner. + + ```bash frame="none" title="Switch to Plan mode" + + ``` + + Now let's describe what we want it to do. + + ```txt frame="none" + When a user deletes a note, we'd like to flag it as deleted in the database. + Then create a screen that shows all the recently deleted notes. + From this screen, the user can undelete a note or permanently delete it. + ``` + + You want to give CoDev Code enough details to understand what you want. It helps + to talk to it like you are talking to a junior developer on your team. + + :::tip + Give CoDev Code plenty of context and examples to help it understand what you + want. + ::: + +2. **Iterate on the plan** + + Once it gives you a plan, you can give it feedback or add more details. + + ```txt frame="none" + We'd like to design this new screen using a design I've used before. + [Image #1] Take a look at this image and use it as a reference. + ``` + + :::tip + Drag and drop images into the terminal to add them to the prompt. + ::: + + CoDev Code can scan any images you give it and add them to the prompt. You can + do this by dragging and dropping an image into the terminal. + +3. **Build the feature** + + Once you feel comfortable with the plan, switch back to _Build mode_ by + hitting the **Tab** key again. + + ```bash frame="none" + + ``` + + And asking it to make the changes. + + ```bash frame="none" + Sounds good! Go ahead and make the changes. + ``` + +--- + +### Make changes + +For more straightforward changes, you can ask CoDev Code to directly build it +without having to review the plan first. + +```txt frame="none" "@packages/functions/src/settings.ts" "@packages/functions/src/notes.ts" +We need to add authentication to the /settings route. Take a look at how this is +handled in the /notes route in @packages/functions/src/notes.ts and implement +the same logic in @packages/functions/src/settings.ts +``` + +You want to make sure you provide a good amount of detail so CoDev Code makes the right +changes. + +--- + +### Undo changes + +Let's say you ask CoDev Code to make some changes. + +```txt frame="none" "@packages/functions/src/api/index.ts" +Can you refactor the function in @packages/functions/src/api/index.ts? +``` + +But you realize that it is not what you wanted. You **can undo** the changes +using the `/undo` command. + +```bash frame="none" +/undo +``` + +CoDev Code will now revert the changes you made and show your original message +again. + +```txt frame="none" "@packages/functions/src/api/index.ts" +Can you refactor the function in @packages/functions/src/api/index.ts? +``` + +From here you can tweak the prompt and ask CoDev Code to try again. + +:::tip +You can run `/undo` multiple times to undo multiple changes. +::: + +Or you **can redo** the changes using the `/redo` command. + +```bash frame="none" +/redo +``` + +--- + +## Share + +The conversations that you have with CoDev Code can be [shared with your +team](/docs/share). + +```bash frame="none" +/share +``` + +This will create a link to the current conversation and copy it to your clipboard. + +:::note +Conversations are not shared by default. +::: + +Here's an [example conversation](https://opencode.ai/s/4XP1fce5) with CoDev Code. + +--- + +## Customize + +And that's it! You are now a pro at using CoDev Code. + +To make it your own, we recommend [picking a theme](/docs/themes), [customizing the keybinds](/docs/keybinds), [configuring code formatters](/docs/formatters), [creating custom commands](/docs/commands), or playing around with the [CoDev Code config](/docs/config). diff --git a/packages/web/src/content/docs/keybinds.mdx b/packages/web/src/content/docs/keybinds.mdx new file mode 100644 index 0000000000..38e48f6318 --- /dev/null +++ b/packages/web/src/content/docs/keybinds.mdx @@ -0,0 +1,301 @@ +--- +title: Keybinds +description: Customize your keybinds. +--- + +CoDev Code has a list of keybinds that you can customize through `tui.json`. + +```json title="tui.json" +{ + "$schema": "https://opencode.ai/tui.json", + "leader_timeout": 2000, + "keybinds": { + "leader": "ctrl+x", + "app_exit": "ctrl+d,q", + "app_exit_confirm": "ctrl+c", + "app_debug": "none", + "app_console": "none", + "app_heap_snapshot": "none", + "app_toggle_animations": "none", + "app_toggle_file_context": "none", + "app_toggle_diffwrap": "none", + "app_toggle_paste_summary": "none", + "app_toggle_session_directory_filter": "none", + "command_list": "ctrl+p", + "help_show": "none", + "docs_open": "none", + + "editor_open": "e", + "theme_list": "t", + "theme_switch_mode": "none", + "theme_mode_lock": "none", + "sidebar_toggle": "ctrl+b,b", + "scrollbar_toggle": "none", + "status_view": "s", + + "session_export": "x", + "session_copy": "none", + "session_move": "none", + "session_new": "n", + "session_list": "l", + "session_timeline": "g", + "session_fork": "none", + "session_rename": "ctrl+r", + "session_delete": "ctrl+d", + "session_share": "none", + "session_unshare": "none", + "session_interrupt": "escape", + "session_interrupt_now": "ctrl+c", + "session_compact": "c", + "session_toggle_timestamps": "none", + "session_toggle_generic_tool_output": "none", + "session_child_first": "down", + "session_child_cycle": "right", + "session_child_cycle_reverse": "left", + "session_parent": "up", + + "stash_delete": "ctrl+d", + "model_provider_list": "ctrl+a", + "model_favorite_toggle": "ctrl+f", + "model_list": "m", + "model_cycle_recent": "f2", + "model_cycle_recent_reverse": "shift+f2", + "model_cycle_favorite": "none", + "model_cycle_favorite_reverse": "none", + "mcp_list": "none", + "provider_connect": "none", + "console_org_switch": "none", + "agent_list": "a", + "agent_cycle": "tab", + "agent_cycle_reverse": "shift+tab", + "variant_cycle": "ctrl+t", + "variant_list": "none", + + "messages_page_up": "pageup,ctrl+alt+b", + "messages_page_down": "pagedown,ctrl+alt+f", + "messages_line_up": "ctrl+alt+y", + "messages_line_down": "ctrl+alt+e", + "messages_half_page_up": "ctrl+alt+u", + "messages_half_page_down": "ctrl+alt+d", + "messages_first": "ctrl+g,home", + "messages_last": "ctrl+alt+g,end", + "messages_next": "none", + "messages_previous": "none", + "messages_last_user": "none", + "messages_copy": "y", + "messages_undo": "u", + "messages_redo": "r", + "messages_toggle_conceal": "h", + "tool_details": "none", + "display_thinking": "none", + + "prompt_submit": "none", + "prompt_editor_context_clear": "none", + "prompt_skills": "none", + "prompt_stash": "none", + "prompt_stash_pop": "none", + "prompt_stash_list": "none", + "workspace_set": "none", + + "input_clear": "ctrl+c", + "input_paste": { + "key": "ctrl+v", + "preventDefault": false + }, + "input_submit": "return", + "input_newline": "shift+return,ctrl+return,alt+return,ctrl+j", + "input_move_left": "left,ctrl+o", + "input_move_right": "right,ctrl+f", + "input_move_up": "up", + "input_move_down": "down", + "input_select_left": "shift+left", + "input_select_right": "shift+right", + "input_select_up": "shift+up", + "input_select_down": "shift+down", + "input_line_home": "ctrl+a", + "input_line_end": "ctrl+e", + "input_select_line_home": "ctrl+shift+a", + "input_select_line_end": "ctrl+shift+e", + "input_visual_line_home": "alt+a", + "input_visual_line_end": "alt+e", + "input_select_visual_line_home": "alt+shift+a", + "input_select_visual_line_end": "alt+shift+e", + "input_buffer_home": "home", + "input_buffer_end": "end", + "input_select_buffer_home": "shift+home", + "input_select_buffer_end": "shift+end", + "input_delete_line": "ctrl+shift+d", + "input_delete_to_line_end": "ctrl+k", + "input_delete_to_line_start": "ctrl+u", + "input_backspace": "backspace,shift+backspace", + "input_delete": "ctrl+d,delete,shift+delete", + "input_undo": "ctrl+-,super+z", + "input_redo": "ctrl+.,super+shift+z", + "input_word_forward": "alt+f,alt+right,ctrl+right", + "input_word_backward": "alt+b,alt+left,ctrl+left", + "input_select_word_forward": "alt+shift+f,alt+shift+right", + "input_select_word_backward": "alt+shift+b,alt+shift+left", + "input_delete_word_forward": "alt+d,alt+delete,ctrl+delete", + "input_delete_word_backward": "ctrl+w,ctrl+backspace,alt+backspace", + "input_select_all": "super+a", + "history_previous": "up", + "history_next": "down", + + "dialog.select.prev": "up,ctrl+p", + "dialog.select.next": "down,ctrl+n", + "dialog.select.page_up": "pageup", + "dialog.select.page_down": "pagedown", + "dialog.select.home": "home", + "dialog.select.end": "end", + "dialog.select.submit": "return", + "dialog.prompt.submit": "return", + "dialog.mcp.toggle": "space", + "prompt.autocomplete.prev": "up,ctrl+p", + "prompt.autocomplete.next": "down,ctrl+n", + "prompt.autocomplete.hide": "escape", + "prompt.autocomplete.select": "return", + "prompt.autocomplete.complete": "tab", + "permission.prompt.fullscreen": "ctrl+f", + "plugins.toggle": "space", + "dialog.plugins.install": "shift+i", + + "terminal_suspend": "ctrl+z", + "terminal_title_toggle": "none", + "tips_toggle": "h", + "plugin_manager": "none", + "plugin_install": "none", + + "which_key_toggle": "ctrl+alt+k", + "which_key_layout_toggle": "ctrl+alt+shift+k", + "which_key_pending_toggle": "ctrl+alt+shift+p", + "which_key_group_previous": "ctrl+alt+left,ctrl+alt+[", + "which_key_group_next": "ctrl+alt+right,ctrl+alt+]", + "which_key_scroll_up": "ctrl+alt+up,ctrl+alt+p", + "which_key_scroll_down": "ctrl+alt+down,ctrl+alt+n", + "which_key_page_up": "ctrl+alt+pageup", + "which_key_page_down": "ctrl+alt+pagedown", + "which_key_home": "ctrl+alt+home", + "which_key_end": "ctrl+alt+end" + } +} +``` + +:::note +On Windows, the defaults for `input_undo` and `terminal_suspend` are different: + +- `input_undo` defaults to `ctrl+z,ctrl+-,super+z` when it is not explicitly configured. The `ctrl+z` binding is added because Windows terminals do not support POSIX suspend. +- `terminal_suspend` is forced to `none` because native Windows terminals do not support POSIX suspend. + ::: + +--- + +## Leader Key + +CoDev Code uses a `leader` key for many keybinds. This avoids conflicts in your terminal. + +By default, `ctrl+x` is the leader key and many actions require you to first press the leader key and then the shortcut. For example, to start a new session you first press `ctrl+x` and then press `n`. + +You don't need to use a leader key for your keybinds but we recommend doing so. + +Some navigation keybinds intentionally do not use the leader key by default. For subagent sessions, the defaults are `session_child_first` = `down`, `session_child_cycle` = `right`, `session_child_cycle_reverse` = `left`, and `session_parent` = `up`. + +`leader_timeout` controls how long CoDev Code waits for the next key after the leader key. It defaults to `2000` milliseconds. + +--- + +## Binding Values + +A string can contain one shortcut or multiple comma-separated shortcuts. You can also use an array for multiple shortcuts. + +For advanced cases, use an object with `key`, `event`, `preventDefault`, or `fallthrough`. + +```json title="tui.json" +{ + "$schema": "https://opencode.ai/tui.json", + "keybinds": { + "messages_copy": ["y", "ctrl+shift+c"], + "input_paste": { + "key": "ctrl+v", + "preventDefault": false + } + } +} +``` + +--- + +## Disable Keybind + +You can disable a keybind by adding the key to `tui.json` with a value of `"none"` or `false`. + +```json title="tui.json" +{ + "$schema": "https://opencode.ai/tui.json", + "keybinds": { + "session_compact": "none" + } +} +``` + +--- + +## Desktop Prompt Shortcuts + +The CoDev Code desktop app prompt input supports common Readline/Emacs-style shortcuts for editing text. These are built-in and currently not configurable via `codev.json`. + +| Shortcut | Action | +| -------- | ---------------------------------------- | +| `ctrl+a` | Move to start of current line | +| `ctrl+e` | Move to end of current line | +| `ctrl+b` | Move cursor back one character | +| `ctrl+f` | Move cursor forward one character | +| `alt+b` | Move cursor back one word | +| `alt+f` | Move cursor forward one word | +| `ctrl+d` | Delete character under cursor | +| `ctrl+k` | Kill to end of line | +| `ctrl+u` | Kill to start of line | +| `ctrl+w` | Kill previous word | +| `alt+d` | Kill next word | +| `ctrl+t` | Transpose characters | +| `ctrl+g` | Cancel popovers / abort running response | + +--- + +## Shift+Enter + +Some terminals don't send modifier keys with Enter by default. You may need to configure your terminal to send `Shift+Enter` as an escape sequence. + +### Windows Terminal + +Open your `settings.json` at: + +``` +%LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json +``` + +Add this to the root-level `actions` array: + +```json +"actions": [ + { + "command": { + "action": "sendInput", + "input": "\u001b[13;2u" + }, + "id": "User.sendInput.ShiftEnterCustom" + } +] +``` + +Add this to the root-level `keybindings` array: + +```json +"keybindings": [ + { + "keys": "shift+enter", + "id": "User.sendInput.ShiftEnterCustom" + } +] +``` + +Save the file and restart Windows Terminal or open a new tab. diff --git a/packages/web/src/content/docs/lsp.mdx b/packages/web/src/content/docs/lsp.mdx new file mode 100644 index 0000000000..e79190ee90 --- /dev/null +++ b/packages/web/src/content/docs/lsp.mdx @@ -0,0 +1,214 @@ +--- +title: LSP Servers +description: CoDev Code integrates with your LSP servers. +--- + +CoDev Code can integrate with Language Server Protocol (LSP) servers to use diagnostics as feedback for the agent. + +--- + +## Built-in + +CoDev Code comes with several built-in LSP servers for popular languages: + +| LSP Server | Extensions | Requirements | +| ------------------ | ------------------------------------------------------------------- | ------------------------------------------------------------ | +| astro | .astro | Auto-installs for Astro projects | +| bash | .sh, .bash, .zsh, .ksh | Auto-installs bash-language-server | +| clangd | .c, .cpp, .cc, .cxx, .c++, .h, .hpp, .hh, .hxx, .h++ | Auto-installs for C/C++ projects | +| csharp | .cs, .csx | `.NET SDK` installed | +| clojure-lsp | .clj, .cljs, .cljc, .edn | `clojure-lsp` command available | +| dart | .dart | `dart` command available | +| deno | .ts, .tsx, .js, .jsx, .mjs | `deno` command available (auto-detects deno.json/deno.jsonc) | +| elixir-ls | .ex, .exs | `elixir` command available | +| eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue | `eslint` dependency in project | +| fsharp | .fs, .fsi, .fsx, .fsscript | `.NET SDK` installed | +| gleam | .gleam | `gleam` command available | +| gopls | .go | `go` command available | +| hls | .hs, .lhs | `haskell-language-server-wrapper` command available | +| jdtls | .java | `Java SDK (version 21+)` installed | +| julials | .jl | `julia` and `LanguageServer.jl` installed | +| kotlin-ls | .kt, .kts | Auto-installs for Kotlin projects | +| lua-ls | .lua | Auto-installs for Lua projects | +| nixd | .nix | `nixd` command available | +| ocaml-lsp | .ml, .mli | `ocamllsp` command available | +| oxlint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue, .astro, .svelte | `oxlint` dependency in project | +| php intelephense | .php | Auto-installs for PHP projects | +| prisma | .prisma | `prisma` command available | +| pyright | .py, .pyi | `pyright` dependency installed | +| razor | .razor, .cshtml | `.NET SDK` and VS Code C# extension installed | +| ruby-lsp (rubocop) | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available | +| rust | .rs | `rust-analyzer` command available | +| sourcekit-lsp | .swift, .objc, .objcpp | `swift` installed (`xcode` on macOS) | +| svelte | .svelte | Auto-installs for Svelte projects | +| terraform | .tf, .tfvars | Auto-installs from GitHub releases | +| tinymist | .typ, .typc | Auto-installs from GitHub releases | +| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project | +| vue | .vue | Auto-installs for Vue projects | +| yaml-ls | .yaml, .yml | Auto-installs Red Hat yaml-language-server | +| zls | .zig, .zon | `zig` command available | + +LSP is disabled by default. When enabled, servers start when one of the above file extensions is detected and the requirements are met. + +:::note +You can disable automatic LSP server downloads by setting the `CODEV_DISABLE_LSP_DOWNLOAD` environment variable to `true`. +::: + +--- + +## How It Works + +When LSP is enabled and CoDev Code opens a file, it: + +1. Checks the file extension against all enabled LSP servers. +2. Starts the appropriate LSP server if not already running. + +--- + +## Best Practices + +LSP can help the agent find and fix issues by providing diagnostics from language servers. This is useful in some projects, but it is not always a net positive. + +Language servers can get out of sync, use significant memory, vary by version or project, and slow down agent workflows. In many projects it is better to have the agent run lint, typecheck, or other diagnostic CLI tools directly, so errors are fed back into the agent loop without those tradeoffs. Document those commands in instruction files such as `AGENTS.md` or skills so the agent knows what to run. Enable LSP when your project benefits from additional language-server feedback. + +--- + +## Configure + +You can enable and customize LSP servers through the `lsp` section in your CoDev Code config. + +To enable all built-in LSP servers, set `lsp` to `true`. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "lsp": true +} +``` + +Use an object to keep built-ins enabled while configuring overrides or custom servers. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "lsp": {} +} +``` + +Each configured LSP server entry supports the following: + +Server entries need `command` unless they only disable a server. + +| Property | Type | Description | +| ---------------- | -------- | ------------------------------------------------- | +| `disabled` | boolean | Set this to `true` to disable the LSP server | +| `command` | string[] | The command to start the LSP server | +| `extensions` | string[] | File extensions this LSP server should handle | +| `env` | object | Environment variables to set when starting server | +| `initialization` | object | Initialization options to send to the LSP server | + +Let's look at some examples. + +--- + +### Environment variables + +Use the `env` property to set environment variables when starting the LSP server: + +```json title="codev.json" {5-8} +{ + "$schema": "https://opencode.ai/config.json", + "lsp": { + "rust": { + "command": ["rust-analyzer"], + "env": { + "RUST_LOG": "debug" + } + } + } +} +``` + +--- + +### Initialization options + +Use the `initialization` property to pass initialization options to the LSP server. These are server-specific settings sent during the LSP `initialize` request: + +```json title="codev.json" {5-13} +{ + "$schema": "https://opencode.ai/config.json", + "lsp": { + "custom-lsp": { + "command": ["custom-lsp-server", "--stdio"], + "extensions": [".custom"], + "initialization": { + "preferences": { + "importModuleSpecifierPreference": "relative" + } + } + } + } +} +``` + +:::note +Initialization options vary by LSP server. Check your LSP server's documentation for available options. +::: + +--- + +### Disabling LSP servers + +If `lsp` is omitted, all LSP servers are disabled. To disable all LSP servers after another config enabled them, set `lsp` to `false`: + +```json title="codev.json" {3} +{ + "$schema": "https://opencode.ai/config.json", + "lsp": false +} +``` + +To disable a **specific** LSP server, set `disabled` to `true`: + +```json title="codev.json" {5} +{ + "$schema": "https://opencode.ai/config.json", + "lsp": { + "typescript": { + "disabled": true + } + } +} +``` + +--- + +### Custom LSP servers + +You can add custom LSP servers by specifying the command and file extensions: + +```json title="codev.json" {4-7} +{ + "$schema": "https://opencode.ai/config.json", + "lsp": { + "custom-lsp": { + "command": ["custom-lsp-server", "--stdio"], + "extensions": [".custom"] + } + } +} +``` + +--- + +## Additional Information + +### PHP Intelephense + +PHP Intelephense offers premium features through a license key. You can provide a license key by placing (only) the key in a text file at: + +- On macOS/Linux: `$HOME/intelephense/license.txt` +- On Windows: `%USERPROFILE%/intelephense/license.txt` + +The file should contain only the license key with no additional content. diff --git a/packages/web/src/content/docs/mcp-servers.mdx b/packages/web/src/content/docs/mcp-servers.mdx new file mode 100644 index 0000000000..ac6c059152 --- /dev/null +++ b/packages/web/src/content/docs/mcp-servers.mdx @@ -0,0 +1,512 @@ +--- +title: MCP servers +description: Add local and remote MCP tools. +--- + +You can add external tools to CoDev Code using the _Model Context Protocol_, or MCP. CoDev Code supports both local and remote servers. + +Once added, MCP tools are automatically available to the LLM alongside built-in tools. + +--- + +#### Caveats + +When you use an MCP server, it adds to the context. This can quickly add up if you have a lot of tools. So we recommend being careful with which MCP servers you use. + +:::tip +MCP servers add to your context, so you want to be careful with which ones you enable. +::: + +Certain MCP servers, like the GitHub MCP server, tend to add a lot of tokens and can easily exceed the context limit. + +--- + +## Enable + +You can define MCP servers in your [CoDev Code Config](https://opencode.ai/docs/config/) under `mcp`. Add each MCP with a unique name. You can refer to that MCP by name when prompting the LLM. + +```jsonc title="codev.jsonc" {6} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "name-of-mcp-server": { + // ... + "enabled": true, + }, + "name-of-other-mcp-server": { + // ... + }, + }, +} +``` + +You can also disable a server by setting `enabled` to `false`. This is useful if you want to temporarily disable a server without removing it from your config. + +--- + +### Overriding remote defaults + +Organizations can provide default MCP servers via their `.well-known/opencode` endpoint. These servers may be disabled by default, allowing users to opt-in to the ones they need. + +To enable a specific server from your organization's remote config, add it to your local config with `enabled: true`: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "jira": { + "type": "remote", + "url": "https://jira.example.com/mcp", + "enabled": true + } + } +} +``` + +Your local config values override the remote defaults. See [config precedence](/docs/config#precedence-order) for more details. + +--- + +## Local + +Add local MCP servers using `type` to `"local"` within the MCP object. + +```jsonc title="codev.jsonc" {15} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "my-local-mcp-server": { + "type": "local", + // Or ["bun", "x", "my-mcp-command"] + "command": ["npx", "-y", "my-mcp-command"], + "enabled": true, + "environment": { + "MY_ENV_VAR": "my_env_var_value", + }, + }, + }, +} +``` + +The command is how the local MCP server is started. You can also pass in a list of environment variables as well. + +For example, here's how you can add the test [`@modelcontextprotocol/server-everything`](https://www.npmjs.com/package/@modelcontextprotocol/server-everything) MCP server. + +```jsonc title="codev.jsonc" +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "mcp_everything": { + "type": "local", + "command": ["npx", "-y", "@modelcontextprotocol/server-everything"], + }, + }, +} +``` + +And to use it I can add `use the mcp_everything tool` to my prompts. + +```txt "mcp_everything" +use the mcp_everything tool to add the number 3 and 4 +``` + +--- + +#### Options + +Here are all the options for configuring a local MCP server. + +| Option | Type | Required | Description | +| ------------- | ------- | -------- | ---------------------------------------------------------------------------------------- | +| `type` | String | Y | Type of MCP server connection, must be `"local"`. | +| `command` | Array | Y | Command and arguments to run the MCP server. | +| `cwd` | String | | Working directory for the MCP server process. Relative paths resolve from the workspace. | +| `environment` | Object | | Environment variables to set when running the server. | +| `enabled` | Boolean | | Enable or disable the MCP server on startup. | +| `timeout` | Number | | Timeout in ms for fetching tools from the MCP server. Defaults to 5000 (5 seconds). | + +--- + +## Remote + +Add remote MCP servers by setting `type` to `"remote"`. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "my-remote-mcp": { + "type": "remote", + "url": "https://my-mcp-server.com", + "enabled": true, + "headers": { + "Authorization": "Bearer MY_API_KEY" + } + } + } +} +``` + +The `url` is the URL of the remote MCP server and with the `headers` option you can pass in a list of headers. + +--- + +#### Options + +| Option | Type | Required | Description | +| --------- | ------- | -------- | ----------------------------------------------------------------------------------- | +| `type` | String | Y | Type of MCP server connection, must be `"remote"`. | +| `url` | String | Y | URL of the remote MCP server. | +| `enabled` | Boolean | | Enable or disable the MCP server on startup. | +| `headers` | Object | | Headers to send with the request. | +| `oauth` | Object | | OAuth authentication configuration. See [OAuth](#oauth) section below. | +| `timeout` | Number | | Timeout in ms for fetching tools from the MCP server. Defaults to 5000 (5 seconds). | + +--- + +## OAuth + +CoDev Code automatically handles OAuth authentication for remote MCP servers. When a server requires authentication, CoDev Code will: + +1. Detect the 401 response and initiate the OAuth flow +2. Use **Dynamic Client Registration (RFC 7591)** if supported by the server +3. Store tokens securely for future requests + +--- + +### Automatic + +For most OAuth-enabled MCP servers, no special configuration is needed. Just configure the remote server: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "my-oauth-server": { + "type": "remote", + "url": "https://mcp.example.com/mcp" + } + } +} +``` + +If the server requires authentication, CoDev Code will prompt you to authenticate when you first try to use it. If not, you can [manually trigger the flow](#authenticating) with `codev mcp auth `. + +--- + +### Pre-registered + +If you have client credentials from the MCP server provider, you can configure them: + +```json title="codev.json" {7-11} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "my-oauth-server": { + "type": "remote", + "url": "https://mcp.example.com/mcp", + "oauth": { + "clientId": "{env:MY_MCP_CLIENT_ID}", + "clientSecret": "{env:MY_MCP_CLIENT_SECRET}", + "scope": "tools:read tools:execute" + } + } + } +} +``` + +--- + +### Authenticating + +You can manually trigger authentication or manage credentials. + +Authenticate with a specific MCP server: + +```bash +codev mcp auth my-oauth-server +``` + +List all MCP servers and their auth status: + +```bash +codev mcp list +``` + +Remove stored credentials: + +```bash +codev mcp logout my-oauth-server +``` + +The `mcp auth` command will open your browser for authorization. After you authorize, CoDev Code will store the tokens securely in `~/.local/share/codev/mcp-auth.json`. + +--- + +#### Disabling OAuth + +If you want to disable automatic OAuth for a server (e.g., for servers that use API keys instead), set `oauth` to `false`: + +```json title="codev.json" {7} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "my-api-key-server": { + "type": "remote", + "url": "https://mcp.example.com/mcp", + "oauth": false, + "headers": { + "Authorization": "Bearer {env:MY_API_KEY}" + } + } + } +} +``` + +--- + +#### OAuth Options + +| Option | Type | Description | +| -------------- | --------------- | -------------------------------------------------------------------------------- | +| `oauth` | Object \| false | OAuth config object, or `false` to disable OAuth auto-detection. | +| `clientId` | String | OAuth client ID. If not provided, dynamic client registration will be attempted. | +| `clientSecret` | String | OAuth client secret, if required by the authorization server. | +| `scope` | String | OAuth scopes to request during authorization. | + +#### Debugging + +If a remote MCP server is failing to authenticate, you can diagnose issues with: + +```bash +# View auth status for all OAuth-capable servers +codev mcp auth list + +# Debug connection and OAuth flow for a specific server +codev mcp debug my-oauth-server +``` + +The `mcp debug` command shows the current auth status, tests HTTP connectivity, and attempts the OAuth discovery flow. + +--- + +## Manage + +Your MCPs are available as tools in CoDev Code, alongside built-in tools. So you can manage them through the CoDev Code config like any other tool. + +--- + +### Global + +This means that you can enable or disable them globally. + +```json title="codev.json" {14} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "my-mcp-foo": { + "type": "local", + "command": ["bun", "x", "my-mcp-command-foo"] + }, + "my-mcp-bar": { + "type": "local", + "command": ["bun", "x", "my-mcp-command-bar"] + } + }, + "tools": { + "my-mcp-foo": false + } +} +``` + +We can also use a glob pattern to disable all matching MCPs. + +```json title="codev.json" {14} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "my-mcp-foo": { + "type": "local", + "command": ["bun", "x", "my-mcp-command-foo"] + }, + "my-mcp-bar": { + "type": "local", + "command": ["bun", "x", "my-mcp-command-bar"] + } + }, + "tools": { + "my-mcp*": false + } +} +``` + +Here we are using the glob pattern `my-mcp*` to disable all MCPs. + +--- + +### Per agent + +If you have a large number of MCP servers you may want to only enable them per agent and disable them globally. To do this: + +1. Disable it as a tool globally. +2. In your [agent config](/docs/agents#tools), enable the MCP server as a tool. + +```json title="codev.json" {11, 14-18} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "my-mcp": { + "type": "local", + "command": ["bun", "x", "my-mcp-command"], + "enabled": true + } + }, + "tools": { + "my-mcp*": false + }, + "agent": { + "my-agent": { + "tools": { + "my-mcp*": true + } + } + } +} +``` + +--- + +#### Glob patterns + +The glob pattern uses simple regex globbing patterns: + +- `*` matches zero or more of any character (e.g., `"my-mcp*"` matches `my-mcp_search`, `my-mcp_list`, etc.) +- `?` matches exactly one character +- All other characters match literally + +:::note +MCP server tools are registered with server name as prefix, so to disable all tools for a server simply use: + +``` +"mymcpservername_*": false +``` + +::: + +--- + +## Examples + +Below are examples of some common MCP servers. You can submit a PR if you want to document other servers. + +--- + +### Sentry + +Add the [Sentry MCP server](https://mcp.sentry.dev) to interact with your Sentry projects and issues. + +```json title="codev.json" {4-8} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "sentry": { + "type": "remote", + "url": "https://mcp.sentry.dev/mcp", + "oauth": {} + } + } +} +``` + +After adding the configuration, authenticate with Sentry: + +```bash +codev mcp auth sentry +``` + +This will open a browser window to complete the OAuth flow and connect CoDev Code to your Sentry account. + +Once authenticated, you can use Sentry tools in your prompts to query issues, projects, and error data. + +```txt "use sentry" +Show me the latest unresolved issues in my project. use sentry +``` + +--- + +### Context7 + +Add the [Context7 MCP server](https://github.com/upstash/context7) to search through docs. + +```json title="codev.json" {4-7} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "context7": { + "type": "remote", + "url": "https://mcp.context7.com/mcp" + } + } +} +``` + +If you have signed up for a free account, you can use your API key and get higher rate-limits. + +```json title="codev.json" {7-9} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "context7": { + "type": "remote", + "url": "https://mcp.context7.com/mcp", + "headers": { + "CONTEXT7_API_KEY": "{env:CONTEXT7_API_KEY}" + } + } + } +} +``` + +Here we are assuming that you have the `CONTEXT7_API_KEY` environment variable set. + +Add `use context7` to your prompts to use Context7 MCP server. + +```txt "use context7" +Configure a Cloudflare Worker script to cache JSON API responses for five minutes. use context7 +``` + +Alternatively, you can add something like this to your [AGENTS.md](/docs/rules/). + +```md title="AGENTS.md" +When you need to search docs, use `context7` tools. +``` + +--- + +### Grep by Vercel + +Add the [Grep by Vercel](https://grep.app) MCP server to search through code snippets on GitHub. + +```json title="codev.json" {4-7} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "gh_grep": { + "type": "remote", + "url": "https://mcp.grep.app" + } + } +} +``` + +Since we named our MCP server `gh_grep`, you can add `use the gh_grep tool` to your prompts to get the agent to use it. + +```txt "use the gh_grep tool" +What's the right way to set a custom domain in an SST Astro component? use the gh_grep tool +``` + +Alternatively, you can add something like this to your [AGENTS.md](/docs/rules/). + +```md title="AGENTS.md" +If you are unsure how to do something, use `gh_grep` to search code examples from GitHub. +``` diff --git a/packages/web/src/content/docs/models.mdx b/packages/web/src/content/docs/models.mdx new file mode 100644 index 0000000000..38c5c696df --- /dev/null +++ b/packages/web/src/content/docs/models.mdx @@ -0,0 +1,223 @@ +--- +title: Models +description: Configuring an LLM provider and model. +--- + +CoDev Code uses the [AI SDK](https://ai-sdk.dev/) and [Models.dev](https://models.dev) to support **75+ LLM providers** and it supports running local models. + +--- + +## Providers + +Most popular providers are preloaded by default. If you've added the credentials for a provider through the `/connect` command, they'll be available when you start CoDev Code. + +Learn more about [providers](/docs/providers). + +--- + +## Select a model + +Once you've configured your provider you can select the model you want by typing in: + +```bash frame="none" +/models +``` + +--- + +## Recommended models + +There are a lot of models out there, with new models coming out every week. + +:::tip +Consider using one of the models we recommend. +::: + +However, there are only a few of them that are good at both generating code and tool calling. + +Here are several models that work well with CoDev Code, in no particular order. (This is not an exhaustive list nor is it necessarily up to date): + +- GPT 5.2 +- GPT 5.1 Codex +- Claude Opus 4.5 +- Claude Sonnet 4.5 +- Minimax M2.1 +- Gemini 3 Pro + +--- + +## Set a default + +To set one of these as the default model, you can set the `model` key in your +CoDev Code config. + +```json title="codev.json" {3} +{ + "$schema": "https://opencode.ai/config.json", + "model": "lmstudio/google/gemma-3n-e4b" +} +``` + +Here the full ID is `provider_id/model_id`. For example, if you're using [OpenCode Zen](/docs/zen), you would use `opencode/gpt-5.1-codex` for GPT 5.1 Codex. + +If you've configured a [custom provider](/docs/providers#custom), the `provider_id` is key from the `provider` part of your config, and the `model_id` is the key from `provider.models`. + +--- + +## Configure models + +You can globally configure a model's options through the config. + +```jsonc title="codev.jsonc" {7-12,19-24} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "openai": { + "models": { + "gpt-5": { + "options": { + "reasoningEffort": "high", + "textVerbosity": "low", + "reasoningSummary": "auto", + "include": ["reasoning.encrypted_content"], + }, + }, + }, + }, + "anthropic": { + "models": { + "claude-sonnet-4-5-20250929": { + "options": { + "thinking": { + "type": "enabled", + "budgetTokens": 16000, + }, + }, + }, + }, + }, + }, +} +``` + +Here we're configuring global settings for two built-in models: `gpt-5` when accessed via the `openai` provider, and `claude-sonnet-4-20250514` when accessed via the `anthropic` provider. +The built-in provider and model names can be found on [Models.dev](https://models.dev). + +You can also configure these options for any agents that you are using. The agent config overrides any global options here. [Learn more](/docs/agents/#additional). + +You can also define custom variants that extend built-in ones. Variants let you configure different settings for the same model without creating duplicate entries: + +```jsonc title="codev.jsonc" {6-21} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "opencode": { + "models": { + "gpt-5": { + "variants": { + "high": { + "reasoningEffort": "high", + "textVerbosity": "low", + "reasoningSummary": "auto", + }, + "low": { + "reasoningEffort": "low", + "textVerbosity": "low", + "reasoningSummary": "auto", + }, + }, + }, + }, + }, + }, +} +``` + +--- + +## Variants + +Many models support multiple variants with different configurations. CoDev Code ships with built-in default variants for popular providers. + +### Built-in variants + +CoDev Code ships with default variants for many providers: + +**Anthropic**: + +- `high` - High thinking budget (default) +- `max` - Maximum thinking budget + +**OpenAI**: + +Varies by model but roughly: + +- `none` - No reasoning +- `minimal` - Minimal reasoning effort +- `low` - Low reasoning effort +- `medium` - Medium reasoning effort +- `high` - High reasoning effort +- `xhigh` - Extra high reasoning effort + +**Google**: + +- `low` - Lower effort/token budget +- `high` - Higher effort/token budget + +:::tip +This list is not comprehensive. Many other providers have built-in defaults too. +::: + +### Custom variants + +You can override existing variants or add your own: + +```jsonc title="codev.jsonc" {7-18} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "openai": { + "models": { + "gpt-5": { + "variants": { + "thinking": { + "reasoningEffort": "high", + "textVerbosity": "low", + }, + "fast": { + "disabled": true, + }, + }, + }, + }, + }, + }, +} +``` + +### Cycle variants + +Use the keybind `variant_cycle` to quickly switch between variants. [Learn more](/docs/keybinds). + +--- + +## Loading models + +When CoDev Code starts up, it checks for models in the following priority order: + +1. The `--model` or `-m` command line flag. The format is the same as in the config file: `provider_id/model_id`. + +2. The model list in the CoDev Code config. + + ```json title="codev.json" + { + "$schema": "https://opencode.ai/config.json", + "model": "anthropic/claude-sonnet-4-20250514" + } + ``` + + The format here is `provider/model`. + +3. The last used model. + +4. The first model using an internal priority. diff --git a/packages/web/src/content/docs/network.mdx b/packages/web/src/content/docs/network.mdx new file mode 100644 index 0000000000..f39fed3e07 --- /dev/null +++ b/packages/web/src/content/docs/network.mdx @@ -0,0 +1,57 @@ +--- +title: Network +description: Configure proxies and custom certificates. +--- + +CoDev Code supports standard proxy environment variables and custom certificates for enterprise network environments. + +--- + +## Proxy + +CoDev Code respects standard proxy environment variables. + +```bash +# HTTPS proxy (recommended) +export HTTPS_PROXY=https://proxy.example.com:8080 + +# HTTP proxy (if HTTPS not available) +export HTTP_PROXY=http://proxy.example.com:8080 + +# Bypass proxy for local server (required) +export NO_PROXY=localhost,127.0.0.1 +``` + +:::caution +The TUI communicates with a local HTTP server. You must bypass the proxy for this connection to prevent routing loops. +::: + +You can configure the server's port and hostname using [CLI flags](/docs/cli#run). + +--- + +### Authenticate + +If your proxy requires basic authentication, include credentials in the URL. + +```bash +export HTTPS_PROXY=http://username:password@proxy.example.com:8080 +``` + +:::caution +Avoid hardcoding passwords. Use environment variables or secure credential storage. +::: + +For proxies requiring advanced authentication like NTLM or Kerberos, consider using an LLM Gateway that supports your authentication method. + +--- + +## Custom certificates + +If your enterprise uses custom CAs for HTTPS connections, configure CoDev Code to trust them. + +```bash +export NODE_EXTRA_CA_CERTS=/path/to/ca-cert.pem +``` + +This works for both proxy connections and direct API access. diff --git a/packages/web/src/content/docs/permissions.mdx b/packages/web/src/content/docs/permissions.mdx new file mode 100644 index 0000000000..e00acce27e --- /dev/null +++ b/packages/web/src/content/docs/permissions.mdx @@ -0,0 +1,256 @@ +--- +title: Permissions +description: Control which actions require approval to run. +--- + +CoDev Code uses the `permission` config to decide whether a given action should run automatically, prompt you, or be blocked. + +As of `v1.1.1`, the legacy `tools` boolean config is deprecated and has been merged into `permission`. The old `tools` config is still supported for backwards compatibility. + +--- + +## Actions + +Each permission rule resolves to one of: + +- `"allow"` — run without approval +- `"ask"` — prompt for approval +- `"deny"` — block the action + +--- + +## Auto mode + +Start CoDev Code with `--auto` to automatically approve permission requests that are not explicitly denied. + +```bash +codev --auto +``` + +You can also use auto mode with [`codev run`](/docs/cli#run). + +```bash +codev run --auto "Refactor this module" +``` + +Explicit `"deny"` rules are still enforced. Auto mode only changes requests that would otherwise ask for approval. + +In the TUI, open the command palette and select **Enable auto-approve permissions** or **Disable auto-approve permissions** to change modes. When auto mode is active, the prompt displays a muted `auto` indicator next to the current agent. + +--- + +## Configuration + +You can set permissions globally (with `*`), and override specific tools. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "*": "ask", + "bash": "allow", + "edit": "deny" + } +} +``` + +You can also set all permissions at once: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "permission": "allow" +} +``` + +--- + +## Granular Rules (Object Syntax) + +For most permissions, you can use an object to apply different actions based on the tool input. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "bash": { + "*": "ask", + "git *": "allow", + "npm *": "allow", + "rm *": "deny", + "grep *": "allow" + }, + "edit": { + "*": "deny", + "packages/web/src/content/docs/*.mdx": "allow" + } + } +} +``` + +Rules are evaluated by pattern match, with the **last matching rule winning**. A common pattern is to put the catch-all `"*"` rule first, and more specific rules after it. + +### Wildcards + +Permission patterns use simple wildcard matching: + +- `*` matches zero or more of any character +- `?` matches exactly one character +- All other characters match literally + +### Home Directory Expansion + +You can use `~` or `$HOME` at the start of a pattern to reference your home directory. This is particularly useful for [`external_directory`](#external-directories) rules. + +- `~/projects/*` -> `/Users/username/projects/*` +- `$HOME/projects/*` -> `/Users/username/projects/*` +- `~` -> `/Users/username` + +### External Directories + +Use `external_directory` to allow tool calls that touch paths outside the working directory where CoDev Code was started. This applies to any tool that takes a path as input (for example `read`, `edit`, `glob`, `grep`, and many `bash` commands). + +Home expansion (like `~/...`) only affects how a pattern is written. It does not make an external path part of the current workspace, so paths outside the working directory must still be allowed via `external_directory`. + +For example, this allows access to everything under `~/projects/personal/`: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "external_directory": { + "~/projects/personal/**": "allow" + } + } +} +``` + +Any directory allowed here inherits the same defaults as the current workspace. Since [`read` defaults to `allow`](#defaults), reads are also allowed for entries under `external_directory` unless overridden. Add explicit rules when a tool should be restricted in these paths, such as blocking edits while keeping reads: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "external_directory": { + "~/projects/personal/**": "allow" + }, + "edit": { + "~/projects/personal/**": "deny" + } + } +} +``` + +Keep the list focused on trusted paths, and layer extra allow or deny rules as needed for other tools (for example `bash`). + +--- + +## Available Permissions + +CoDev Code permissions are keyed by tool name, plus a couple of safety guards: + +- `read` — reading a file (matches the file path) +- `edit` — all file modifications (covers `edit`, `write`, `patch`) +- `glob` — file globbing (matches the glob pattern) +- `grep` — content search (matches the regex pattern) +- `bash` — running shell commands (matches parsed commands like `git status --porcelain`) +- `task` — launching subagents (matches the subagent type) +- `skill` — loading a skill (matches the skill name) +- `lsp` — running LSP queries (currently non-granular) +- `question` — asking the user questions during execution +- `webfetch` — fetching a URL (matches the URL) +- `websearch` — web search (matches the query) +- `external_directory` — triggered when a tool touches paths outside the project working directory +- `doom_loop` — triggered when the same tool call repeats 3 times with identical input + +--- + +## Defaults + +If you don’t specify anything, CoDev Code starts from permissive defaults: + +- Most permissions default to `"allow"`. +- `doom_loop` and `external_directory` default to `"ask"`. +- `read` is `"allow"`, but `.env` files are denied by default: + +```json title="codev.json" +{ + "permission": { + "read": { + "*": "allow", + "*.env": "deny", + "*.env.*": "deny", + "*.env.example": "allow" + } + } +} +``` + +--- + +## What “Ask” Does + +When CoDev Code prompts for approval, the UI offers three outcomes: + +- `once` — approve just this request +- `always` — approve future requests matching the suggested patterns (for the rest of the current CoDev Code session) +- `reject` — deny the request + +The set of patterns that `always` would approve is provided by the tool (for example, bash approvals typically whitelist a safe command prefix like `git status*`). + +--- + +## Agents + +You can override permissions per agent. Agent permissions are merged with the global config, and agent rules take precedence. [Learn more](/docs/agents#permissions) about agent permissions. + +:::note +Refer to the [Granular Rules (Object Syntax)](#granular-rules-object-syntax) section above for more detailed pattern matching examples. +::: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "bash": { + "*": "ask", + "git *": "allow", + "git commit *": "deny", + "git push *": "deny", + "grep *": "allow" + } + }, + "agent": { + "build": { + "permission": { + "bash": { + "*": "ask", + "git *": "allow", + "git commit *": "ask", + "git push *": "deny", + "grep *": "allow" + } + } + } + } +} +``` + +You can also configure agent permissions in Markdown: + +```markdown title="~/.config/codev/agents/review.md" +--- +description: Code review without edits +mode: subagent +permission: + edit: deny + bash: ask + webfetch: deny +--- + +Only analyze code and suggest changes. +``` + +:::tip +Use pattern matching for commands with arguments. `"grep *"` allows `grep pattern file.txt`, while `"grep"` alone would block it. Commands like `git status` work for default behavior but require explicit permission (like `"git status *"`) when arguments are passed. +::: diff --git a/packages/web/src/content/docs/plugins.mdx b/packages/web/src/content/docs/plugins.mdx new file mode 100644 index 0000000000..a8ee68939d --- /dev/null +++ b/packages/web/src/content/docs/plugins.mdx @@ -0,0 +1,389 @@ +--- +title: Plugins +description: Write your own plugins to extend CoDev Code. +--- + +Plugins allow you to extend CoDev Code by hooking into various events and customizing behavior. You can create plugins to add new features, integrate with external services, or modify CoDev Code's default behavior. + +For examples, check out the [plugins](/docs/ecosystem#plugins) created by the community. + +--- + +## Use a plugin + +There are two ways to load plugins. + +--- + +### From local files + +Place JavaScript or TypeScript files in the plugin directory. + +- `.codev/plugins/` - Project-level plugins +- `~/.config/codev/plugins/` - Global plugins + +Files in these directories are automatically loaded at startup. + +--- + +### From npm + +Specify npm packages in your config file. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"] +} +``` + +Both regular and scoped npm packages are supported. + +Browse available plugins in the [ecosystem](/docs/ecosystem#plugins). + +--- + +### How plugins are installed + +**npm plugins** are installed automatically using Bun at startup. Packages and their dependencies are cached in `~/.cache/codev/node_modules/`. + +**Local plugins** are loaded directly from the plugin directory. To use external packages, you must create a `package.json` within your config directory (see [Dependencies](#dependencies)), or publish the plugin to npm and [add it to your config](/docs/config#plugins). + +--- + +### Load order + +Plugins are loaded from all sources and all hooks run in sequence. The load order is: + +1. Global config (`~/.config/codev/codev.json`) +2. Project config (`codev.json`) +3. Global plugin directory (`~/.config/codev/plugins/`) +4. Project plugin directory (`.codev/plugins/`) + +Duplicate npm packages with the same name and version are loaded once. However, a local plugin and an npm plugin with similar names are both loaded separately. + +--- + +## Create a plugin + +A plugin is a **JavaScript/TypeScript module** that exports one or more plugin +functions. Each function receives a context object and returns a hooks object. + +--- + +### Dependencies + +Local plugins and custom tools can use external npm packages. Add a `package.json` to your config directory with the dependencies you need. + +```json title=".codev/package.json" +{ + "dependencies": { + "shescape": "^2.1.0" + } +} +``` + +CoDev Code runs `bun install` at startup to install these. Your plugins and tools can then import them. + +```ts title=".codev/plugins/my-plugin.ts" +import { escape } from "shescape" + +export const MyPlugin = async (ctx) => { + return { + "tool.execute.before": async (input, output) => { + if (input.tool === "bash") { + output.args.command = escape(output.args.command) + } + }, + } +} +``` + +--- + +### Basic structure + +```js title=".codev/plugins/example.js" +export const MyPlugin = async ({ project, client, $, directory, worktree }) => { + console.log("Plugin initialized!") + + return { + // Hook implementations go here + } +} +``` + +The plugin function receives: + +- `project`: The current project information. +- `directory`: The current working directory. +- `worktree`: The git worktree path. +- `client`: A CoDev Code SDK client for interacting with the AI. +- `$`: Bun's [shell API](https://bun.com/docs/runtime/shell) for executing commands. + +--- + +### TypeScript support + +For TypeScript plugins, you can import types from the plugin package: + +```ts title="my-plugin.ts" {1} +import type { Plugin } from "@opencode-ai/plugin" + +export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => { + return { + // Type-safe hook implementations + } +} +``` + +--- + +### Events + +Plugins can subscribe to events as seen below in the Examples section. Here is a list of the different events available. + +#### Command Events + +- `command.executed` + +#### File Events + +- `file.edited` +- `file.watcher.updated` + +#### Installation Events + +- `installation.updated` + +#### LSP Events + +- `lsp.client.diagnostics` +- `lsp.updated` + +#### Message Events + +- `message.part.removed` +- `message.part.updated` +- `message.removed` +- `message.updated` + +#### Permission Events + +- `permission.asked` +- `permission.replied` + +#### Server Events + +- `server.connected` + +#### Session Events + +- `session.created` +- `session.compacted` +- `session.deleted` +- `session.diff` +- `session.error` +- `session.idle` +- `session.status` +- `session.updated` + +#### Todo Events + +- `todo.updated` + +#### Shell Events + +- `shell.env` + +#### Tool Events + +- `tool.execute.after` +- `tool.execute.before` + +#### TUI Events + +- `tui.prompt.append` +- `tui.command.execute` +- `tui.toast.show` + +--- + +## Examples + +Here are some examples of plugins you can use to extend CoDev Code. + +--- + +### Send notifications + +Send notifications when certain events occur: + +```js title=".codev/plugins/notification.js" +export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => { + return { + event: async ({ event }) => { + // Send notification on session completion + if (event.type === "session.idle") { + await $`osascript -e 'display notification "Session completed!" with title "opencode"'` + } + }, + } +} +``` + +We are using `osascript` to run AppleScript on macOS. Here we are using it to send notifications. + +:::note +If you’re using the CoDev Code desktop app, it can send system notifications automatically when a response is ready or when a session errors. +::: + +--- + +### .env protection + +Prevent CoDev Code from reading `.env` files: + +```javascript title=".codev/plugins/env-protection.js" +export const EnvProtection = async ({ project, client, $, directory, worktree }) => { + return { + "tool.execute.before": async (input, output) => { + if (input.tool === "read" && output.args.filePath.includes(".env")) { + throw new Error("Do not read .env files") + } + }, + } +} +``` + +--- + +### Inject environment variables + +Inject environment variables into all shell execution (AI tools and user terminals): + +```javascript title=".codev/plugins/inject-env.js" +export const InjectEnvPlugin = async () => { + return { + "shell.env": async (input, output) => { + output.env.MY_API_KEY = "secret" + output.env.PROJECT_ROOT = input.cwd + }, + } +} +``` + +--- + +### Custom tools + +Plugins can also add custom tools to CoDev Code: + +```ts title=".codev/plugins/custom-tools.ts" +import { type Plugin, tool } from "@opencode-ai/plugin" + +export const CustomToolsPlugin: Plugin = async (ctx) => { + return { + tool: { + mytool: tool({ + description: "This is a custom tool", + args: { + foo: tool.schema.string(), + }, + async execute(args, context) { + const { directory, worktree } = context + return `Hello ${args.foo} from ${directory} (worktree: ${worktree})` + }, + }), + }, + } +} +``` + +The `tool` helper creates a custom tool that CoDev Code can call. It takes a Zod schema function and returns a tool definition with: + +- `description`: What the tool does +- `args`: Zod schema for the tool's arguments +- `execute`: Function that runs when the tool is called + +Your custom tools will be available to CoDev Code alongside built-in tools. + +:::note +If a plugin tool uses the same name as a built-in tool, the plugin tool takes precedence. +::: + +--- + +### Logging + +Use `client.app.log()` instead of `console.log` for structured logging: + +```ts title=".codev/plugins/my-plugin.ts" +export const MyPlugin = async ({ client }) => { + await client.app.log({ + body: { + service: "my-plugin", + level: "info", + message: "Plugin initialized", + extra: { foo: "bar" }, + }, + }) +} +``` + +Levels: `debug`, `info`, `warn`, `error`. See [SDK documentation](https://opencode.ai/docs/sdk) for details. + +--- + +### Compaction hooks + +Customize the context included when a session is compacted: + +```ts title=".codev/plugins/compaction.ts" +import type { Plugin } from "@opencode-ai/plugin" + +export const CompactionPlugin: Plugin = async (ctx) => { + return { + "experimental.session.compacting": async (input, output) => { + // Inject additional context into the compaction prompt + output.context.push(` +## Custom Context + +Include any state that should persist across compaction: +- Current task status +- Important decisions made +- Files being actively worked on +`) + }, + } +} +``` + +The `experimental.session.compacting` hook fires before the LLM generates a continuation summary. Use it to inject domain-specific context that the default compaction prompt would miss. + +You can also replace the compaction prompt entirely by setting `output.prompt`: + +```ts title=".codev/plugins/custom-compaction.ts" +import type { Plugin } from "@opencode-ai/plugin" + +export const CustomCompactionPlugin: Plugin = async (ctx) => { + return { + "experimental.session.compacting": async (input, output) => { + // Replace the entire compaction prompt + output.prompt = ` +You are generating a continuation prompt for a multi-agent swarm session. + +Summarize: +1. The current task and its status +2. Which files are being modified and by whom +3. Any blockers or dependencies between agents +4. The next steps to complete the work + +Format as a structured prompt that a new agent can use to resume work. +` + }, + } +} +``` + +When `output.prompt` is set, it completely replaces the default compaction prompt. The `output.context` array is ignored in this case. diff --git a/packages/web/src/content/docs/policies.mdx b/packages/web/src/content/docs/policies.mdx new file mode 100644 index 0000000000..2977e78371 --- /dev/null +++ b/packages/web/src/content/docs/policies.mdx @@ -0,0 +1,137 @@ +--- +title: Policies +description: Control which configured resources CoDev Code may use. +--- + +Policies control whether CoDev Code may perform an action on a named resource. This feature is experimental and is configured with the `experimental.policies` array in `codev.json`. + +Policies are separate from [permissions](/docs/permissions). Permissions control what tools can do during a session, while policies control whether CoDev Code may use a resource such as an LLM provider. + +--- + +## Configuration + +Each policy statement has three fields: + +- `effect` - Either `"allow"` or `"deny"`. +- `action` - The operation being controlled. +- `resource` - The resource ID or wildcard pattern the statement applies to. + +For example, deny use of the `openai` provider: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "experimental": { + "policies": [ + { + "effect": "deny", + "action": "provider.use", + "resource": "openai" + } + ] + } +} +``` + +A provider denied by policy is not available for model selection or model use, even if it has credentials or is otherwise configured correctly. + +--- + +## Available Policies + +CoDev Code currently supports one policy action: + +| Action | Resource | Description | +| -------------- | ----------------------------- | ------------------------------------- | +| `provider.use` | Provider ID, such as `openai` | Allow or deny use of an LLM provider. | + +More policy actions may be added in the future. + +--- + +## Matching + +The `resource` field supports wildcard matching. Use `*` to match zero or more characters and `?` to match one character. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "experimental": { + "policies": [ + { + "effect": "deny", + "action": "provider.use", + "resource": "company-*" + } + ] + } +} +``` + +This denies providers such as `company-us` and `company-eu`. + +--- + +## Rule Order + +When multiple statements match, the last matching statement wins. Put broad rules first, then more specific exceptions after them. + +For example, allow only Anthropic: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "experimental": { + "policies": [ + { + "effect": "deny", + "action": "provider.use", + "resource": "*" + }, + { + "effect": "allow", + "action": "provider.use", + "resource": "anthropic" + } + ] + } +} +``` + +If no policy matches a provider, provider use is allowed by default. + +Policies may be set in both your global config and project config. If policies from both locations match the same provider, your global policy takes priority over the project policy. This prevents a repository from re-enabling a provider that you deny globally. + +--- + +## Provider Lists + +Use policies instead of the older `disabled_providers` and `enabled_providers` settings when controlling provider access. + +To replace `disabled_providers`: + +```json title="codev.json" +{ + "experimental": { + "policies": [ + { "effect": "deny", "action": "provider.use", "resource": "openai" }, + { "effect": "deny", "action": "provider.use", "resource": "google" } + ] + } +} +``` + +To replace `enabled_providers`, deny all providers first and allow the selected providers after it: + +```json title="codev.json" +{ + "experimental": { + "policies": [ + { "effect": "deny", "action": "provider.use", "resource": "*" }, + { "effect": "allow", "action": "provider.use", "resource": "anthropic" }, + { "effect": "allow", "action": "provider.use", "resource": "openai" } + ] + } +} +``` diff --git a/packages/web/src/content/docs/providers.mdx b/packages/web/src/content/docs/providers.mdx new file mode 100644 index 0000000000..60a7d8941e --- /dev/null +++ b/packages/web/src/content/docs/providers.mdx @@ -0,0 +1,2501 @@ +--- +title: Providers +description: Using any LLM provider in CoDev Code. +--- + +import config from "../../../config.mjs" +export const console = config.console + +CoDev Code uses the [AI SDK](https://ai-sdk.dev/) and [Models.dev](https://models.dev) to support **75+ LLM providers** and it supports running local models. + +To add a provider you need to: + +1. Add the API keys for the provider using the `/connect` command. +2. Configure the provider in your CoDev Code config. + +--- + +### Credentials + +When you add a provider's API keys with the `/connect` command, they are stored +in `~/.local/share/codev/auth.json`. + +--- + +### Config + +You can customize the providers through the `provider` section in your CoDev Code +config. + +--- + +#### Base URL + +You can customize the base URL for any provider by setting the `baseURL` option. This is useful when using proxy services or custom endpoints. + +```json title="codev.json" {6} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "anthropic": { + "options": { + "baseURL": "https://api.anthropic.com/v1" + } + } + } +} +``` + +--- + +#### Hiding models + +You can hide specific models from the `/models` picker for a provider using the `blacklist` option. This is useful when a provider exposes models you don't want to use or select. + +```json title="codev.json" {6} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "anthropic": { + "blacklist": ["claude-opus-4-20250514"] + } + } +} +``` + +The inverse `whitelist` option hides every model except the ones listed. + +```json title="codev.json" {6} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "anthropic": { + "whitelist": ["claude-sonnet-4-20250514"] + } + } +} +``` + +Both options take an array of model IDs — the same IDs shown in the `/models` picker. + +- `blacklist` removes the listed models from the picker. +- `whitelist` keeps only the listed models and hides the rest. +- You can combine them: `whitelist` narrows the set, then `blacklist` removes entries from it. + +--- + +## OpenCode Zen + +OpenCode Zen is a list of models provided by the OpenCode team that have been +tested and verified to work well with CoDev Code. [Learn more](/docs/zen). + +:::tip +If you are new, we recommend starting with OpenCode Zen. +::: + +1. Run the `/connect` command in the TUI, select `OpenCode Zen`, and head to [opencode.ai/auth](https://opencode.ai/zen). + + ```txt + /connect + ``` + +2. Sign in, add your billing details, and copy your API key. + +3. Paste your API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run `/models` in the TUI to see the list of models we recommend. + + ```txt + /models + ``` + +It works like any other provider in CoDev Code and is completely optional to use. + +--- + +## OpenCode Go + +OpenCode Go is a low cost subscription plan that provides reliable access to popular open coding models provided by the OpenCode team that have been +tested and verified to work well with CoDev Code. + +1. Run the `/connect` command in the TUI, select `OpenCode Go`, and head to [opencode.ai/auth](https://opencode.ai/zen). + + ```txt + /connect + ``` + +2. Sign in, add your billing details, and copy your API key. + +3. Paste your API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run `/models` in the TUI to see the list of models we recommend. + + ```txt + /models + ``` + +It works like any other provider in CoDev Code and is completely optional to use. + +--- + +## Directory + +Let's look at some of the providers in detail. If you'd like to add a provider to the +list, feel free to open a PR. + +:::note +Don't see a provider here? Submit a PR. +::: + +--- + +### 302.AI + +1. Head over to the [302.AI console](https://302.ai/), create an account, and generate an API key. + +2. Run the `/connect` command and search for **302.AI**. + + ```txt + /connect + ``` + +3. Enter your 302.AI API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model. + + ```txt + /models + ``` + +--- + +### Amazon Bedrock + +To use Amazon Bedrock with CoDev Code: + +1. Head over to the **Model catalog** in the Amazon Bedrock console and request + access to the models you want. + + :::tip + You need to have access to the model you want in Amazon Bedrock. + ::: + +2. **Configure authentication** using one of the following methods: + + *** + + #### Environment Variables (Quick Start) + + Set one of these environment variables while running CoDev Code: + + ```bash + # Option 1: Using AWS access keys + AWS_ACCESS_KEY_ID=XXX AWS_SECRET_ACCESS_KEY=YYY codev + + # Option 2: Using named AWS profile + AWS_PROFILE=my-profile codev + + # Option 3: Using Bedrock bearer token + AWS_BEARER_TOKEN_BEDROCK=XXX codev + ``` + + Or add them to your bash profile: + + ```bash title="~/.bash_profile" + export AWS_PROFILE=my-dev-profile + export AWS_REGION=us-east-1 + ``` + + *** + + #### Configuration File (Recommended) + + For project-specific or persistent configuration, use `codev.json`: + + ```json title="codev.json" + { + "$schema": "https://opencode.ai/config.json", + "provider": { + "amazon-bedrock": { + "options": { + "region": "us-east-1", + "profile": "my-aws-profile" + } + } + } + } + ``` + + **Available options:** + - `region` - AWS region (e.g., `us-east-1`, `eu-west-1`) + - `profile` - AWS named profile from `~/.aws/credentials` + - `endpoint` - Custom endpoint URL for VPC endpoints (alias for generic `baseURL` option) + + :::tip + Configuration file options take precedence over environment variables. + ::: + + *** + + #### Advanced: VPC Endpoints + + If you're using VPC endpoints for Bedrock: + + ```json title="codev.json" + { + "$schema": "https://opencode.ai/config.json", + "provider": { + "amazon-bedrock": { + "options": { + "region": "us-east-1", + "profile": "production", + "endpoint": "https://bedrock-runtime.us-east-1.vpce-xxxxx.amazonaws.com" + } + } + } + } + ``` + + :::note + The `endpoint` option is an alias for the generic `baseURL` option, using AWS-specific terminology. If both `endpoint` and `baseURL` are specified, `endpoint` takes precedence. + ::: + + *** + + #### Authentication Methods + - **`AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY`**: Create an IAM user and generate access keys in the AWS Console + - **`AWS_PROFILE`**: Use named profiles from `~/.aws/credentials`. First configure with `aws configure --profile my-profile` or `aws sso login` + - **`AWS_BEARER_TOKEN_BEDROCK`**: Generate long-term API keys from the Amazon Bedrock console + - **`AWS_WEB_IDENTITY_TOKEN_FILE` / `AWS_ROLE_ARN`**: For EKS IRSA (IAM Roles for Service Accounts) or other Kubernetes environments with OIDC federation. These environment variables are automatically injected by Kubernetes when using service account annotations. + + *** + + #### Authentication Precedence + + Amazon Bedrock uses the following authentication priority: + 1. **Bearer Token** - `AWS_BEARER_TOKEN_BEDROCK` environment variable or token from `/connect` command + 2. **AWS Credential Chain** - Profile, access keys, shared credentials, IAM roles, Web Identity Tokens (EKS IRSA), instance metadata + + :::note + When a bearer token is set (via `/connect` or `AWS_BEARER_TOKEN_BEDROCK`), it takes precedence over all AWS credential methods including configured profiles. + ::: + +3. Run the `/models` command to select the model you want. + + ```txt + /models + ``` + +:::note +For custom inference profiles, use the model and provider name in the key and set the `id` property to the arn. This ensures correct caching. +::: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "amazon-bedrock": { + // ... + "models": { + "anthropic-claude-sonnet-4.5": { + "id": "arn:aws:bedrock:us-east-1:xxx:application-inference-profile/yyy" + } + } + } + } +} +``` + +--- + +### Anthropic + +1. Once you've signed up, run the `/connect` command and select Anthropic. + + ```txt + /connect + ``` + +2. Here you can select the **Claude Pro/Max** option and it'll open your browser + and ask you to authenticate. + + ```txt + ┌ Select auth method + │ + │ Manually enter API Key + └ + ``` + +3. Now all the Anthropic models should be available when you use the `/models` command. + + ```txt + /models + ``` + +:::info +There are plugins that allow you to use your Claude Pro/Max models with +CoDev Code. Anthropic explicitly prohibits this. + +Previous versions of CoDev Code came bundled with these plugins but that is no +longer the case as of 1.3.0 + +Other companies support freedom of choice with developer tooling - you can use +the following subscriptions in CoDev Code with zero setup: + +- ChatGPT Plus +- Github Copilot +- Gitlab Duo + ::: + +--- + +### Atomic Chat + +You can configure CoDev Code to use local models through [Atomic Chat](https://atomic.chat), a desktop application that runs local LLMs behind an OpenAI-compatible API server (default endpoint `http://127.0.0.1:1337/v1`). + +```json title="codev.json" "atomic-chat" {5, 6, 8, 10-14} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "atomic-chat": { + "npm": "@ai-sdk/openai-compatible", + "name": "Atomic Chat (local)", + "options": { + "baseURL": "http://127.0.0.1:1337/v1" + }, + "models": { + "": { + "name": "" + } + } + } + } +} +``` + +In this example: + +- `atomic-chat` is the custom provider ID. This can be any string you want. +- `npm` specifies the package to use for this provider. Here, `@ai-sdk/openai-compatible` is used for any OpenAI-compatible API. +- `name` is the display name for the provider in the UI. +- `options.baseURL` is the endpoint for the local server. Change the host and port to match your Atomic Chat setup. +- `models` is a map of model IDs to their display names. Each ID must match the `id` returned by `GET /v1/models` — run `curl http://127.0.0.1:1337/v1/models` to list the ids currently loaded in Atomic Chat. + +:::tip +If tool calls aren't working well, pick a loaded model with strong tool-calling support (for example, a Qwen-Coder or DeepSeek-Coder variant). +::: + +--- + +### Azure OpenAI + +:::note +If you encounter "I'm sorry, but I cannot assist with that request" errors, try changing the content filter from **DefaultV2** to **Default** in your Azure resource. +::: + +1. Head over to the [Azure portal](https://portal.azure.com/) and create an **Azure OpenAI** resource. You'll need: + - **Resource name**: This becomes part of your API endpoint (`https://RESOURCE_NAME.openai.azure.com/`) + - **API key**: Either `KEY 1` or `KEY 2` from your resource + +2. Go to [Azure AI Foundry](https://ai.azure.com/) and deploy a model. + + :::note + The deployment name must match the model name for CoDev Code to work properly. + ::: + +3. Run the `/connect` command and search for **Azure**. + + ```txt + /connect + ``` + +4. Enter your API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +5. Set your resource name as an environment variable: + + ```bash + AZURE_RESOURCE_NAME=XXX codev + ``` + + Or add it to your bash profile: + + ```bash title="~/.bash_profile" + export AZURE_RESOURCE_NAME=XXX + ``` + +6. Run the `/models` command to select your deployed model. + + ```txt + /models + ``` + +--- + +### Azure Cognitive Services + +1. Head over to the [Azure portal](https://portal.azure.com/) and create an **Azure OpenAI** resource. You'll need: + - **Resource name**: This becomes part of your API endpoint (`https://AZURE_COGNITIVE_SERVICES_RESOURCE_NAME.cognitiveservices.azure.com/`) + - **API key**: Either `KEY 1` or `KEY 2` from your resource + +2. Go to [Azure AI Foundry](https://ai.azure.com/) and deploy a model. + + :::note + The deployment name must match the model name for CoDev Code to work properly. + ::: + +3. Run the `/connect` command and search for **Azure Cognitive Services**. + + ```txt + /connect + ``` + +4. Enter your API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +5. Set your resource name as an environment variable: + + ```bash + AZURE_COGNITIVE_SERVICES_RESOURCE_NAME=XXX codev + ``` + + Or add it to your bash profile: + + ```bash title="~/.bash_profile" + export AZURE_COGNITIVE_SERVICES_RESOURCE_NAME=XXX + ``` + +6. Run the `/models` command to select your deployed model. + + ```txt + /models + ``` + +--- + +### Baseten + +1. Head over to the [Baseten](https://app.baseten.co/), create an account, and generate an API key. + +2. Run the `/connect` command and search for **Baseten**. + + ```txt + /connect + ``` + +3. Enter your Baseten API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model. + + ```txt + /models + ``` + +--- + +### Cerebras + +1. Head over to the [Cerebras console](https://inference.cerebras.ai/), create an account, and generate an API key. + +2. Run the `/connect` command and search for **Cerebras**. + + ```txt + /connect + ``` + +3. Enter your Cerebras API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _Qwen 3 Coder 480B_. + + ```txt + /models + ``` + +--- + +### Cloudflare AI Gateway + +Cloudflare AI Gateway lets you access models from OpenAI, Anthropic, Workers AI, and more through a unified endpoint. With [Unified Billing](https://developers.cloudflare.com/ai-gateway/features/unified-billing/) you don't need separate API keys for each provider. + +1. Head over to the [Cloudflare dashboard](https://dash.cloudflare.com/), navigate to **AI** > **AI Gateway**, and create a new gateway. Note your **Account ID** and **Gateway ID**. + +2. Run the `/connect` command and search for **Cloudflare AI Gateway**. + + ```txt + /connect + ``` + +3. Enter your **Account ID** when prompted. + + ```txt + ┌ Enter your Cloudflare Account ID + │ + │ + └ enter + ``` + +4. Enter your **Gateway ID** when prompted. + + ```txt + ┌ Enter your Cloudflare AI Gateway ID + │ + │ + └ enter + ``` + +5. Enter your **Cloudflare API token**. + + ```txt + ┌ Gateway API token + │ + │ + └ enter + ``` + +6. Run the `/models` command to select a model. + + ```txt + /models + ``` + + You can also add models through your CoDev Code config. + + ```json title="codev.json" + { + "$schema": "https://opencode.ai/config.json", + "provider": { + "cloudflare-ai-gateway": { + "models": { + "openai/gpt-4o": {}, + "anthropic/claude-sonnet-4": {} + } + } + } + } + ``` + + Alternatively, you can set environment variables instead of using `/connect`. + + ```bash title="~/.bash_profile" + export CLOUDFLARE_ACCOUNT_ID=your-32-character-account-id + export CLOUDFLARE_GATEWAY_ID=your-gateway-id + export CLOUDFLARE_API_TOKEN=your-api-token + ``` + +--- + +### Cloudflare Workers AI + +Cloudflare Workers AI lets you run AI models on Cloudflare's global network directly via REST API, with no separate provider accounts needed for supported models. + +1. Head over to the [Cloudflare dashboard](https://dash.cloudflare.com/), navigate to **Workers AI**, and select **Use REST API** to get your **Account ID** and create an API token. + +2. Run the `/connect` command and search for **Cloudflare Workers AI**. + + ```txt + /connect + ``` + +3. Enter your **Account ID** when prompted. + + ```txt + ┌ Enter your Cloudflare Account ID + │ + │ + └ enter + ``` + +4. Enter your **Cloudflare API key**. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +5. Run the `/models` command to select a model. + + ```txt + /models + ``` + + Alternatively, you can set environment variables instead of using `/connect`. + + ```bash title="~/.bash_profile" + export CLOUDFLARE_ACCOUNT_ID=your-32-character-account-id + export CLOUDFLARE_API_KEY=your-api-token + ``` + +--- + +### Cortecs + +1. Head over to the [Cortecs console](https://cortecs.ai/), create an account, and generate an API key. + +2. Run the `/connect` command and search for **Cortecs**. + + ```txt + /connect + ``` + +3. Enter your Cortecs API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _Kimi K2 Instruct_. + + ```txt + /models + ``` + +--- + +### DeepSeek + +1. Head over to the [DeepSeek console](https://platform.deepseek.com/), create an account, and click **Create new API key**. + +2. Run the `/connect` command and search for **DeepSeek**. + + ```txt + /connect + ``` + +3. Enter your DeepSeek API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a DeepSeek model like _DeepSeek V4 Pro_. + + ```txt + /models + ``` + +--- + +### Deep Infra + +1. Head over to the [Deep Infra dashboard](https://deepinfra.com/dash), create an account, and generate an API key. + +2. Run the `/connect` command and search for **Deep Infra**. + + ```txt + /connect + ``` + +3. Enter your Deep Infra API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model. + + ```txt + /models + ``` + +--- + +### DigitalOcean + +DigitalOcean's [Inference Engine](https://docs.digitalocean.com/products/inference/) provides access to open models like GPT-OSS, Llama, Qwen, and DeepSeek, plus custom [Inference Routers](https://docs.digitalocean.com/products/genai-platform/concepts/inference-routers/) that route each request to the cheapest, fastest, or best-fit model for a task. + +CoDev Code supports two authentication methods: + +- **OAuth (Recommended)** — Sign in to your DigitalOcean account; CoDev Code uses your DigitalOcean API token directly for inference and discovers your Inference Routers. +- **Model Access Key** — Paste an existing key from the DigitalOcean console. + +#### OAuth (Recommended) + +1. Run the `/connect` command and search for **DigitalOcean**. + + ```txt + /connect + ``` + +2. Select **Login with DigitalOcean**. + + ```txt + ┌ Select auth method + │ + │ Login with DigitalOcean + │ Paste Model Access Key + └ + ``` + +3. Your browser opens to authorize CoDev Code. Sign in and approve. + + :::note + CoDev Code requests `genai:read` and `inference:query` OAuth scopes. Your DigitalOcean API token is used directly for inference — no separate Model Access Key is created. + ::: + + :::note + Inference Routers only appear in the model picker after OAuth. Pasting a Model Access Key manually does not discover routers. + ::: + +4. Run the `/models` command. Your Inference Routers appear as the format `router:` in the model selection. + + ```txt + /models + ``` + +5. To pick up newly created Inference Routers, re-run `/connect` and select **DigitalOcean** again. + +#### Using a Model Access Key + +If you'd rather paste a key directly: + +1. Head over to the **Manage** page in the Inference section of the [DigitalOcean console](https://cloud.digitalocean.com/) and create a new key. + +2. Run the `/connect` command and select **DigitalOcean**, then **Paste Model Access Key**. + + ```txt + ┌ Enter your DigitalOcean Model Access Key + │ + │ + └ enter + ``` + + :::note + Inference Routers are not auto-discovered with this method. To surface them in the model picker, sign in via OAuth instead. + ::: + +3. Run the `/models` command to select a model. + + ```txt + /models + ``` + +#### Environment Variable + +Alternatively, set your Model Access Key as an environment variable. + +```bash frame="none" +export DIGITALOCEAN_ACCESS_TOKEN=your-model-access-key +``` + +#### Inference Routers + +Inference Routers let you define a routing policy across multiple models — picking the cheapest, fastest, or most appropriate model per request based on the task. After OAuth, CoDev Code surfaces each router as `router:` in the model picker. + +Selecting a router model is a drop-in replacement for any other model — CoDev Code forwards your request and DigitalOcean picks the underlying model based on your router's policy. Learn more about [Inference Routers](https://docs.digitalocean.com/products/inference/how-to/use-inference-router/) + +--- + +### FrogBot + +1. Head over to the [FrogBot dashboard](https://app.frogbot.ai/signup), create an account, and generate an API key. + +2. Run the `/connect` command and search for **FrogBot**. + + ```txt + /connect + ``` + +3. Enter your FrogBot API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model. + + ```txt + /models + ``` + +--- + +### Fireworks AI + +1. Head over to the [Fireworks AI console](https://app.fireworks.ai/), create an account, and click **Create API Key**. + +2. Run the `/connect` command and search for **Fireworks AI**. + + ```txt + /connect + ``` + +3. Enter your Fireworks AI API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _Kimi K2 Instruct_. + + ```txt + /models + ``` + +--- + +### GitLab Duo + +:::caution[Experimental] +GitLab Duo support in CoDev Code is experimental. Features, configuration, and +behavior may change in future releases. +::: + +CoDev Code integrates with the [GitLab Duo Agent Platform](https://docs.gitlab.com/user/duo_agent_platform/), +providing AI-powered agentic chat with native tool calling capabilities. + +:::note[License requirements] +GitLab Duo Agent Platform requires a **Premium** or **Ultimate** GitLab +subscription. It is available on GitLab.com and GitLab Self-Managed. +See [GitLab Duo Agent Platform prerequisites](https://docs.gitlab.com/user/duo_agent_platform/#prerequisites) +for full requirements. +::: + +1. Run the `/connect` command and select GitLab. + + ```txt + /connect + ``` + +2. Choose your authentication method: + + ```txt + ┌ Select auth method + │ + │ OAuth (Recommended) + │ Personal Access Token + └ + ``` + + #### Using OAuth (Recommended) + + Select **OAuth** and your browser will open for authorization. + + #### Using Personal Access Token + 1. Go to [GitLab User Settings > Access Tokens](https://gitlab.com/-/user_settings/personal_access_tokens) + 2. Click **Add new token** + 3. Name: `CoDev Code`, Scopes: `api` + 4. Copy the token (starts with `glpat-`) + 5. Enter it in the terminal + +3. Run the `/models` command to see available models. + + ```txt + /models + ``` + + Three Claude-based models are available: + - **duo-chat-haiku-4-5** (Default) - Fast responses for quick tasks + - **duo-chat-sonnet-4-5** - Balanced performance for most workflows + - **duo-chat-opus-4-5** - Most capable for complex analysis + +:::note +You can also specify 'GITLAB_TOKEN' environment variable if you don't want +to store token in CoDev Code auth storage. +::: + +##### Self-Hosted GitLab + +:::note[compliance note] +CoDev Code uses a small model for some AI tasks like generating the session title. +It is configured to use gpt-5-nano by default, hosted by Zen. To lock CoDev Code +to only use your own GitLab-hosted instance, add the following to your +`codev.json` file. It is also recommended to disable session sharing. + +```json +{ + "$schema": "https://opencode.ai/config.json", + "small_model": "gitlab/duo-chat-haiku-4-5", + "share": "disabled" +} +``` + +::: + +For self-hosted GitLab instances: + +```bash +export GITLAB_INSTANCE_URL=https://gitlab.company.com +export GITLAB_TOKEN=glpat-... +``` + +If your instance runs a custom AI Gateway: + +```bash +GITLAB_AI_GATEWAY_URL=https://ai-gateway.company.com +``` + +Or add to your bash profile: + +```bash title="~/.bash_profile" +export GITLAB_INSTANCE_URL=https://gitlab.company.com +export GITLAB_AI_GATEWAY_URL=https://ai-gateway.company.com +export GITLAB_TOKEN=glpat-... +``` + +:::note +Your GitLab administrator must: + +1. [Turn on GitLab Duo](https://docs.gitlab.com/user/duo_agent_platform/turn_on_off/#turn-gitlab-duo-on-or-off) + for the user, group, or instance +2. [Turn on the Agent Platform](https://docs.gitlab.com/user/duo_agent_platform/turn_on_off/#turn-gitlab-duo-agent-platform-on-or-off) + (GitLab 18.8+) or [enable beta and experimental features](https://docs.gitlab.com/user/duo_agent_platform/turn_on_off/#turn-on-beta-and-experimental-features) + (GitLab 18.7 and earlier) +3. For Self-Managed, [configure your instance](https://docs.gitlab.com/administration/gitlab_duo/configure/gitlab_self_managed/) + ::: + +##### OAuth for Self-Hosted instances + +In order to make Oauth working for your self-hosted instance, you need to create +a new application (Settings → Applications) with the +callback URL `http://127.0.0.1:8080/callback` and following scopes: + +- api (Access the API on your behalf) +- read_user (Read your personal information) +- read_repository (Allows read-only access to the repository) + +Then expose application ID as environment variable: + +```bash +export GITLAB_OAUTH_CLIENT_ID=your_application_id_here +``` + +More documentation on [opencode-gitlab-auth](https://www.npmjs.com/package/opencode-gitlab-auth) homepage. + +##### Configuration + +Customize through `codev.json`: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "gitlab": { + "options": { + "instanceUrl": "https://gitlab.com" + } + } + } +} +``` + +##### GitLab Duo Agent Platform (DAP) Workflow Models + +DAP workflow models provide an alternative execution path that routes tool calls +through GitLab's Duo Workflow Service (DWS) instead of the standard agentic chat. +When a `duo-workflow-*` model is selected, CoDev Code will: + +1. Discover available models from your GitLab namespace +2. Present a selection picker if multiple models are available +3. Cache the selected model to disk for fast subsequent startups +4. Route tool execution requests through CoDev Code's permission-gated tool system + +Available DAP workflow models follow the `duo-workflow-*` naming convention and +are dynamically discovered from your GitLab instance. + +##### GitLab API Tools (Optional, but highly recommended) + +To access GitLab tools (merge requests, issues, pipelines, CI/CD, etc.): + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "plugin": ["opencode-gitlab-plugin"] +} +``` + +This plugin provides comprehensive GitLab repository management capabilities including MR reviews, issue tracking, pipeline monitoring, and more. + +--- + +### GitHub Copilot + +To use your GitHub Copilot subscription with CoDev Code: + +:::note +Some models might need a [Pro+ +subscription](https://github.com/features/copilot/plans) to use. +::: + +1. Run the `/connect` command and search for GitHub Copilot. + + ```txt + /connect + ``` + +2. Navigate to [github.com/login/device](https://github.com/login/device) and enter the code. + + ```txt + ┌ Login with GitHub Copilot + │ + │ https://github.com/login/device + │ + │ Enter code: 8F43-6FCF + │ + └ Waiting for authorization... + ``` + +3. Now run the `/models` command to select the model you want. + + ```txt + /models + ``` + +--- + +### GMI Cloud + +To use GMI Cloud with CoDev Code: + +1. Head over to the [GMI Cloud console](https://console.gmicloud.ai/) to create an API key. You can also review the [API reference](https://docs.gmicloud.ai/inference-engine/api-reference/llm-api-reference) for the endpoint details. + +2. Run the `/connect` command and search for **GMI Cloud**. + + ```txt + /connect + ``` + +3. Enter your GMI Cloud API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select the model you want. + + ```txt + /models + ``` + +--- + +### Google Vertex AI + +To use Google Vertex AI with CoDev Code: + +1. Head over to the **Model Garden** in the Google Cloud Console and check the + models available in your region. + + :::note + You need to have a Google Cloud project with Vertex AI API enabled. + ::: + +2. Set the required environment variables: + - `GOOGLE_CLOUD_PROJECT`: Your Google Cloud project ID + - `VERTEX_LOCATION` (optional): The region for Vertex AI (defaults to `global`) + - Authentication (choose one): + - `GOOGLE_APPLICATION_CREDENTIALS`: Path to your service account JSON key file + - Authenticate using gcloud CLI: `gcloud auth application-default login` + + Set them while running CoDev Code. + + ```bash + GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json GOOGLE_CLOUD_PROJECT=your-project-id codev + ``` + + Or add them to your bash profile. + + ```bash title="~/.bash_profile" + export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json + export GOOGLE_CLOUD_PROJECT=your-project-id + export VERTEX_LOCATION=global + ``` + +:::tip +The `global` region improves availability and reduces errors at no extra cost. Use regional endpoints (e.g., `us-central1`) for data residency requirements. [Learn more](https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-partner-models#regional_and_global_endpoints) +::: + +3. Run the `/models` command to select the model you want. + + ```txt + /models + ``` + +--- + +### Groq + +1. Head over to the [Groq console](https://console.groq.com/), click **Create API Key**, and copy the key. + +2. Run the `/connect` command and search for Groq. + + ```txt + /connect + ``` + +3. Enter the API key for the provider. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select the one you want. + + ```txt + /models + ``` + +--- + +### Hugging Face + +[Hugging Face Inference Providers](https://huggingface.co/docs/inference-providers) provides access to open models supported by 17+ providers. + +1. Head over to [Hugging Face settings](https://huggingface.co/settings/tokens/new?ownUserPermissions=inference.serverless.write&tokenType=fineGrained) to create a token with permission to make calls to Inference Providers. + +2. Run the `/connect` command and search for **Hugging Face**. + + ```txt + /connect + ``` + +3. Enter your Hugging Face token. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _Kimi-K2-Instruct_ or _GLM-4.6_. + + ```txt + /models + ``` + +--- + +### Helicone + +[Helicone](https://helicone.ai) is an LLM observability platform that provides logging, monitoring, and analytics for your AI applications. The Helicone AI Gateway routes your requests to the appropriate provider automatically based on the model. + +1. Head over to [Helicone](https://helicone.ai), create an account, and generate an API key from your dashboard. + +2. Run the `/connect` command and search for **Helicone**. + + ```txt + /connect + ``` + +3. Enter your Helicone API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model. + + ```txt + /models + ``` + +For more providers and advanced features like caching and rate limiting, check the [Helicone documentation](https://docs.helicone.ai). + +#### Optional Configs + +In the event you see a feature or model from Helicone that isn't configured automatically through CoDev Code, you can always configure it yourself. + +Here's [Helicone's Model Directory](https://helicone.ai/models), you'll need this to grab the IDs of the models you want to add. + +```jsonc title="~/.config/codev/codev.jsonc" +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "helicone": { + "npm": "@ai-sdk/openai-compatible", + "name": "Helicone", + "options": { + "baseURL": "https://ai-gateway.helicone.ai", + }, + "models": { + "gpt-4o": { + // Model ID (from Helicone's model directory page) + "name": "GPT-4o", // Your own custom name for the model + }, + "claude-sonnet-4-20250514": { + "name": "Claude Sonnet 4", + }, + }, + }, + }, +} +``` + +#### Custom Headers + +Helicone supports custom headers for features like caching, user tracking, and session management. Add them to your provider config using `options.headers`: + +```jsonc title="~/.config/codev/codev.jsonc" +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "helicone": { + "npm": "@ai-sdk/openai-compatible", + "name": "Helicone", + "options": { + "baseURL": "https://ai-gateway.helicone.ai", + "headers": { + "Helicone-Cache-Enabled": "true", + "Helicone-User-Id": "opencode", + }, + }, + }, + }, +} +``` + +##### Session tracking + +Helicone's [Sessions](https://docs.helicone.ai/features/sessions) feature lets you group related LLM requests together. Use the [opencode-helicone-session](https://github.com/H2Shami/opencode-helicone-session) plugin to automatically log each CoDev Code conversation as a session in Helicone. + +```bash +npm install -g opencode-helicone-session +``` + +Add it to your config. + +```json title="codev.json" +{ + "plugin": ["opencode-helicone-session"] +} +``` + +The plugin injects `Helicone-Session-Id` and `Helicone-Session-Name` headers into your requests. In Helicone's Sessions page, you'll see each CoDev Code conversation listed as a separate session. + +##### Common Helicone headers + +| Header | Description | +| -------------------------- | ------------------------------------------------------------- | +| `Helicone-Cache-Enabled` | Enable response caching (`true`/`false`) | +| `Helicone-User-Id` | Track metrics by user | +| `Helicone-Property-[Name]` | Add custom properties (e.g., `Helicone-Property-Environment`) | +| `Helicone-Prompt-Id` | Associate requests with prompt versions | + +See the [Helicone Header Directory](https://docs.helicone.ai/helicone-headers/header-directory) for all available headers. + +--- + +### llama.cpp + +You can configure CoDev Code to use local models through [llama.cpp's](https://github.com/ggml-org/llama.cpp) llama-server utility + +```json title="codev.json" "llama.cpp" {5, 6, 8, 10-15} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "llama.cpp": { + "npm": "@ai-sdk/openai-compatible", + "name": "llama-server (local)", + "options": { + "baseURL": "http://127.0.0.1:8080/v1" + }, + "models": { + "qwen3-coder:a3b": { + "name": "Qwen3-Coder: a3b-30b (local)", + "limit": { + "context": 128000, + "output": 65536 + } + } + } + } + } +} +``` + +In this example: + +- `llama.cpp` is the custom provider ID. This can be any string you want. +- `npm` specifies the package to use for this provider. Here, `@ai-sdk/openai-compatible` is used for any OpenAI-compatible API. +- `name` is the display name for the provider in the UI. +- `options.baseURL` is the endpoint for the local server. +- `models` is a map of model IDs to their configurations. The model name will be displayed in the model selection list. + +--- + +### IO.NET + +IO.NET offers 17 models optimized for various use cases: + +1. Head over to the [IO.NET console](https://ai.io.net/), create an account, and generate an API key. + +2. Run the `/connect` command and search for **IO.NET**. + + ```txt + /connect + ``` + +3. Enter your IO.NET API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model. + + ```txt + /models + ``` + +--- + +### LM Studio + +You can configure CoDev Code to use local models through LM Studio. + +```json title="codev.json" "lmstudio" {5, 6, 8, 10-14} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "lmstudio": { + "npm": "@ai-sdk/openai-compatible", + "name": "LM Studio (local)", + "options": { + "baseURL": "http://127.0.0.1:1234/v1" + }, + "models": { + "google/gemma-3n-e4b": { + "name": "Gemma 3n-e4b (local)" + } + } + } + } +} +``` + +In this example: + +- `lmstudio` is the custom provider ID. This can be any string you want. +- `npm` specifies the package to use for this provider. Here, `@ai-sdk/openai-compatible` is used for any OpenAI-compatible API. +- `name` is the display name for the provider in the UI. +- `options.baseURL` is the endpoint for the local server. +- `models` is a map of model IDs to their configurations. The model name will be displayed in the model selection list. + +--- + +### Moonshot AI + +To use Kimi K2 from Moonshot AI: + +1. Head over to the [Moonshot AI console](https://platform.moonshot.ai/console), create an account, and click **Create API key**. + +2. Run the `/connect` command and search for **Moonshot AI**. + + ```txt + /connect + ``` + +3. Enter your Moonshot API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select _Kimi K2_. + + ```txt + /models + ``` + +--- + +### MiniMax + +1. Head over to the [MiniMax API Console](https://platform.minimax.io/login), create an account, and generate an API key. + +2. Run the `/connect` command and search for **MiniMax**. + + ```txt + /connect + ``` + +3. Enter your MiniMax API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _M2.1_. + + ```txt + /models + ``` + +--- + +### NVIDIA + +NVIDIA provides access to Nemotron models and many other open models through [build.nvidia.com](https://build.nvidia.com) for free. + +1. Head over to [build.nvidia.com](https://build.nvidia.com), create an account, and generate an API key. + +2. Run the `/connect` command and search for **NVIDIA**. + + ```txt + /connect + ``` + +3. Enter your NVIDIA API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like nemotron-3-super-120b-a12b. + + ```txt + /models + ``` + +#### On-Prem / NIM + +You can also use NVIDIA models locally via [NVIDIA NIM](https://docs.nvidia.com/nim/) by setting a custom base URL. + +```json title="codev.json" {6} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "nvidia": { + "options": { + "baseURL": "http://localhost:8000/v1" + } + } + } +} +``` + +#### Environment Variable + +Alternatively, set your API key as an environment variable. + +```bash frame="none" +export NVIDIA_API_KEY=nvapi-your-key-here +``` + +--- + +### Nebius Token Factory + +1. Head over to the [Nebius Token Factory console](https://tokenfactory.nebius.com/), create an account, and click **Add Key**. + +2. Run the `/connect` command and search for **Nebius Token Factory**. + + ```txt + /connect + ``` + +3. Enter your Nebius Token Factory API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _Kimi K2 Instruct_. + + ```txt + /models + ``` + +--- + +### Ollama + +You can configure CoDev Code to use local models through Ollama. + +:::tip +Ollama can automatically configure itself for CoDev Code. See the [Ollama integration docs](https://docs.ollama.com/integrations/opencode) for details. +::: + +```json title="codev.json" "ollama" {5, 6, 8, 10-14} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "ollama": { + "npm": "@ai-sdk/openai-compatible", + "name": "Ollama (local)", + "options": { + "baseURL": "http://localhost:11434/v1" + }, + "models": { + "llama2": { + "name": "Llama 2" + } + } + } + } +} +``` + +In this example: + +- `ollama` is the custom provider ID. This can be any string you want. +- `npm` specifies the package to use for this provider. Here, `@ai-sdk/openai-compatible` is used for any OpenAI-compatible API. +- `name` is the display name for the provider in the UI. +- `options.baseURL` is the endpoint for the local server. +- `models` is a map of model IDs to their configurations. The model name will be displayed in the model selection list. + +:::tip +If tool calls aren't working, try increasing `num_ctx` in Ollama. Start around 16k - 32k. +::: + +--- + +### Ollama Cloud + +To use Ollama Cloud with CoDev Code: + +1. Head over to [https://ollama.com/](https://ollama.com/) and sign in or create an account. + +2. Navigate to **Settings** > **Keys** and click **Add API Key** to generate a new API key. + +3. Copy the API key for use in CoDev Code. + +4. Run the `/connect` command and search for **Ollama Cloud**. + + ```txt + /connect + ``` + +5. Enter your Ollama Cloud API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +6. **Important**: Before using cloud models in CoDev Code, you must pull the model information locally: + + ```bash + ollama pull gpt-oss:20b-cloud + ``` + +7. Run the `/models` command to select your Ollama Cloud model. + + ```txt + /models + ``` + +--- + +### OpenAI + +We recommend signing up for [ChatGPT Plus or Pro](https://chatgpt.com/pricing). + +1. Once you've signed up, run the `/connect` command and select OpenAI. + + ```txt + /connect + ``` + +2. Here you can select the **ChatGPT Plus/Pro** option and it'll open your browser + and ask you to authenticate. + + ```txt + ┌ Select auth method + │ + │ ChatGPT Plus/Pro + │ Manually enter API Key + └ + ``` + +3. Now all the OpenAI models should be available when you use the `/models` command. + + ```txt + /models + ``` + +##### Using API keys + +If you already have an API key, you can select **Manually enter API Key** and paste it in your terminal. + +--- + +### OpenCode Zen + +OpenCode Zen is a list of tested and verified models provided by the OpenCode team. [Learn more](/docs/zen). + +1. Sign in to **OpenCode Zen** and click **Create API Key**. + +2. Run the `/connect` command and search for **OpenCode Zen**. + + ```txt + /connect + ``` + +3. Enter your CoDev Code API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _Qwen 3 Coder 480B_. + + ```txt + /models + ``` + +--- + +### OpenRouter + +1. Head over to the [OpenRouter dashboard](https://openrouter.ai/settings/keys), click **Create API Key**, and copy the key. + +2. Run the `/connect` command and search for OpenRouter. + + ```txt + /connect + ``` + +3. Enter the API key for the provider. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Many OpenRouter models are preloaded by default, run the `/models` command to select the one you want. + + ```txt + /models + ``` + + You can also add additional models through your CoDev Code config. + + ```json title="codev.json" {6} + { + "$schema": "https://opencode.ai/config.json", + "provider": { + "openrouter": { + "models": { + "somecoolnewmodel": {} + } + } + } + } + ``` + +5. You can also customize them through your CoDev Code config. Here's an example of specifying a provider + + ```json title="codev.json" + { + "$schema": "https://opencode.ai/config.json", + "provider": { + "openrouter": { + "models": { + "moonshotai/kimi-k2": { + "options": { + "provider": { + "order": ["baseten"], + "allow_fallbacks": false + } + } + } + } + } + } + } + ``` + +--- + +### LLM Gateway + +1. Head over to the [LLM Gateway dashboard](https://llmgateway.io/dashboard), click **Create API Key**, and copy the key. + +2. Run the `/connect` command and search for LLM Gateway. + + ```txt + /connect + ``` + +3. Enter the API key for the provider. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Many LLM Gateway models are preloaded by default, run the `/models` command to select the one you want. + + ```txt + /models + ``` + + You can also add additional models through your CoDev Code config. + + ```json title="codev.json" {6} + { + "$schema": "https://opencode.ai/config.json", + "provider": { + "llmgateway": { + "models": { + "somecoolnewmodel": {} + } + } + } + } + ``` + +5. You can also customize them through your CoDev Code config. Here's an example of specifying a provider + + ```json title="codev.json" + { + "$schema": "https://opencode.ai/config.json", + "provider": { + "llmgateway": { + "models": { + "glm-4.7": { + "name": "GLM 4.7" + }, + "gpt-5.2": { + "name": "GPT-5.2" + }, + "gemini-2.5-pro": { + "name": "Gemini 2.5 Pro" + }, + "claude-3-5-sonnet-20241022": { + "name": "Claude 3.5 Sonnet" + } + } + } + } + } + ``` + +--- + +### SAP AI Core + +SAP AI Core provides access to 40+ models from OpenAI, Anthropic, Google, Amazon, Meta, Mistral, and AI21 through a unified platform. + +1. Go to your [SAP BTP Cockpit](https://account.hana.ondemand.com/), navigate to your SAP AI Core service instance, and create a service key. + + :::tip + The service key is a JSON object containing `clientid`, `clientsecret`, `url`, and `serviceurls.AI_API_URL`. You can find your AI Core instance under **Services** > **Instances and Subscriptions** in the BTP Cockpit. + ::: + +2. Run the `/connect` command and search for **SAP AI Core**. + + ```txt + /connect + ``` + +3. Enter your service key JSON. + + ```txt + ┌ Service key + │ + │ + └ enter + ``` + + Or set the `AICORE_SERVICE_KEY` environment variable: + + ```bash + AICORE_SERVICE_KEY='{"clientid":"...","clientsecret":"...","url":"...","serviceurls":{"AI_API_URL":"..."}}' codev + ``` + + Or add it to your bash profile: + + ```bash title="~/.bash_profile" + export AICORE_SERVICE_KEY='{"clientid":"...","clientsecret":"...","url":"...","serviceurls":{"AI_API_URL":"..."}}' + ``` + +4. Optionally set deployment ID and resource group: + + ```bash + AICORE_DEPLOYMENT_ID=your-deployment-id AICORE_RESOURCE_GROUP=your-resource-group codev + ``` + + :::note + These settings are optional and should be configured according to your SAP AI Core setup. + ::: + +5. Run the `/models` command to select from 40+ available models. + + ```txt + /models + ``` + +--- + +### STACKIT + +STACKIT AI Model Serving provides fully managed sovereign hosting environment for AI models, focusing on LLMs like Llama, Mistral, and Qwen, with maximum data sovereignty on European infrastructure. + +1. Head over to [STACKIT Portal](https://portal.stackit.cloud), navigate to **AI Model Serving**, and create an auth token for your project. + + :::tip + You need a STACKIT customer account, user account, and project before creating auth tokens. + ::: + +2. Run the `/connect` command and search for **STACKIT**. + + ```txt + /connect + ``` + +3. Enter your STACKIT AI Model Serving auth token. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select from available models like _Qwen3-VL 235B_ or _Llama 3.3 70B_. + + ```txt + /models + ``` + +--- + +### OVHcloud AI Endpoints + +1. Head over to the [OVHcloud panel](https://ovh.com/manager). Navigate to the `Public Cloud` section, `AI & Machine Learning` > `AI Endpoints` and in `API Keys` tab, click **Create a new API key**. + +2. Run the `/connect` command and search for **OVHcloud AI Endpoints**. + + ```txt + /connect + ``` + +3. Enter your OVHcloud AI Endpoints API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _gpt-oss-120b_. + + ```txt + /models + ``` + +--- + +### Scaleway + +To use [Scaleway Generative APIs](https://www.scaleway.com/en/docs/generative-apis/) with CoDev Code: + +1. Head over to the [Scaleway Console IAM settings](https://console.scaleway.com/iam/api-keys) to generate a new API key. + +2. Run the `/connect` command and search for **Scaleway**. + + ```txt + /connect + ``` + +3. Enter your Scaleway API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _devstral-2-123b-instruct-2512_ or _gpt-oss-120b_. + + ```txt + /models + ``` + +--- + +### Snowflake Cortex + +[Snowflake Cortex](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-rest-api) gives you access to frontier models (Claude, OpenAI GPT-5, and more) via an OpenAI-compatible API. All inference runs within the Snowflake perimeter and is billed in Snowflake credits. For per-model rates, see the [Snowflake Service Consumption Table](https://www.snowflake.com/legal-files/CreditConsumptionTable.pdf). + +Don't have a Snowflake account? [Sign up for a free trial](https://signup.snowflake.com/?utm_source=opencode&utm_medium=docs&utm_campaign=cortex-provider). + +CoDev Code's core workflow for coding, editing files, and running commands relies on tool calling. Only the Claude and OpenAI families within Snowflake Cortex support this. The provider is limited to those families to support the core workflow. + +CoDev Code supports two authentication methods: + +- **Browser OAuth (Recommended)** — sign in with your IdP/SSO; no secrets to manage, tokens refresh automatically. +- **Manual bearer token** — paste a PAT or JWT from the Snowflake console. + +#### Browser OAuth (Recommended) + +1. Run the `/connect` command and search for **Snowflake Cortex**. + + ```txt + /connect + ``` + +2. Select **Login with Snowflake (External Browser)**. + + ```txt + ┌ Select auth method + │ + │ Login with Snowflake (External Browser) + │ Paste PAT or bearer token manually + └ + ``` + +3. Enter your [account identifier](https://docs.snowflake.com/en/user-guide/admin-account-identifier) when prompted, for example `myorg-myaccount` or `xy12345.us-east-1`. + + ```txt + ┌ Snowflake Account Identifier + │ + │ + └ enter + ``` + +4. Optionally enter a Snowflake role to scope the session (e.g. `SYSADMIN`). Leave blank to use your default role. + +5. Complete sign-in in the browser that opens. CoDev Code captures the OAuth callback automatically and stores the token — no copy/paste needed. + +6. Run the `/models` command to select a model. + + ```txt + /models + ``` + +:::note +Browser OAuth uses Snowflake's built-in `SNOWFLAKE$LOCAL_APPLICATION` security integration ([docs](https://docs.snowflake.com/en/user-guide/oauth-local-applications)), which is rolling out to all accounts. To check availability in your account: + +```sql +SHOW SECURITY INTEGRATIONS LIKE 'SNOWFLAKE$LOCAL_APPLICATION'; +``` + +If the result is empty, use the **Manual bearer token** method below while the integration rolls out to your account. +::: + +#### Manual bearer token + +If you prefer to paste a token directly, or if `SNOWFLAKE$LOCAL_APPLICATION` is not yet available in your account: + +1. Generate a [Programmatic Access Token (PAT)](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) in your Snowflake account. + +2. Run the `/connect` command, search for **Snowflake Cortex**, and select **Paste PAT or bearer token manually**. + +3. Enter your [account identifier](https://docs.snowflake.com/en/user-guide/admin-account-identifier) when prompted. + +4. Paste your PAT. + +5. Run the `/models` command to select a model. + + ```txt + /models + ``` + +#### Environment variable + +For CI or headless environments, set a PAT or JWT before starting CoDev Code: + +```bash +export SNOWFLAKE_ACCOUNT=myorg-myaccount +export SNOWFLAKE_CORTEX_TOKEN=your-pat-or-jwt +``` + +:::note +`SNOWFLAKE_CORTEX_TOKEN` accepts a PAT or JWT only — the browser OAuth flow is available via `/connect` only and cannot be configured through an environment variable. `SNOWFLAKE_CORTEX_PAT` is still supported for backward compatibility. +::: + +The model catalog is provided automatically. A minimal `codev.json` is all that's needed: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "model": "snowflake-cortex/claude-sonnet-4-6", + "small_model": "snowflake-cortex/claude-haiku-4-5" +} +``` + +--- + +### Together AI + +1. Head over to the [Together AI console](https://api.together.ai), create an account, and click **Add Key**. + +2. Run the `/connect` command and search for **Together AI**. + + ```txt + /connect + ``` + +3. Enter your Together AI API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _Kimi K2 Instruct_. + + ```txt + /models + ``` + +--- + +### Venice AI + +1. Head over to the [Venice AI console](https://venice.ai), create an account, and generate an API key. + +2. Run the `/connect` command and search for **Venice AI**. + + ```txt + /connect + ``` + +3. Enter your Venice AI API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _Llama 3.3 70B_. + + ```txt + /models + ``` + +--- + +### Vercel AI Gateway + +Vercel AI Gateway lets you access models from OpenAI, Anthropic, Google, xAI, and more through a unified endpoint. Models are offered at list price with no markup. + +1. Head over to the [Vercel dashboard](https://vercel.com/), navigate to the **AI Gateway** tab, and click **API keys** to create a new API key. + +2. Run the `/connect` command and search for **Vercel AI Gateway**. + + ```txt + /connect + ``` + +3. Enter your Vercel AI Gateway API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model. + + ```txt + /models + ``` + +You can also customize models through your CoDev Code config. Here's an example of specifying provider routing order. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "vercel": { + "models": { + "anthropic/claude-sonnet-4": { + "options": { + "order": ["anthropic", "vertex"] + } + } + } + } + } +} +``` + +Some useful routing options: + +| Option | Description | +| ------------------- | ---------------------------------------------------- | +| `order` | Provider sequence to try | +| `only` | Restrict to specific providers | +| `zeroDataRetention` | Only use providers with zero data retention policies | + +--- + +### xAI + +Three ways to authenticate: a SuperGrok subscription via browser OAuth, the same SuperGrok subscription via a headless device-code flow (for VPS / SSH / Docker), or a pay-as-you-go API key from the xAI console. + +#### Option A — SuperGrok OAuth (browser login) + +1. Run the `/connect` command and search for **xAI**. + + ```txt + /connect + ``` + +2. Select **xAI Grok OAuth (SuperGrok Subscription)**. CoDev Code opens xAI's consent screen in your browser and waits for the callback on `http://127.0.0.1:56121/callback`. + +3. Run the `/models` command to select a Grok model. + + ```txt + /models + ``` + +CoDev Code refreshes the OAuth access token automatically. Any Grok or X Premium plan that includes Grok API access works; you do not need a separate `XAI_API_KEY`. + +#### Option B — SuperGrok device-code (headless / remote server / VPS) + +Use this when CoDev Code is running somewhere a browser can't reach the loopback redirect: a VPS, a remote dev box over SSH, inside Docker, in CI, etc. No callback port is opened on the host running CoDev Code — instead xAI hands the CLI a short code that you type into a browser on any other device (laptop, phone, …). + +1. Run the `/connect` command on the remote host and search for **xAI**. + + ```txt + /connect + ``` + +2. Select **xAI Grok OAuth (Headless / Remote / VPS)**. CoDev Code prints a verification URL and a short user code. + + ```txt + Open https://x.ai/device on any device and enter code: ABCD-1234 + ``` + +3. Open the URL on a device that has a browser (your laptop or phone), enter the code, and approve the consent screen. CoDev Code polls xAI's token endpoint and stores the resulting OAuth tokens once you approve. Token refresh works the same as Option A. + +#### Option C — API key + +1. Head over to the [xAI console](https://console.x.ai/), create an account, and generate an API key. + +2. Run the `/connect` command and search for **xAI**. + + ```txt + /connect + ``` + +3. Select **Manually enter API Key** and paste your xAI API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _Grok Beta_. + + ```txt + /models + ``` + +--- + +### Z.AI + +1. Head over to the [Z.AI API console](https://z.ai/manage-apikey/apikey-list), create an account, and click **Create a new API key**. + +2. Run the `/connect` command and search for **Z.AI**. + + ```txt + /connect + ``` + + If you are subscribed to the **GLM Coding Plan**, select **Z.AI Coding Plan**. + +3. Enter your Z.AI API key. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Run the `/models` command to select a model like _GLM-4.7_. + + ```txt + /models + ``` + +--- + +### ZenMux + +1. Head over to the [ZenMux dashboard](https://zenmux.ai/settings/keys), click **Create API Key**, and copy the key. + +2. Run the `/connect` command and search for ZenMux. + + ```txt + /connect + ``` + +3. Enter the API key for the provider. + + ```txt + ┌ API key + │ + │ + └ enter + ``` + +4. Many ZenMux models are preloaded by default, run the `/models` command to select the one you want. + + ```txt + /models + ``` + + You can also add additional models through your CoDev Code config. + + ```json title="codev.json" {6} + { + "$schema": "https://opencode.ai/config.json", + "provider": { + "zenmux": { + "models": { + "somecoolnewmodel": {} + } + } + } + } + ``` + +--- + +## Custom provider + +To add any **OpenAI-compatible** provider that's not listed in the `/connect` command: + +:::tip +You can use any OpenAI-compatible provider with CoDev Code. Most modern AI providers offer OpenAI-compatible APIs. +::: + +1. Run the `/connect` command and scroll down to **Other**. + + ```bash + $ /connect + + ┌ Add credential + │ + ◆ Select provider + │ ... + │ ● Other + └ + ``` + +2. Enter a unique ID for the provider. + + ```bash + $ /connect + + ┌ Add credential + │ + ◇ Enter provider id + │ myprovider + └ + ``` + + :::note + Choose a memorable ID, you'll use this in your config file. + ::: + +3. Enter your API key for the provider. + + ```bash + $ /connect + + ┌ Add credential + │ + ▲ This only stores a credential for myprovider - you will need to configure it in codev.json, check the docs for examples. + │ + ◇ Enter your API key + │ sk-... + └ + ``` + +4. Create or update your `codev.json` file in your project directory: + + ```json title="codev.json" ""myprovider"" {5-15} + { + "$schema": "https://opencode.ai/config.json", + "provider": { + "myprovider": { + "npm": "@ai-sdk/openai-compatible", + "name": "My AI ProviderDisplay Name", + "options": { + "baseURL": "https://api.myprovider.com/v1" + }, + "models": { + "my-model-name": { + "name": "My Model Display Name" + } + } + } + } + } + ``` + + Here are the configuration options: + - **npm**: AI SDK package to use, `@ai-sdk/openai-compatible` for OpenAI-compatible providers (for `/v1/chat/completions`). If your provider/model uses `/v1/responses`, use `@ai-sdk/openai`. + - **name**: Display name in UI. + - **models**: Available models. + - **options.baseURL**: API endpoint URL. + - **options.apiKey**: Optionally set the API key, if not using auth. + - **options.headers**: Optionally set custom headers. + + More on the advanced options in the example below. + +5. Run the `/models` command and your custom provider and models will appear in the selection list. + +--- + +##### Example + +Here's an example setting the `apiKey`, `headers`, and model `limit` options. + +```json title="codev.json" {9,11,17-20} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "myprovider": { + "npm": "@ai-sdk/openai-compatible", + "name": "My AI ProviderDisplay Name", + "options": { + "baseURL": "https://api.myprovider.com/v1", + "apiKey": "{env:ANTHROPIC_API_KEY}", + "headers": { + "Authorization": "Bearer custom-token" + } + }, + "models": { + "my-model-name": { + "name": "My Model Display Name", + "limit": { + "context": 200000, + "output": 65536 + } + } + } + } + } +} +``` + +Configuration details: + +- **apiKey**: Set using `env` variable syntax, [learn more](/docs/config#env-vars). +- **headers**: Custom headers sent with each request. +- **limit.context**: Maximum input tokens the model accepts. +- **limit.output**: Maximum tokens the model can generate. + +The `limit` fields allow CoDev Code to understand how much context you have left. Standard providers pull these from models.dev automatically. + +--- + +## Troubleshooting + +If you are having trouble with configuring a provider, check the following: + +1. **Check the auth setup**: Run `codev auth list` to see if the credentials + for the provider are added to your config. + + This doesn't apply to providers like Amazon Bedrock, that rely on environment variables for their auth. + +2. For custom providers, check the CoDev Code config and: + - Make sure the provider ID used in the `/connect` command matches the ID in your CoDev Code config. + - The right npm package is used for the provider. For example, use `@ai-sdk/cerebras` for Cerebras. And for all other OpenAI-compatible providers, use `@ai-sdk/openai-compatible` (for `/v1/chat/completions`); if a model uses `/v1/responses`, use `@ai-sdk/openai`. For mixed setups under one provider, you can override per model via `provider.npm`. + - Check correct API endpoint is used in the `options.baseURL` field. diff --git a/packages/web/src/content/docs/references.mdx b/packages/web/src/content/docs/references.mdx new file mode 100644 index 0000000000..85927e1a4f --- /dev/null +++ b/packages/web/src/content/docs/references.mdx @@ -0,0 +1,157 @@ +--- +title: References +description: Add local directories and Git repositories as project references. +--- + +References give CoDev Code access to directories outside the current project. Use them to make documentation, shared libraries, examples, or another repository available while you work. + +References are configured by alias in `codev.json` or `codev.jsonc`. + +```jsonc title="codev.jsonc" +{ + "$schema": "https://opencode.ai/config.json", + "references": { + "docs": { + "path": "../product-docs", + "description": "Use for product behavior and documentation conventions", + }, + "sdk": { + "repository": "anomalyco/opencode-sdk-js", + "branch": "main", + "description": "Use for JavaScript SDK implementation details", + }, + }, +} +``` + +--- + +## Local directories + +Use `path` to reference a local directory. + +```jsonc title="codev.jsonc" +{ + "references": { + "docs": { + "path": "../docs", + }, + }, +} +``` + +Paths can be: + +- Relative to the config file that defines the reference +- Absolute, such as `/home/user/docs` +- Relative to your home directory, such as `~/docs` + +You can also use a string shorthand: + +```jsonc title="codev.jsonc" +{ + "references": { + "docs": "../docs", + }, +} +``` + +--- + +## Git repositories + +Use `repository` to reference a Git repository. CoDev Code materializes the repository in its local repository cache and makes the checked-out source available as a reference directory. + +```jsonc title="codev.jsonc" +{ + "references": { + "effect": { + "repository": "Effect-TS/effect", + "branch": "main", + }, + }, +} +``` + +`repository` accepts Git URLs, host/path references, and GitHub `owner/repo` shorthand. The optional `branch` field selects a branch or ref. Without `branch`, CoDev Code uses the repository's default branch. + +You can use string shorthand when you do not need a branch, description, or other options: + +```jsonc title="codev.jsonc" +{ + "references": { + "effect": "Effect-TS/effect", + }, +} +``` + +:::note +Git references are refreshed asynchronously. A newly configured repository may take a moment to finish cloning or updating. +::: + +--- + +## Describe usage + +Add `description` to explain when an agent should use a reference. + +```jsonc title="codev.jsonc" +{ + "references": { + "design-system": { + "path": "../design-system", + "description": "Use when implementing UI components or design tokens", + }, + }, +} +``` + +CoDev Code includes references with descriptions in agent context. Descriptions should be short and specific enough to distinguish references with similar content. References without descriptions remain available through autocomplete and direct use, but are not advertised to agents. + +--- + +## Hide autocomplete entries + +Set `hidden` to `true` to omit a reference from `@` autocomplete in the TUI. + +```jsonc title="codev.jsonc" +{ + "references": { + "internal": { + "path": "../internal", + "description": "Use for internal implementation details", + "hidden": true, + }, + }, +} +``` + +`hidden` only affects autocomplete. A hidden reference with a description remains included in agent context. + +--- + +## Use references + +Configured references appear in TUI `@` autocomplete. Type `@alias` to attach the reference root, or `@alias/` to search for files inside it. + +```text +Compare this implementation with @sdk/src/client.ts +``` + +Agents also receive the resolved paths and descriptions of configured references that have descriptions in their system context, so they can inspect a reference when it is relevant without you attaching it manually. + +CoDev Code automatically allows reference directories through its external-directory permission boundary. Normal tool permissions still apply; for example, an agent that cannot edit files does not gain edit access because a directory is configured as a reference. + +--- + +## Configure fields + +| Field | Local | Git | Description | +| ------------- | ----- | --- | ------------------------------------------------ | +| `path` | Yes | No | Local reference directory | +| `repository` | No | Yes | Git URL, host/path, or GitHub `owner/repo` value | +| `branch` | No | Yes | Optional Git branch or ref | +| `description` | Yes | Yes | Guidance describing when to use the reference | +| `hidden` | Yes | Yes | Hide the reference from TUI `@` autocomplete | + +Reference aliases cannot be empty or contain `/`, whitespace, backticks, or commas. diff --git a/packages/web/src/content/docs/rules.mdx b/packages/web/src/content/docs/rules.mdx new file mode 100644 index 0000000000..0f52fbc0fa --- /dev/null +++ b/packages/web/src/content/docs/rules.mdx @@ -0,0 +1,188 @@ +--- +title: Rules +description: Set custom instructions for CoDev Code. +--- + +You can provide custom instructions to CoDev Code by creating an `AGENTS.md` file. This is similar to Cursor's rules. It contains instructions that will be included in the LLM's context to customize its behavior for your specific project. + +--- + +## Initialize + +To create a new `AGENTS.md` file, you can run the `/init` command in CoDev Code. + +:::tip +You should commit your project's `AGENTS.md` file to Git. +::: + +`/init` scans the important files in your repo, may ask a couple of targeted questions when the codebase cannot answer them, and then creates or updates `AGENTS.md` with concise project-specific guidance. + +It focuses on the things future agent sessions are most likely to need: + +- build, lint, and test commands +- command order and focused verification steps when they matter +- architecture and repo structure that are not obvious from filenames alone +- project-specific conventions, setup quirks, and operational gotchas +- references to existing instruction sources like Cursor or Copilot rules + +If you already have an `AGENTS.md`, `/init` will improve it in place instead of blindly replacing it. + +--- + +## Example + +You can also just create this file manually. Here's an example of some things you can put into an `AGENTS.md` file. + +```markdown title="AGENTS.md" +# SST v3 Monorepo Project + +This is an SST v3 monorepo with TypeScript. The project uses bun workspaces for package management. + +## Project Structure + +- `packages/` - Contains all workspace packages (functions, core, web, etc.) +- `infra/` - Infrastructure definitions split by service (storage.ts, api.ts, web.ts) +- `sst.config.ts` - Main SST configuration with dynamic imports + +## Code Standards + +- Use TypeScript with strict mode enabled +- Shared code goes in `packages/core/` with proper exports configuration +- Functions go in `packages/functions/` +- Infrastructure should be split into logical files in `infra/` + +## Monorepo Conventions + +- Import shared modules using workspace names: `@my-app/core/example` +``` + +We are adding project-specific instructions here and this will be shared across your team. + +--- + +## Types + +CoDev Code also supports reading the `AGENTS.md` file from multiple locations. And this serves different purposes. + +### Project + +Place an `AGENTS.md` in your project root for project-specific rules. These only apply when you are working in this directory or its sub-directories. + +### Global + +You can also have global rules in a `~/.config/codev/AGENTS.md` file. This gets applied across all CoDev Code sessions. + +Since this isn't committed to Git or shared with your team, we recommend using this to specify any personal rules that the LLM should follow. + +### Claude Code Compatibility + +For users migrating from Claude Code, CoDev Code supports Claude Code's file conventions as fallbacks: + +- **Project rules**: `CLAUDE.md` in your project directory (used if no `AGENTS.md` exists) +- **Global rules**: `~/.claude/CLAUDE.md` (used if no `~/.config/codev/AGENTS.md` exists) +- **Skills**: `~/.claude/skills/` — see [Agent Skills](/docs/skills/) for details + +To disable Claude Code compatibility, set one of these environment variables: + +```bash +export CODEV_DISABLE_CLAUDE_CODE=1 # Disable all .claude support +export CODEV_DISABLE_CLAUDE_CODE_PROMPT=1 # Disable only ~/.claude/CLAUDE.md +export CODEV_DISABLE_CLAUDE_CODE_SKILLS=1 # Disable only .claude/skills +``` + +--- + +## Precedence + +When CoDev Code starts, it looks for rule files in this order: + +1. **Local files** by traversing up from the current directory (`AGENTS.md`, `CLAUDE.md`) +2. **Global file** at `~/.config/codev/AGENTS.md` +3. **Claude Code file** at `~/.claude/CLAUDE.md` (unless disabled) + +The first matching file wins in each category. For example, if you have both `AGENTS.md` and `CLAUDE.md`, only `AGENTS.md` is used. Similarly, `~/.config/codev/AGENTS.md` takes precedence over `~/.claude/CLAUDE.md`. + +--- + +## Custom Instructions + +You can specify custom instruction files in your `codev.json` or the global `~/.config/codev/codev.json`. This allows you and your team to reuse existing rules rather than having to duplicate them to AGENTS.md. + +Example: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "instructions": ["CONTRIBUTING.md", "docs/guidelines.md", ".cursor/rules/*.md"] +} +``` + +You can also use remote URLs to load instructions from the web. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "instructions": ["https://raw.githubusercontent.com/my-org/shared-rules/main/style.md"] +} +``` + +Remote instructions are fetched with a 5 second timeout. + +All instruction files are combined with your `AGENTS.md` files. + +--- + +## Referencing External Files + +While CoDev Code doesn't automatically parse file references in `AGENTS.md`, you can achieve similar functionality in two ways: + +### Using codev.json + +The recommended approach is to use the `instructions` field in `codev.json`: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "instructions": ["docs/development-standards.md", "test/testing-guidelines.md", "packages/*/AGENTS.md"] +} +``` + +### Manual Instructions in AGENTS.md + +You can teach CoDev Code to read external files by providing explicit instructions in your `AGENTS.md`. Here's a practical example: + +```markdown title="AGENTS.md" +# TypeScript Project Rules + +## External File Loading + +CRITICAL: When you encounter a file reference (e.g., @rules/general.md), use your Read tool to load it on a need-to-know basis. They're relevant to the SPECIFIC task at hand. + +Instructions: + +- Do NOT preemptively load all references - use lazy loading based on actual need +- When loaded, treat content as mandatory instructions that override defaults +- Follow references recursively when needed + +## Development Guidelines + +For TypeScript code style and best practices: @docs/typescript-guidelines.md +For React component architecture and hooks patterns: @docs/react-patterns.md +For REST API design and error handling: @docs/api-standards.md +For testing strategies and coverage requirements: @test/testing-guidelines.md + +## General Guidelines + +Read the following file immediately as it's relevant to all workflows: @rules/general-guidelines.md. +``` + +This approach allows you to: + +- Create modular, reusable rule files +- Share rules across projects via symlinks or git submodules +- Keep AGENTS.md concise while referencing detailed guidelines +- Ensure CoDev Code loads files only when needed for the specific task + +:::tip +For monorepos or projects with shared standards, using `codev.json` with glob patterns (like `packages/*/AGENTS.md`) is more maintainable than manual instructions. +::: diff --git a/packages/web/src/content/docs/sdk.mdx b/packages/web/src/content/docs/sdk.mdx new file mode 100644 index 0000000000..7f93af106c --- /dev/null +++ b/packages/web/src/content/docs/sdk.mdx @@ -0,0 +1,463 @@ +--- +title: SDK +description: Type-safe JS client for CoDev Code server. +--- + +import config from "../../../config.mjs" +export const typesUrl = `${config.github}/blob/dev/packages/sdk/js/src/gen/types.gen.ts` + +The CoDev Code JS/TS SDK provides a type-safe client for interacting with the server. +Use it to build integrations and control CoDev Code programmatically. + +[Learn more](/docs/server) about how the server works. For examples, check out the [projects](/docs/ecosystem#projects) built by the community. + +--- + +## Install + +Install the SDK from npm: + +```bash +npm install @opencode-ai/sdk +``` + +--- + +## Create client + +Create an instance of CoDev Code: + +```javascript +import { createOpencode } from "@opencode-ai/sdk" + +const { client } = await createOpencode() +``` + +This starts both a server and a client + +#### Options + +| Option | Type | Description | Default | +| ---------- | ------------- | ------------------------------ | ----------- | +| `hostname` | `string` | Server hostname | `127.0.0.1` | +| `port` | `number` | Server port | `4096` | +| `signal` | `AbortSignal` | Abort signal for cancellation | `undefined` | +| `timeout` | `number` | Timeout in ms for server start | `5000` | +| `config` | `Config` | Configuration object | `{}` | + +--- + +## Config + +You can pass a configuration object to customize behavior. The instance still picks up your `codev.json`, but you can override or add configuration inline: + +```javascript +import { createOpencode } from "@opencode-ai/sdk" + +const opencode = await createOpencode({ + hostname: "127.0.0.1", + port: 4096, + config: { + model: "anthropic/claude-3-5-sonnet-20241022", + }, +}) + +console.log(`Server running at ${opencode.server.url}`) + +opencode.server.close() +``` + +## Client only + +If you already have a running instance of CoDev Code, you can create a client instance to connect to it: + +```javascript +import { createOpencodeClient } from "@opencode-ai/sdk" + +const client = createOpencodeClient({ + baseUrl: "http://localhost:4096", +}) +``` + +#### Options + +| Option | Type | Description | Default | +| --------------- | ---------- | -------------------------------- | ----------------------- | +| `baseUrl` | `string` | URL of the server | `http://localhost:4096` | +| `fetch` | `function` | Custom fetch implementation | `globalThis.fetch` | +| `parseAs` | `string` | Response parsing method | `auto` | +| `responseStyle` | `string` | Return style: `data` or `fields` | `fields` | +| `throwOnError` | `boolean` | Throw errors instead of return | `false` | + +--- + +## Types + +The SDK includes TypeScript definitions for all API types. Import them directly: + +```typescript +import type { Session, Message, Part } from "@opencode-ai/sdk" +``` + +All types are generated from the server's OpenAPI specification and available in the types file. + +--- + +## Errors + +The SDK can throw errors that you can catch and handle: + +```typescript +try { + await client.session.get({ path: { id: "invalid-id" } }) +} catch (error) { + console.error("Failed to get session:", (error as Error).message) +} +``` + +--- + +## Structured Output + +You can request structured JSON output from the model by specifying an `format` with a JSON schema. The model will use a `StructuredOutput` tool to return validated JSON matching your schema. + +### Basic Usage + +```typescript +const result = await client.session.prompt({ + path: { id: sessionId }, + body: { + parts: [{ type: "text", text: "Research Anthropic and provide company info" }], + format: { + type: "json_schema", + schema: { + type: "object", + properties: { + company: { type: "string", description: "Company name" }, + founded: { type: "number", description: "Year founded" }, + products: { + type: "array", + items: { type: "string" }, + description: "Main products", + }, + }, + required: ["company", "founded"], + }, + }, + }, +}) + +// Access the structured output +console.log(result.data.info.structured_output) +// { company: "Anthropic", founded: 2021, products: ["Claude", "Claude API"] } +``` + +### Output Format Types + +| Type | Description | +| ------------- | ------------------------------------------------------ | +| `text` | Default. Standard text response (no structured output) | +| `json_schema` | Returns validated JSON matching the provided schema | + +### JSON Schema Format + +When using `type: 'json_schema'`, provide: + +| Field | Type | Description | +| ------------ | --------------- | ---------------------------------------------------------- | +| `type` | `'json_schema'` | Required. Specifies JSON schema mode | +| `schema` | `object` | Required. JSON Schema object defining the output structure | +| `retryCount` | `number` | Optional. Number of validation retries (default: 2) | + +### Error Handling + +If the model fails to produce valid structured output after all retries, the response will include a `StructuredOutputError`: + +```typescript +if (result.data.info.error?.name === "StructuredOutputError") { + console.error("Failed to produce structured output:", result.data.info.error.message) + console.error("Attempts:", result.data.info.error.retries) +} +``` + +### Best Practices + +1. **Provide clear descriptions** in your schema properties to help the model understand what data to extract +2. **Use `required`** to specify which fields must be present +3. **Keep schemas focused** - complex nested schemas may be harder for the model to fill correctly +4. **Set appropriate `retryCount`** - increase for complex schemas, decrease for simple ones + +--- + +## APIs + +The SDK exposes all server APIs through a type-safe client. + +--- + +### Global + +| Method | Description | Response | +| ----------------- | ------------------------------- | ------------------------------------ | +| `global.health()` | Check server health and version | `{ healthy: true, version: string }` | + +--- + +#### Examples + +```javascript +const health = await client.global.health() +console.log(health.data.version) +``` + +--- + +### App + +| Method | Description | Response | +| -------------- | ------------------------- | ------------------------------------------- | +| `app.log()` | Write a log entry | `boolean` | +| `app.agents()` | List all available agents | Agent[] | + +--- + +#### Examples + +```javascript +// Write a log entry +await client.app.log({ + body: { + service: "my-app", + level: "info", + message: "Operation completed", + }, +}) + +// List available agents +const agents = await client.app.agents() +``` + +--- + +### Project + +| Method | Description | Response | +| ------------------- | ------------------- | --------------------------------------------- | +| `project.list()` | List all projects | Project[] | +| `project.current()` | Get current project | Project | + +--- + +#### Examples + +```javascript +// List all projects +const projects = await client.project.list() + +// Get current project +const currentProject = await client.project.current() +``` + +--- + +### Path + +| Method | Description | Response | +| ------------ | ---------------- | ---------------------------------------- | +| `path.get()` | Get current path | Path | + +--- + +#### Examples + +```javascript +// Get current path information +const pathInfo = await client.path.get() +``` + +--- + +### Config + +| Method | Description | Response | +| -------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `config.get()` | Get config info | Config | +| `config.providers()` | List providers and default models | `{ providers: `Provider[]`, default: { [key: string]: string } }` | + +--- + +#### Examples + +```javascript +const config = await client.config.get() + +const { providers, default: defaults } = await client.config.providers() +``` + +--- + +### Sessions + +| Method | Description | Notes | +| ---------------------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `session.list()` | List sessions | Returns Session[] | +| `session.get({ path })` | Get session | Returns Session | +| `session.children({ path })` | List child sessions | Returns Session[] | +| `session.create({ body })` | Create session | Returns Session | +| `session.delete({ path })` | Delete session | Returns `boolean` | +| `session.update({ path, body })` | Update session properties | Returns Session | +| `session.init({ path, body })` | Analyze app and create `AGENTS.md` | Returns `boolean` | +| `session.abort({ path })` | Abort a running session | Returns `boolean` | +| `session.share({ path })` | Share session | Returns Session | +| `session.unshare({ path })` | Unshare session | Returns Session | +| `session.summarize({ path, body })` | Summarize session | Returns `boolean` | +| `session.messages({ path })` | List messages in a session | Returns `{ info: `Message`, parts: `Part[]`}[]` | +| `session.message({ path })` | Get message details | Returns `{ info: `Message`, parts: `Part[]`}` | +| `session.prompt({ path, body })` | Send prompt message | `body.noReply: true` returns UserMessage (context only). Default returns AssistantMessage with AI response. Supports `body.outputFormat` for [structured output](#structured-output) | +| `session.command({ path, body })` | Send command to session | Returns `{ info: `AssistantMessage`, parts: `Part[]`}` | +| `session.shell({ path, body })` | Run a shell command | Returns AssistantMessage | +| `session.revert({ path, body })` | Revert a message | Returns Session | +| `session.unrevert({ path })` | Restore reverted messages | Returns Session | +| `postSessionByIdPermissionsByPermissionId({ path, body })` | Respond to a permission request | Returns `boolean` | + +--- + +#### Examples + +```javascript +// Create and manage sessions +const session = await client.session.create({ + body: { title: "My session" }, +}) + +const sessions = await client.session.list() + +// Send a prompt message +const result = await client.session.prompt({ + path: { id: session.id }, + body: { + model: { providerID: "anthropic", modelID: "claude-3-5-sonnet-20241022" }, + parts: [{ type: "text", text: "Hello!" }], + }, +}) + +// Inject context without triggering AI response (useful for plugins) +await client.session.prompt({ + path: { id: session.id }, + body: { + noReply: true, + parts: [{ type: "text", text: "You are a helpful assistant." }], + }, +}) +``` + +--- + +### Files + +| Method | Description | Response | +| ------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------- | +| `find.text({ query })` | Search for text in files | Array of match objects with `path`, `lines`, `line_number`, `absolute_offset`, `submatches` | +| `find.files({ query })` | Find files and directories by name | `string[]` (paths) | +| `find.symbols({ query })` | Find workspace symbols | Symbol[] | +| `file.read({ query })` | Read a file | `{ type: "raw" \| "patch", content: string }` | +| `file.status({ query? })` | Get status for tracked files | File[] | + +`find.files` supports a few optional query fields: + +- `type`: `"file"` or `"directory"` +- `directory`: override the project root for the search +- `limit`: max results (1–200) + +--- + +#### Examples + +```javascript +// Search and read files +const textResults = await client.find.text({ + query: { pattern: "function.*opencode" }, +}) + +const files = await client.find.files({ + query: { query: "*.ts", type: "file" }, +}) + +const directories = await client.find.files({ + query: { query: "packages", type: "directory", limit: 20 }, +}) + +const content = await client.file.read({ + query: { path: "src/index.ts" }, +}) +``` + +--- + +### TUI + +| Method | Description | Response | +| ------------------------------ | ------------------------- | --------- | +| `tui.appendPrompt({ body })` | Append text to the prompt | `boolean` | +| `tui.openHelp()` | Open the help dialog | `boolean` | +| `tui.openSessions()` | Open the session selector | `boolean` | +| `tui.openThemes()` | Open the theme selector | `boolean` | +| `tui.openModels()` | Open the model selector | `boolean` | +| `tui.submitPrompt()` | Submit the current prompt | `boolean` | +| `tui.clearPrompt()` | Clear the prompt | `boolean` | +| `tui.executeCommand({ body })` | Execute a command | `boolean` | +| `tui.showToast({ body })` | Show toast notification | `boolean` | + +--- + +#### Examples + +```javascript +// Control TUI interface +await client.tui.appendPrompt({ + body: { text: "Add this to prompt" }, +}) + +await client.tui.showToast({ + body: { message: "Task completed", variant: "success" }, +}) +``` + +--- + +### Auth + +| Method | Description | Response | +| ------------------- | ------------------------------ | --------- | +| `auth.set({ ... })` | Set authentication credentials | `boolean` | + +--- + +#### Examples + +```javascript +await client.auth.set({ + path: { id: "anthropic" }, + body: { type: "api", key: "your-api-key" }, +}) +``` + +--- + +### Events + +| Method | Description | Response | +| ------------------- | ------------------------- | ------------------------- | +| `event.subscribe()` | Server-sent events stream | Server-sent events stream | + +--- + +#### Examples + +```javascript +// Listen to real-time events +const events = await client.event.subscribe() +for await (const event of events.stream) { + console.log("Event:", event.type, event.properties) +} +``` diff --git a/packages/web/src/content/docs/server.mdx b/packages/web/src/content/docs/server.mdx new file mode 100644 index 0000000000..b7cd4abe75 --- /dev/null +++ b/packages/web/src/content/docs/server.mdx @@ -0,0 +1,287 @@ +--- +title: Server +description: Interact with CoDev Code server over HTTP. +--- + +import config from "../../../config.mjs" +export const typesUrl = `${config.github}/blob/dev/packages/sdk/js/src/gen/types.gen.ts` + +The `codev serve` command runs a headless HTTP server that exposes an OpenAPI endpoint that a CoDev Code client can use. + +--- + +### Usage + +```bash +codev serve [--port ] [--hostname ] [--cors ] +``` + +#### Options + +| Flag | Description | Default | +| --------------- | ----------------------------------- | ---------------- | +| `--port` | Port to listen on | `4096` | +| `--hostname` | Hostname to listen on | `127.0.0.1` | +| `--mdns` | Enable mDNS discovery | `false` | +| `--mdns-domain` | Custom domain name for mDNS service | `opencode.local` | +| `--cors` | Additional browser origins to allow | `[]` | + +`--cors` can be passed multiple times: + +```bash +codev serve --cors http://localhost:5173 --cors https://app.example.com +``` + +--- + +### Authentication + +Set `CODEV_SERVER_PASSWORD` to protect the server with HTTP basic auth. The username defaults to `opencode`, or set `CODEV_SERVER_USERNAME` to override it. This applies to both `codev serve` and `codev web`. + +```bash +CODEV_SERVER_PASSWORD=your-password codev serve +``` + +--- + +### How it works + +When you run `codev` it starts a TUI and a server. Where the TUI is the +client that talks to the server. The server exposes an OpenAPI 3.1 spec +endpoint. This endpoint is also used to generate an [SDK](/docs/sdk). + +:::tip +Use the CoDev Code server to interact with CoDev Code programmatically. +::: + +This architecture lets CoDev Code support multiple clients and allows you to interact with CoDev Code programmatically. + +You can run `codev serve` to start a standalone server. If you have the +CoDev Code TUI running, `codev serve` will start a new server. + +--- + +#### Connect to an existing server + +When you start the TUI it randomly assigns a port and hostname. You can instead pass in the `--hostname` and `--port` [flags](/docs/cli). Then use this to connect to its server. + +The [`/tui`](#tui) endpoint can be used to drive the TUI through the server. For example, you can prefill or run a prompt. This setup is used by the CoDev Code [IDE](/docs/ide) plugins. + +--- + +## Spec + +The server publishes an OpenAPI 3.1 spec that can be viewed at: + +``` +http://:/doc +``` + +For example, `http://localhost:4096/doc`. Use the spec to generate clients or inspect request and response types. Or view it in a Swagger explorer. + +--- + +## APIs + +The CoDev Code server exposes the following APIs. + +--- + +### Global + +| Method | Path | Description | Response | +| ------ | ---------------- | ------------------------------ | ------------------------------------ | +| `GET` | `/global/health` | Get server health and version | `{ healthy: true, version: string }` | +| `GET` | `/global/event` | Get global events (SSE stream) | Event stream | + +--- + +### Project + +| Method | Path | Description | Response | +| ------ | ------------------ | ----------------------- | --------------------------------------------- | +| `GET` | `/project` | List all projects | Project[] | +| `GET` | `/project/current` | Get the current project | Project | + +--- + +### Path & VCS + +| Method | Path | Description | Response | +| ------ | ------- | ------------------------------------ | ------------------------------------------- | +| `GET` | `/path` | Get the current path | Path | +| `GET` | `/vcs` | Get VCS info for the current project | VcsInfo | + +--- + +### Instance + +| Method | Path | Description | Response | +| ------ | ------------------- | ---------------------------- | --------- | +| `POST` | `/instance/dispose` | Dispose the current instance | `boolean` | + +--- + +### Config + +| Method | Path | Description | Response | +| ------- | ------------------- | --------------------------------- | ---------------------------------------------------------------------------------------- | +| `GET` | `/config` | Get config info | Config | +| `PATCH` | `/config` | Update config | Config | +| `GET` | `/config/providers` | List providers and default models | `{ providers: `Provider[]`, default: { [key: string]: string } }` | + +--- + +### Provider + +| Method | Path | Description | Response | +| ------ | -------------------------------- | ------------------------------------ | ----------------------------------------------------------------------------------- | +| `GET` | `/provider` | List all providers | `{ all: `Provider[]`, default: {...}, connected: string[] }` | +| `GET` | `/provider/auth` | Get provider authentication methods | `{ [providerID: string]: `ProviderAuthMethod[]` }` | +| `POST` | `/provider/{id}/oauth/authorize` | Authorize a provider using OAuth | ProviderAuthAuthorization | +| `POST` | `/provider/{id}/oauth/callback` | Handle OAuth callback for a provider | `boolean` | + +--- + +### Sessions + +| Method | Path | Description | Notes | +| -------- | ---------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------- | +| `GET` | `/session` | List all sessions | Returns Session[] | +| `POST` | `/session` | Create a new session | body: `{ parentID?, title? }`, returns Session | +| `GET` | `/session/status` | Get session status for all sessions | Returns `{ [sessionID: string]: `SessionStatus` }` | +| `GET` | `/session/:id` | Get session details | Returns Session | +| `DELETE` | `/session/:id` | Delete a session and all its data | Returns `boolean` | +| `PATCH` | `/session/:id` | Update session properties | body: `{ title? }`, returns Session | +| `GET` | `/session/:id/children` | Get a session's child sessions | Returns Session[] | +| `GET` | `/session/:id/todo` | Get the todo list for a session | Returns Todo[] | +| `POST` | `/session/:id/init` | Analyze app and create `AGENTS.md` | body: `{ messageID, providerID, modelID }`, returns `boolean` | +| `POST` | `/session/:id/fork` | Fork an existing session at a message | body: `{ messageID? }`, returns Session | +| `POST` | `/session/:id/abort` | Abort a running session | Returns `boolean` | +| `POST` | `/session/:id/share` | Share a session | Returns Session | +| `DELETE` | `/session/:id/share` | Unshare a session | Returns Session | +| `GET` | `/session/:id/diff` | Get the diff for this session | query: `messageID?`, returns FileDiff[] | +| `POST` | `/session/:id/summarize` | Summarize the session | body: `{ providerID, modelID }`, returns `boolean` | +| `POST` | `/session/:id/revert` | Revert a message | body: `{ messageID, partID? }`, returns `boolean` | +| `POST` | `/session/:id/unrevert` | Restore all reverted messages | Returns `boolean` | +| `POST` | `/session/:id/permissions/:permissionID` | Respond to a permission request | body: `{ response, remember? }`, returns `boolean` | + +--- + +### Messages + +| Method | Path | Description | Notes | +| ------ | --------------------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `GET` | `/session/:id/message` | List messages in a session | query: `limit?`, returns `{ info: `Message`, parts: `Part[]`}[]` | +| `POST` | `/session/:id/message` | Send a message and wait for response | body: `{ messageID?, model?, agent?, noReply?, system?, tools?, parts }`, returns `{ info: `Message`, parts: `Part[]`}` | +| `GET` | `/session/:id/message/:messageID` | Get message details | Returns `{ info: `Message`, parts: `Part[]`}` | +| `POST` | `/session/:id/prompt_async` | Send a message asynchronously (no wait) | body: same as `/session/:id/message`, returns `204 No Content` | +| `POST` | `/session/:id/command` | Execute a slash command | body: `{ messageID?, agent?, model?, command, arguments }`, returns `{ info: `Message`, parts: `Part[]`}` | +| `POST` | `/session/:id/shell` | Run a shell command | body: `{ agent, model?, command }`, returns `{ info: `Message`, parts: `Part[]`}` | + +--- + +### Commands + +| Method | Path | Description | Response | +| ------ | ---------- | ----------------- | --------------------------------------------- | +| `GET` | `/command` | List all commands | Command[] | + +--- + +### Files + +| Method | Path | Description | Response | +| ------ | ------------------------ | ---------------------------------- | ------------------------------------------------------------------------------------------- | +| `GET` | `/find?pattern=` | Search for text in files | Array of match objects with `path`, `lines`, `line_number`, `absolute_offset`, `submatches` | +| `GET` | `/find/file?query=` | Find files and directories by name | `string[]` (paths) | +| `GET` | `/find/symbol?query=` | Find workspace symbols | Symbol[] | +| `GET` | `/file?path=` | List files and directories | FileNode[] | +| `GET` | `/file/content?path=

` | Read a file | FileContent | +| `GET` | `/file/status` | Get status for tracked files | File[] | + +#### `/find/file` query parameters + +- `query` (required) — search string (fuzzy match) +- `type` (optional) — limit results to `"file"` or `"directory"` +- `directory` (optional) — override the project root for the search +- `limit` (optional) — max results (1–200) +- `dirs` (optional) — legacy flag (`"false"` returns only files) + +--- + +### Tools (Experimental) + +| Method | Path | Description | Response | +| ------ | ------------------------------------------- | ---------------------------------------- | -------------------------------------------- | +| `GET` | `/experimental/tool/ids` | List all tool IDs | ToolIDs | +| `GET` | `/experimental/tool?provider=

&model=` | List tools with JSON schemas for a model | ToolList | + +--- + +### LSP, Formatters & MCP + +| Method | Path | Description | Response | +| ------ | ------------ | -------------------------- | -------------------------------------------------------- | +| `GET` | `/lsp` | Get LSP server status | LSPStatus[] | +| `GET` | `/formatter` | Get formatter status | FormatterStatus[] | +| `GET` | `/mcp` | Get MCP server status | `{ [name: string]: `MCPStatus` }` | +| `POST` | `/mcp` | Add MCP server dynamically | body: `{ name, config }`, returns MCP status object | + +--- + +### Agents + +| Method | Path | Description | Response | +| ------ | -------- | ------------------------- | ------------------------------------------- | +| `GET` | `/agent` | List all available agents | Agent[] | + +--- + +### Logging + +| Method | Path | Description | Response | +| ------ | ------ | ------------------------------------------------------------ | --------- | +| `POST` | `/log` | Write log entry. Body: `{ service, level, message, extra? }` | `boolean` | + +--- + +### TUI + +| Method | Path | Description | Response | +| ------ | ----------------------- | ------------------------------------------- | ---------------------- | +| `POST` | `/tui/append-prompt` | Append text to the prompt | `boolean` | +| `POST` | `/tui/open-help` | Open the help dialog | `boolean` | +| `POST` | `/tui/open-sessions` | Open the session selector | `boolean` | +| `POST` | `/tui/open-themes` | Open the theme selector | `boolean` | +| `POST` | `/tui/open-models` | Open the model selector | `boolean` | +| `POST` | `/tui/submit-prompt` | Submit the current prompt | `boolean` | +| `POST` | `/tui/clear-prompt` | Clear the prompt | `boolean` | +| `POST` | `/tui/execute-command` | Execute a command (`{ command }`) | `boolean` | +| `POST` | `/tui/show-toast` | Show toast (`{ title?, message, variant }`) | `boolean` | +| `GET` | `/tui/control/next` | Wait for the next control request | Control request object | +| `POST` | `/tui/control/response` | Respond to a control request (`{ body }`) | `boolean` | + +--- + +### Auth + +| Method | Path | Description | Response | +| ------ | ----------- | --------------------------------------------------------------- | --------- | +| `PUT` | `/auth/:id` | Set authentication credentials. Body must match provider schema | `boolean` | + +--- + +### Events + +| Method | Path | Description | Response | +| ------ | -------- | ----------------------------------------------------------------------------- | ------------------------- | +| `GET` | `/event` | Server-sent events stream. First event is `server.connected`, then bus events | Server-sent events stream | + +--- + +### Docs + +| Method | Path | Description | Response | +| ------ | ------ | ------------------------- | --------------------------- | +| `GET` | `/doc` | OpenAPI 3.1 specification | HTML page with OpenAPI spec | diff --git a/packages/web/src/content/docs/share.mdx b/packages/web/src/content/docs/share.mdx new file mode 100644 index 0000000000..09ddc4377f --- /dev/null +++ b/packages/web/src/content/docs/share.mdx @@ -0,0 +1,128 @@ +--- +title: Share +description: Share your CoDev Code conversations. +--- + +CoDev Code's share feature allows you to create public links to your CoDev Code conversations, so you can collaborate with teammates or get help from others. + +:::note +Shared conversations are publicly accessible to anyone with the link. +::: + +--- + +## How it works + +When you share a conversation, CoDev Code: + +1. Creates a unique public URL for your session +2. Syncs your conversation history to our servers +3. Makes the conversation accessible via the shareable link — `opncd.ai/s/` + +--- + +## Sharing + +CoDev Code supports three sharing modes that control how conversations are shared: + +--- + +### Manual (default) + +By default, CoDev Code uses manual sharing mode. Sessions are not shared automatically, but you can manually share them using the `/share` command: + +``` +/share +``` + +This will generate a unique URL that'll be copied to your clipboard. + +To explicitly set manual mode in your [config file](/docs/config): + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "share": "manual" +} +``` + +--- + +### Auto-share + +You can enable automatic sharing for all new conversations by setting the `share` option to `"auto"` in your [config file](/docs/config): + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "share": "auto" +} +``` + +With auto-share enabled, every new conversation will automatically be shared and a link will be generated. + +--- + +### Disabled + +You can disable sharing entirely by setting the `share` option to `"disabled"` in your [config file](/docs/config): + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "share": "disabled" +} +``` + +To enforce this across your team for a given project, add it to the `codev.json` in your project and check into Git. + +--- + +## Un-sharing + +To stop sharing a conversation and remove it from public access: + +``` +/unshare +``` + +This will remove the share link and delete the data related to the conversation. + +--- + +## Privacy + +There are a few things to keep in mind when sharing a conversation. + +--- + +### Data retention + +Shared conversations remain accessible until you explicitly unshare them. This +includes: + +- Full conversation history +- All messages and responses +- Session metadata + +--- + +### Recommendations + +- Only share conversations that don't contain sensitive information. +- Review conversation content before sharing. +- Unshare conversations when collaboration is complete. +- Avoid sharing conversations with proprietary code or confidential data. +- For sensitive projects, disable sharing entirely. + +--- + +## For enterprises + +For enterprise deployments, the share feature can be: + +- **Disabled** entirely for security compliance +- **Restricted** to users authenticated through SSO only +- **Self-hosted** on your own infrastructure + +[Learn more](/docs/enterprise) about using CoDev Code in your organization. diff --git a/packages/web/src/content/docs/skills.mdx b/packages/web/src/content/docs/skills.mdx new file mode 100644 index 0000000000..701ef0892c --- /dev/null +++ b/packages/web/src/content/docs/skills.mdx @@ -0,0 +1,222 @@ +--- +title: "Agent Skills" +description: "Define reusable behavior via SKILL.md definitions" +--- + +Agent skills let CoDev Code discover reusable instructions from your repo or home directory. +Skills are loaded on-demand via the native `skill` tool—agents see available skills and can load the full content when needed. + +--- + +## Place files + +Create one folder per skill name and put a `SKILL.md` inside it. +CoDev Code searches these locations: + +- Project config: `.codev/skills//SKILL.md` +- Global config: `~/.config/codev/skills//SKILL.md` +- Project Claude-compatible: `.claude/skills//SKILL.md` +- Global Claude-compatible: `~/.claude/skills//SKILL.md` +- Project agent-compatible: `.agents/skills//SKILL.md` +- Global agent-compatible: `~/.agents/skills//SKILL.md` + +--- + +## Understand discovery + +For project-local paths, CoDev Code walks up from your current working directory until it reaches the git worktree. +It loads any matching `skills/*/SKILL.md` in `.codev/` and any matching `.claude/skills/*/SKILL.md` or `.agents/skills/*/SKILL.md` along the way. + +Global definitions are also loaded from `~/.config/codev/skills/*/SKILL.md`, `~/.claude/skills/*/SKILL.md`, and `~/.agents/skills/*/SKILL.md`. + +--- + +## Write frontmatter + +Each `SKILL.md` must start with YAML frontmatter. +Only these fields are recognized: + +- `name` (required) +- `description` (required) +- `license` (optional) +- `compatibility` (optional) +- `metadata` (optional, string-to-string map) + +Unknown frontmatter fields are ignored. + +--- + +## Validate names + +`name` must: + +- Be 1–64 characters +- Be lowercase alphanumeric with single hyphen separators +- Not start or end with `-` +- Not contain consecutive `--` +- Match the directory name that contains `SKILL.md` + +Equivalent regex: + +```text +^[a-z0-9]+(-[a-z0-9]+)*$ +``` + +--- + +## Follow length rules + +`description` must be 1-1024 characters. +Keep it specific enough for the agent to choose correctly. + +--- + +## Use an example + +Create `.codev/skills/git-release/SKILL.md` like this: + +```markdown +--- +name: git-release +description: Create consistent releases and changelogs +license: MIT +compatibility: opencode +metadata: + audience: maintainers + workflow: github +--- + +## What I do + +- Draft release notes from merged PRs +- Propose a version bump +- Provide a copy-pasteable `gh release create` command + +## When to use me + +Use this when you are preparing a tagged release. +Ask clarifying questions if the target versioning scheme is unclear. +``` + +--- + +## Recognize tool description + +CoDev Code lists available skills in the `skill` tool description. +Each entry includes the skill name and description: + +```xml + + + git-release + Create consistent releases and changelogs + + +``` + +The agent loads a skill by calling the tool: + +``` +skill({ name: "git-release" }) +``` + +--- + +## Configure permissions + +Control which skills agents can access using pattern-based permissions in `codev.json`: + +```json +{ + "permission": { + "skill": { + "*": "allow", + "pr-review": "allow", + "internal-*": "deny", + "experimental-*": "ask" + } + } +} +``` + +| Permission | Behavior | +| ---------- | ----------------------------------------- | +| `allow` | Skill loads immediately | +| `deny` | Skill hidden from agent, access rejected | +| `ask` | User prompted for approval before loading | + +Patterns support wildcards: `internal-*` matches `internal-docs`, `internal-tools`, etc. + +--- + +## Override per agent + +Give specific agents different permissions than the global defaults. + +**For custom agents** (in agent frontmatter): + +```yaml +--- +permission: + skill: + "documents-*": "allow" +--- +``` + +**For built-in agents** (in `codev.json`): + +```json +{ + "agent": { + "plan": { + "permission": { + "skill": { + "internal-*": "allow" + } + } + } + } +} +``` + +--- + +## Disable the skill tool + +Completely disable skills for agents that shouldn't use them: + +**For custom agents**: + +```yaml +--- +tools: + skill: false +--- +``` + +**For built-in agents**: + +```json +{ + "agent": { + "plan": { + "tools": { + "skill": false + } + } + } +} +``` + +When disabled, the `` section is omitted entirely. + +--- + +## Troubleshoot loading + +If a skill does not show up: + +1. Verify `SKILL.md` is spelled in all caps +2. Check that frontmatter includes `name` and `description` +3. Ensure skill names are unique across all locations +4. Check permissions—skills with `deny` are hidden from agents diff --git a/packages/web/src/content/docs/themes.mdx b/packages/web/src/content/docs/themes.mdx new file mode 100644 index 0000000000..8db72b59fb --- /dev/null +++ b/packages/web/src/content/docs/themes.mdx @@ -0,0 +1,369 @@ +--- +title: Themes +description: Select a built-in theme or define your own. +--- + +With CoDev Code you can select from one of several built-in themes, use a theme that adapts to your terminal theme, or define your own custom theme. + +By default, CoDev Code uses our own `opencode` theme. + +--- + +## Terminal requirements + +For themes to display correctly with their full color palette, your terminal must support **truecolor** (24-bit color). Most modern terminals support this by default, but you may need to enable it: + +- **Check support**: Run `echo $COLORTERM` - it should output `truecolor` or `24bit` +- **Enable truecolor**: Set the environment variable `COLORTERM=truecolor` in your shell profile +- **Terminal compatibility**: Ensure your terminal emulator supports 24-bit color (most modern terminals like iTerm2, Alacritty, Kitty, Windows Terminal, and recent versions of GNOME Terminal do) + +Without truecolor support, themes may appear with reduced color accuracy or fall back to the nearest 256-color approximation. + +--- + +## Built-in themes + +CoDev Code comes with several built-in themes. + +| Name | Description | +| ---------------------- | ---------------------------------------------------------------------------- | +| `system` | Adapts to your terminal’s background color | +| `tokyonight` | Based on the [Tokyonight](https://github.com/folke/tokyonight.nvim) theme | +| `everforest` | Based on the [Everforest](https://github.com/sainnhe/everforest) theme | +| `ayu` | Based on the [Ayu](https://github.com/ayu-theme) dark theme | +| `catppuccin` | Based on the [Catppuccin](https://github.com/catppuccin) theme | +| `catppuccin-macchiato` | Based on the [Catppuccin](https://github.com/catppuccin) theme | +| `gruvbox` | Based on the [Gruvbox](https://github.com/morhetz/gruvbox) theme | +| `kanagawa` | Based on the [Kanagawa](https://github.com/rebelot/kanagawa.nvim) theme | +| `nord` | Based on the [Nord](https://github.com/nordtheme/nord) theme | +| `matrix` | Hacker-style green on black theme | +| `one-dark` | Based on the [Atom One](https://github.com/Th3Whit3Wolf/one-nvim) Dark theme | + +And more, we are constantly adding new themes. + +--- + +## System theme + +The `system` theme is designed to automatically adapt to your terminal's color scheme. Unlike traditional themes that use fixed colors, the _system_ theme: + +- **Generates gray scale**: Creates a custom gray scale based on your terminal's background color, ensuring optimal contrast. +- **Uses ANSI colors**: Leverages standard ANSI colors (0-15) for syntax highlighting and UI elements, which respect your terminal's color palette. +- **Preserves terminal defaults**: Uses `none` for text and background colors to maintain your terminal's native appearance. + +The system theme is for users who: + +- Want CoDev Code to match their terminal's appearance +- Use custom terminal color schemes +- Prefer a consistent look across all terminal applications + +--- + +## Using a theme + +You can select a theme by bringing up the theme select with the `/theme` command. Or you can specify it in `tui.json`. + +```json title="tui.json" {3} +{ + "$schema": "https://opencode.ai/tui.json", + "theme": "tokyonight" +} +``` + +--- + +## Custom themes + +CoDev Code supports a flexible JSON-based theme system that allows users to create and customize themes easily. + +--- + +### Hierarchy + +Themes are loaded from multiple directories in the following order where later directories override earlier ones: + +1. **Built-in themes** - These are embedded in the binary +2. **User config directory** - Defined in `~/.config/codev/themes/*.json` or `$XDG_CONFIG_HOME/codev/themes/*.json` +3. **Project root directory** - Defined in the `/.codev/themes/*.json` +4. **Current working directory** - Defined in `./.codev/themes/*.json` + +If multiple directories contain a theme with the same name, the theme from the directory with higher priority will be used. + +--- + +### Creating a theme + +To create a custom theme, create a JSON file in one of the theme directories. + +For user-wide themes: + +```bash no-frame +mkdir -p ~/.config/codev/themes +vim ~/.config/codev/themes/my-theme.json +``` + +And for project-specific themes. + +```bash no-frame +mkdir -p .codev/themes +vim .codev/themes/my-theme.json +``` + +--- + +### JSON format + +Themes use a flexible JSON format with support for: + +- **Hex colors**: `"#ffffff"` +- **ANSI colors**: `3` (0-255) +- **Color references**: `"primary"` or custom definitions +- **Dark/light variants**: `{"dark": "#000", "light": "#fff"}` +- **No color**: `"none"` - Uses the terminal's default color or transparent + +--- + +### Color definitions + +The `defs` section is optional and it allows you to define reusable colors that can be referenced in the theme. + +--- + +### Terminal defaults + +The special value `"none"` can be used for any color to inherit the terminal's default color. This is particularly useful for creating themes that blend seamlessly with your terminal's color scheme: + +- `"text": "none"` - Uses terminal's default foreground color +- `"background": "none"` - Uses terminal's default background color + +--- + +### Example + +Here's an example of a custom theme: + +```json title="my-theme.json" +{ + "$schema": "https://opencode.ai/theme.json", + "defs": { + "nord0": "#2E3440", + "nord1": "#3B4252", + "nord2": "#434C5E", + "nord3": "#4C566A", + "nord4": "#D8DEE9", + "nord5": "#E5E9F0", + "nord6": "#ECEFF4", + "nord7": "#8FBCBB", + "nord8": "#88C0D0", + "nord9": "#81A1C1", + "nord10": "#5E81AC", + "nord11": "#BF616A", + "nord12": "#D08770", + "nord13": "#EBCB8B", + "nord14": "#A3BE8C", + "nord15": "#B48EAD" + }, + "theme": { + "primary": { + "dark": "nord8", + "light": "nord10" + }, + "secondary": { + "dark": "nord9", + "light": "nord9" + }, + "accent": { + "dark": "nord7", + "light": "nord7" + }, + "error": { + "dark": "nord11", + "light": "nord11" + }, + "warning": { + "dark": "nord12", + "light": "nord12" + }, + "success": { + "dark": "nord14", + "light": "nord14" + }, + "info": { + "dark": "nord8", + "light": "nord10" + }, + "text": { + "dark": "nord4", + "light": "nord0" + }, + "textMuted": { + "dark": "nord3", + "light": "nord1" + }, + "background": { + "dark": "nord0", + "light": "nord6" + }, + "backgroundPanel": { + "dark": "nord1", + "light": "nord5" + }, + "backgroundElement": { + "dark": "nord1", + "light": "nord4" + }, + "border": { + "dark": "nord2", + "light": "nord3" + }, + "borderActive": { + "dark": "nord3", + "light": "nord2" + }, + "borderSubtle": { + "dark": "nord2", + "light": "nord3" + }, + "diffAdded": { + "dark": "nord14", + "light": "nord14" + }, + "diffRemoved": { + "dark": "nord11", + "light": "nord11" + }, + "diffContext": { + "dark": "nord3", + "light": "nord3" + }, + "diffHunkHeader": { + "dark": "nord3", + "light": "nord3" + }, + "diffHighlightAdded": { + "dark": "nord14", + "light": "nord14" + }, + "diffHighlightRemoved": { + "dark": "nord11", + "light": "nord11" + }, + "diffAddedBg": { + "dark": "#3B4252", + "light": "#E5E9F0" + }, + "diffRemovedBg": { + "dark": "#3B4252", + "light": "#E5E9F0" + }, + "diffContextBg": { + "dark": "nord1", + "light": "nord5" + }, + "diffLineNumber": { + "dark": "nord2", + "light": "nord4" + }, + "diffAddedLineNumberBg": { + "dark": "#3B4252", + "light": "#E5E9F0" + }, + "diffRemovedLineNumberBg": { + "dark": "#3B4252", + "light": "#E5E9F0" + }, + "markdownText": { + "dark": "nord4", + "light": "nord0" + }, + "markdownHeading": { + "dark": "nord8", + "light": "nord10" + }, + "markdownLink": { + "dark": "nord9", + "light": "nord9" + }, + "markdownLinkText": { + "dark": "nord7", + "light": "nord7" + }, + "markdownCode": { + "dark": "nord14", + "light": "nord14" + }, + "markdownBlockQuote": { + "dark": "nord3", + "light": "nord3" + }, + "markdownEmph": { + "dark": "nord12", + "light": "nord12" + }, + "markdownStrong": { + "dark": "nord13", + "light": "nord13" + }, + "markdownHorizontalRule": { + "dark": "nord3", + "light": "nord3" + }, + "markdownListItem": { + "dark": "nord8", + "light": "nord10" + }, + "markdownListEnumeration": { + "dark": "nord7", + "light": "nord7" + }, + "markdownImage": { + "dark": "nord9", + "light": "nord9" + }, + "markdownImageText": { + "dark": "nord7", + "light": "nord7" + }, + "markdownCodeBlock": { + "dark": "nord4", + "light": "nord0" + }, + "syntaxComment": { + "dark": "nord3", + "light": "nord3" + }, + "syntaxKeyword": { + "dark": "nord9", + "light": "nord9" + }, + "syntaxFunction": { + "dark": "nord8", + "light": "nord8" + }, + "syntaxVariable": { + "dark": "nord7", + "light": "nord7" + }, + "syntaxString": { + "dark": "nord14", + "light": "nord14" + }, + "syntaxNumber": { + "dark": "nord15", + "light": "nord15" + }, + "syntaxType": { + "dark": "nord7", + "light": "nord7" + }, + "syntaxOperator": { + "dark": "nord9", + "light": "nord9" + }, + "syntaxPunctuation": { + "dark": "nord4", + "light": "nord0" + } + } +} +``` diff --git a/packages/web/src/content/docs/tools.mdx b/packages/web/src/content/docs/tools.mdx new file mode 100644 index 0000000000..fd2fc1e4f3 --- /dev/null +++ b/packages/web/src/content/docs/tools.mdx @@ -0,0 +1,345 @@ +--- +title: Tools +description: Manage the tools an LLM can use. +--- + +Tools allow the LLM to perform actions in your codebase. CoDev Code comes with a set of built-in tools, but you can extend it with [custom tools](/docs/custom-tools) or [MCP servers](/docs/mcp-servers). + +By default, all tools are **enabled** and don't need permission to run. You can control tool behavior through [permissions](/docs/permissions). + +--- + +## Configure + +Use the `permission` field to control tool behavior. You can allow, deny, or require approval for each tool. + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "edit": "deny", + "bash": "ask", + "webfetch": "allow" + } +} +``` + +You can also use wildcards to control multiple tools at once. For example, to require approval for all tools from an MCP server: + +```json title="codev.json" +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "mymcp_*": "ask" + } +} +``` + +[Learn more](/docs/permissions) about configuring permissions. + +--- + +## Built-in + +Here are all the built-in tools available in CoDev Code. + +--- + +### bash + +Execute shell commands in your project environment. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "bash": "allow" + } +} +``` + +This tool allows the LLM to run terminal commands like `npm install`, `git status`, or any other shell command. + +--- + +### edit + +Modify existing files using exact string replacements. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "edit": "allow" + } +} +``` + +This tool performs precise edits to files by replacing exact text matches. It's the primary way the LLM modifies code. + +--- + +### write + +Create new files or overwrite existing ones. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "edit": "allow" + } +} +``` + +Use this to allow the LLM to create new files. It will overwrite existing files if they already exist. + +:::note +The `write` tool is controlled by the `edit` permission, which covers all file modifications (`edit`, `write`, `apply_patch`). +::: + +--- + +### read + +Read file contents from your codebase. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "read": "allow" + } +} +``` + +This tool reads files and returns their contents. It supports reading specific line ranges for large files. + +--- + +### grep + +Search file contents using regular expressions. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "grep": "allow" + } +} +``` + +Fast content search across your codebase. Supports full regex syntax and file pattern filtering. + +--- + +### glob + +Find files by pattern matching. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "glob": "allow" + } +} +``` + +Search for files using glob patterns like `**/*.js` or `src/**/*.ts`. Returns matching file paths sorted by modification time. + +--- + +### lsp (experimental) + +Interact with your configured LSP servers to get code intelligence features like definitions, references, hover info, and call hierarchy. + +:::note +This tool is only available when `CODEV_EXPERIMENTAL_LSP_TOOL=true` (or `CODEV_EXPERIMENTAL=true`). +::: + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "lsp": "allow" + } +} +``` + +Supported operations include `goToDefinition`, `findReferences`, `hover`, `documentSymbol`, `workspaceSymbol`, `goToImplementation`, `prepareCallHierarchy`, `incomingCalls`, and `outgoingCalls`. + +To configure which LSP servers are available for your project, see [LSP Servers](/docs/lsp). + +--- + +### apply_patch + +Apply patches to files. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "edit": "allow" + } +} +``` + +This tool applies patch files to your codebase. Useful for applying diffs and patches from various sources. + +When handling `tool.execute.before` or `tool.execute.after` hooks, check `input.tool === "apply_patch"` (not `"patch"`). + +`apply_patch` uses `output.args.patchText` instead of `output.args.filePath`. Paths are embedded in marker lines within `patchText` and are relative to the project root (for example: `*** Add File: src/new-file.ts`, `*** Update File: src/existing.ts`, `*** Move to: src/renamed.ts`, `*** Delete File: src/obsolete.ts`). + +:::note +The `apply_patch` tool is controlled by the `edit` permission, which covers all file modifications (`edit`, `write`, `apply_patch`). +::: + +--- + +### skill + +Load a [skill](/docs/skills) (a `SKILL.md` file) and return its content in the conversation. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "skill": "allow" + } +} +``` + +--- + +### todowrite + +Manage todo lists during coding sessions. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "todowrite": "allow" + } +} +``` + +Creates and updates task lists to track progress during complex operations. The LLM uses this to organize multi-step tasks. + +:::note +This tool is disabled for subagents by default, but you can enable it manually. [Learn more](/docs/agents/#permissions) +::: + +--- + +### webfetch + +Fetch web content. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "webfetch": "allow" + } +} +``` + +Allows the LLM to fetch and read web pages. Useful for looking up documentation or researching online resources. + +--- + +### websearch + +Search the web for information. + +:::note +This tool is only available when using the OpenCode provider or when the `CODEV_ENABLE_EXA` environment variable is set to any truthy value (e.g., `true` or `1`). + +To enable when launching CoDev Code: + +```bash +CODEV_ENABLE_EXA=1 codev +``` + +::: + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "websearch": "allow" + } +} +``` + +Performs web searches using Exa AI to find relevant information online. Useful for researching topics, finding current events, or gathering information beyond the training data cutoff. + +No API key is required — the tool connects directly to Exa AI's hosted MCP service without authentication. + +:::tip +Use `websearch` when you need to find information (discovery), and `webfetch` when you need to retrieve content from a specific URL (retrieval). +::: + +--- + +### question + +Ask the user questions during execution. + +```json title="codev.json" {4} +{ + "$schema": "https://opencode.ai/config.json", + "permission": { + "question": "allow" + } +} +``` + +This tool allows the LLM to ask the user questions during a task. It's useful for: + +- Gathering user preferences or requirements +- Clarifying ambiguous instructions +- Getting decisions on implementation choices +- Offering choices about what direction to take + +Each question includes a header, the question text, and a list of options. Users can select from the provided options or type a custom answer. When there are multiple questions, users can navigate between them before submitting all answers. + +--- + +## Custom tools + +Custom tools let you define your own functions that the LLM can call. These are defined in your config file and can execute arbitrary code. + +[Learn more](/docs/custom-tools) about creating custom tools. + +--- + +## MCP servers + +MCP (Model Context Protocol) servers allow you to integrate external tools and services. This includes database access, API integrations, and third-party services. + +[Learn more](/docs/mcp-servers) about configuring MCP servers. + +--- + +## Internals + +Internally, tools like `grep` and `glob` use [ripgrep](https://github.com/BurntSushi/ripgrep) under the hood. By default, ripgrep respects `.gitignore` patterns, which means files and directories listed in your `.gitignore` will be excluded from searches and listings. + +--- + +### Ignore patterns + +To include files that would normally be ignored, create a `.ignore` file in your project root. This file can explicitly allow certain paths. + +```text title=".ignore" +!node_modules/ +!dist/ +!build/ +``` + +For example, this `.ignore` file allows ripgrep to search within `node_modules/`, `dist/`, and `build/` directories even if they're listed in `.gitignore`. diff --git a/packages/web/src/content/docs/troubleshooting.mdx b/packages/web/src/content/docs/troubleshooting.mdx new file mode 100644 index 0000000000..ce83f590ee --- /dev/null +++ b/packages/web/src/content/docs/troubleshooting.mdx @@ -0,0 +1,314 @@ +--- +title: Troubleshooting +description: Common issues and how to resolve them. +--- + +To debug issues with CoDev Code, start by checking the logs and local data it stores on disk. + +--- + +## Logs + +Log files are written to: + +- **macOS/Linux**: `~/.local/share/codev/log/` +- **Windows**: Press `WIN+R` and paste `%USERPROFILE%\.local\share\codev\log` + +Log files are named with timestamps (e.g., `2025-01-09T123456.log`) and the most recent 10 log files are kept. + +You can set the log level with the `--log-level` command-line option to get more detailed debug information. For example, `codev --log-level DEBUG`. + +--- + +## Storage + +CoDev Code stores session data and other application data on disk at: + +- **macOS/Linux**: `~/.local/share/codev/` +- **Windows**: Press `WIN+R` and paste `%USERPROFILE%\.local\share\codev` + +This directory contains: + +- `auth.json` - Authentication data like API keys, OAuth tokens +- `log/` - Application logs +- `project/` - Project-specific data like session and message data + - If the project is within a Git repo, it is stored in `.//storage/` + - If it is not a Git repo, it is stored in `./global/storage/` + +--- + +## Uninstall + +To uninstall the CoDev Code CLI and remove its related files, run: + +```bash +codev uninstall +``` + +The command shows what will be removed and asks for confirmation. See the [CLI reference](/docs/cli#uninstall) for options to keep your configuration or application data. + +To remove CoDev Code Desktop, uninstall the application through your operating system's app management tools. + +--- + +## Desktop app + +CoDev Code Desktop runs a local CoDev Code server (the `opencode-cli` sidecar) in the background. Most issues are caused by a misbehaving plugin, a corrupted cache, or a bad server setting. + +### Quick checks + +- Fully quit and relaunch the app. +- If the app shows an error screen, click **Restart** and copy the error details. +- macOS only: `CoDev Code` menu -> **Reload Webview** (helps if the UI is blank/frozen). + +--- + +### Disable plugins + +If the desktop app is crashing on launch, hanging, or behaving strangely, start by disabling plugins. + +#### Check the global config + +Open your global config file and look for a `plugin` key. + +- **macOS/Linux**: `~/.config/codev/codev.jsonc` (or `~/.config/codev/codev.json`) +- **macOS/Linux** (older installs): `~/.local/share/codev/codev.jsonc` +- **Windows**: Press `WIN+R` and paste `%USERPROFILE%\.config\opencode\codev.jsonc` + +If you have plugins configured, temporarily disable them by removing the key or setting it to an empty array: + +```jsonc +{ + "$schema": "https://opencode.ai/config.json", + "plugin": [], +} +``` + +#### Check plugin directories + +CoDev Code can also load local plugins from disk. Temporarily move these out of the way (or rename the folder) and restart the desktop app: + +- **Global plugins** + - **macOS/Linux**: `~/.config/codev/plugins/` + - **Windows**: Press `WIN+R` and paste `%USERPROFILE%\.config\opencode\plugins` +- **Project plugins** (only if you use per-project config) + - `/.codev/plugins/` + +If the app starts working again, re-enable plugins one at a time to find which one is causing the issue. + +--- + +### Clear the cache + +If disabling plugins doesn't help (or a plugin install is stuck), clear the cache so CoDev Code can rebuild it. + +1. Quit CoDev Code Desktop completely. +2. Delete the cache directory: + +- **macOS**: Finder -> `Cmd+Shift+G` -> paste `~/.cache/codev` +- **Linux**: delete `~/.cache/codev` (or run `rm -rf ~/.cache/codev`) +- **Windows**: Press `WIN+R` and paste `%USERPROFILE%\.cache\codev` + +3. Restart CoDev Code Desktop. + +--- + +### Fix server connection issues + +CoDev Code Desktop can either start its own local server (default) or connect to a server URL you configured. + +If you see a **"Connection Failed"** dialog (or the app never gets past the splash screen), check for a custom server URL. + +#### Clear the desktop default server URL + +From the Home screen, click the server name (with the status dot) to open the Server picker. In the **Default server** section, click **Clear**. + +#### Remove `server.port` / `server.hostname` from your config + +If your `codev.json(c)` contains a `server` section, temporarily remove it and restart the desktop app. + +#### Check environment variables + +If you have `CODEV_PORT` set in your environment, the desktop app will try to use that port for the local server. + +- Unset `CODEV_PORT` (or pick a free port) and restart. + +--- + +### Linux: Wayland / X11 issues + +On Linux, some Wayland setups can cause blank windows or compositor errors. + +- If you're on Wayland and the app is blank/crashing, try launching with `OC_ALLOW_WAYLAND=1`. +- If that makes things worse, remove it and try launching under an X11 session instead. + +--- + +### Windows: WebView2 runtime + +On Windows, CoDev Code Desktop requires the Microsoft Edge **WebView2 Runtime**. If the app opens to a blank window or won't start, install/update WebView2 and try again. + +--- + +### Windows: General performance issues + +If you're experiencing slow performance, file access issues, or terminal problems on Windows, try using [WSL (Windows Subsystem for Linux)](/docs/windows-wsl). WSL provides a Linux environment that works more seamlessly with CoDev Code's features. + +--- + +### Notifications not showing + +CoDev Code Desktop only shows system notifications when: + +- notifications are enabled for CoDev Code in your OS settings, and +- the app window is not focused. + +--- + +### Reset desktop app storage (last resort) + +If the app won't start and you can't clear settings from inside the UI, reset the desktop app's saved state. + +1. Quit CoDev Code Desktop. +2. Find and delete these files (they live in the CoDev Code Desktop app data directory): + +- `opencode.settings.dat` (desktop default server URL) +- `opencode.global.dat` and `opencode.workspace.*.dat` (UI state like recent servers/projects) + +To find the directory quickly: + +- **macOS**: Finder -> `Cmd+Shift+G` -> `~/Library/Application Support` (then search for the filenames above) +- **Linux**: search under `~/.local/share` for the filenames above +- **Windows**: Press `WIN+R` -> `%APPDATA%` (then search for the filenames above) + +--- + +## Getting help + +If you're experiencing issues with CoDev Code: + +1. **Report issues on GitHub** + + The best way to report bugs or request features is through our GitHub repository: + + [**github.com/quickbeard/codev-code/issues**](https://github.com/quickbeard/codev-code/issues) + + Before creating a new issue, search existing issues to see if your problem has already been reported. + +2. **Join our Discord** + + For real-time help and community discussion, join our Discord server: + + [**opencode.ai/discord**](https://opencode.ai/discord) + +--- + +## Common issues + +Here are some common issues and how to resolve them. + +--- + +### CoDev Code won't start + +1. Check the logs for error messages +2. Try running with `--print-logs` to see output in the terminal +3. Ensure you have the latest version with `codev upgrade` + +--- + +### Authentication issues + +1. Try re-authenticating with the `/connect` command in the TUI +2. Check that your API keys are valid +3. Ensure your network allows connections to the provider's API + +--- + +### Model not available + +1. Check that you've authenticated with the provider +2. Verify the model name in your config is correct +3. Some models may require specific access or subscriptions + +If you encounter `ProviderModelNotFoundError` you are most likely incorrectly +referencing a model somewhere. +Models should be referenced like so: `/` + +Examples: + +- `openai/gpt-4.1` +- `openrouter/google/gemini-2.5-flash` +- `opencode/kimi-k2` + +To figure out what models you have access to, run `codev models` + +--- + +### ProviderInitError + +If you encounter a ProviderInitError, you likely have an invalid or corrupted configuration. + +To resolve this: + +1. First, verify your provider is set up correctly by following the [providers guide](/docs/providers) +2. If the issue persists, try clearing your stored configuration: + + ```bash + rm -rf ~/.local/share/codev + ``` + + On Windows, press `WIN+R` and delete: `%USERPROFILE%\.local\share\codev` + +3. Re-authenticate with your provider using the `/connect` command in the TUI. + +--- + +### AI_APICallError and provider package issues + +If you encounter API call errors, this may be due to outdated provider packages. CoDev Code dynamically installs provider packages (OpenAI, Anthropic, Google, etc.) as needed and caches them locally. + +To resolve provider package issues: + +1. Clear the provider package cache: + + ```bash + rm -rf ~/.cache/codev + ``` + + On Windows, press `WIN+R` and delete: `%USERPROFILE%\.cache\codev` + +2. Restart CoDev Code to reinstall the latest provider packages + +This will force CoDev Code to download the most recent versions of provider packages, which often resolves compatibility issues with model parameters and API changes. + +--- + +### Copy/paste not working on Linux + +Linux users need to have one of the following clipboard utilities installed for copy/paste functionality to work: + +**For X11 systems:** + +```bash +apt install -y xclip +# or +apt install -y xsel +``` + +**For Wayland systems:** + +```bash +apt install -y wl-clipboard +``` + +**For headless environments:** + +```bash +apt install -y xvfb +# and run: +Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & +export DISPLAY=:99.0 +``` + +CoDev Code will detect if you're using Wayland and prefer `wl-clipboard`, otherwise it will try to find clipboard tools in order of: `xclip` and `xsel`. diff --git a/packages/web/src/content/docs/tui.mdx b/packages/web/src/content/docs/tui.mdx new file mode 100644 index 0000000000..cca3f60656 --- /dev/null +++ b/packages/web/src/content/docs/tui.mdx @@ -0,0 +1,427 @@ +--- +title: TUI +description: Using the CoDev Code terminal user interface. +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components" + +CoDev Code provides an interactive terminal interface or TUI for working on your projects with an LLM. + +Running CoDev Code starts the TUI for the current directory. + +```bash +codev +``` + +Or you can start it for a specific working directory. + +```bash +codev /path/to/project +``` + +Once you're in the TUI, you can prompt it with a message. + +```text +Give me a quick summary of the codebase. +``` + +--- + +## File references + +You can reference files in your messages using `@`. This does a fuzzy file search in the current working directory. + +:::tip +You can also use `@` to reference files in your messages. +::: + +```text "@packages/functions/src/api/index.ts" +How is auth handled in @packages/functions/src/api/index.ts? +``` + +The content of the file is added to the conversation automatically. + +Configured [references](/docs/references) also appear in `@` autocomplete. Type `@alias` to add the reference root as context, or type `@alias/` to autocomplete files inside that reference. + +```text "@docs/README.md" +Compare our setup with @docs/README.md +``` + +--- + +## Bash commands + +Start a message with `!` to run a shell command. + +```bash frame="none" +!ls -la +``` + +The output of the command is added to the conversation as a tool result. + +--- + +## Commands + +When using the CoDev Code TUI, you can type `/` followed by a command name to quickly execute actions. For example: + +```bash frame="none" +/help +``` + +Most commands also have keyboard shortcuts using `ctrl+x` as the default leader key. [Learn more](/docs/keybinds). + +Here are all available slash commands: + +--- + +### connect + +Add a provider to CoDev Code. Allows you to select from available providers and add their API keys. + +```bash frame="none" +/connect +``` + +--- + +### compact + +Compact the current session. _Alias_: `/summarize` + +```bash frame="none" +/compact +``` + +**Keybind:** `ctrl+x c` + +--- + +### details + +Toggle tool execution details. + +```bash frame="none" +/details +``` + +--- + +### editor + +Open external editor for composing messages. Uses the editor set in your `EDITOR` environment variable. [Learn more](#editor-setup). + +```bash frame="none" +/editor +``` + +**Keybind:** `ctrl+x e` + +--- + +### exit + +Exit CoDev Code. _Aliases_: `/quit`, `/q` + +```bash frame="none" +/exit +``` + +**Keybind:** `ctrl+x q` + +--- + +### export + +Export current conversation to Markdown and open in your default editor. Uses the editor set in your `EDITOR` environment variable. [Learn more](#editor-setup). + +```bash frame="none" +/export +``` + +**Keybind:** `ctrl+x x` + +--- + +### help + +Show the help dialog. + +```bash frame="none" +/help +``` + +--- + +### init + +Guided setup for creating or updating `AGENTS.md`. [Learn more](/docs/rules). + +```bash frame="none" +/init +``` + +--- + +### models + +List available models. + +```bash frame="none" +/models +``` + +**Keybind:** `ctrl+x m` + +--- + +### new + +Start a new session. _Alias_: `/clear` + +```bash frame="none" +/new +``` + +**Keybind:** `ctrl+x n` + +--- + +### redo + +Redo a previously undone message. Only available after using `/undo`. + +:::tip +Any file changes will also be restored. +::: + +Internally, this uses Git to manage the file changes. So your project **needs to +be a Git repository**. + +```bash frame="none" +/redo +``` + +**Keybind:** `ctrl+x r` + +--- + +### sessions + +List and switch between sessions. _Aliases_: `/resume`, `/continue` + +```bash frame="none" +/sessions +``` + +**Keybind:** `ctrl+x l` + +--- + +### share + +Share current session. [Learn more](/docs/share). + +```bash frame="none" +/share +``` + +--- + +### themes + +List available themes. + +```bash frame="none" +/themes +``` + +**Keybind:** `ctrl+x t` + +--- + +### thinking + +Toggle the visibility of thinking/reasoning blocks in the conversation. When enabled, you can see the model's reasoning process for models that support extended thinking. + +:::note +This command only controls whether thinking blocks are **displayed** - it does not enable or disable the model's reasoning capabilities. To toggle actual reasoning capabilities, use `ctrl+t` to cycle through model variants. +::: + +```bash frame="none" +/thinking +``` + +--- + +### undo + +Undo last message in the conversation. Removes the most recent user message, all subsequent responses, and any file changes. + +:::tip +Any file changes made will also be reverted. +::: + +Internally, this uses Git to manage the file changes. So your project **needs to +be a Git repository**. + +```bash frame="none" +/undo +``` + +**Keybind:** `ctrl+x u` + +--- + +### unshare + +Unshare current session. [Learn more](/docs/share#un-sharing). + +```bash frame="none" +/unshare +``` + +--- + +## Editor setup + +Both the `/editor` and `/export` commands use the editor specified in your `EDITOR` environment variable. + + + + ```bash + # Example for nano or vim + export EDITOR=nano + export EDITOR=vim + + # For GUI editors, VS Code, Cursor, VSCodium, Windsurf, Zed, etc. + # include --wait + export EDITOR="code --wait" + ``` + + To make it permanent, add this to your shell profile; + `~/.bashrc`, `~/.zshrc`, etc. + + + + + ```bash + set EDITOR=notepad + + # For GUI editors, VS Code, Cursor, VSCodium, Windsurf, Zed, etc. + # include --wait + set EDITOR=code --wait + ``` + + To make it permanent, use **System Properties** > **Environment + Variables**. + + + + + ```powershell + $env:EDITOR = "notepad" + + # For GUI editors, VS Code, Cursor, VSCodium, Windsurf, Zed, etc. + # include --wait + $env:EDITOR = "code --wait" + ``` + + To make it permanent, add this to your PowerShell profile. + + + + +Popular editor options include: + +- `code` - Visual Studio Code +- `cursor` - Cursor +- `windsurf` - Windsurf +- `nvim` - Neovim editor +- `vim` - Vim editor +- `nano` - Nano editor +- `notepad` - Windows Notepad +- `subl` - Sublime Text + +:::note +Some editors like VS Code need to be started with the `--wait` flag. +::: + +Some editors need command-line arguments to run in blocking mode. The `--wait` flag makes the editor process block until closed. + +--- + +## Configure + +You can customize TUI behavior through `tui.json` (or `tui.jsonc`). + +```json title="tui.json" +{ + "$schema": "https://opencode.ai/tui.json", + "theme": "opencode", + "leader_timeout": 2000, + "keybinds": { + "leader": "ctrl+x", + "command_list": "ctrl+p" + }, + "scroll_speed": 3, + "scroll_acceleration": { + "enabled": false + }, + "diff_style": "auto", + "mouse": true, + "attention": { + "enabled": true, + "notifications": true, + "sound": true, + "volume": 0.4, + "sound_pack": "opencode.default", + "sounds": { + "error": "./sounds/error.mp3" + } + } +} +``` + +This is separate from `codev.json`, which configures server/runtime behavior. + +`keybinds` is merged with built-in defaults, so you only need to configure the shortcuts you want to change. + +### Options + +- `theme` - Sets your UI theme. [Learn more](/docs/themes). +- `keybinds` - Customizes keyboard shortcuts. [Learn more](/docs/keybinds). +- `leader_timeout` - Controls how long CoDev Code waits after the leader key. Defaults to `2000`. +- `scroll_acceleration.enabled` - Enable macOS-style scroll acceleration for smooth, natural scrolling. When enabled, scroll speed increases with rapid scrolling gestures and stays precise for slower movements. **This setting takes precedence over `scroll_speed` and overrides it when enabled.** +- `scroll_speed` - Controls how fast the TUI scrolls when using scroll commands (minimum: `0.001`, supports decimal values). Defaults to `3`. **Note: This is ignored if `scroll_acceleration.enabled` is set to `true`.** +- `diff_style` - Controls diff rendering. `"auto"` adapts to terminal width, `"stacked"` always shows a single-column layout. +- `mouse` - Enable or disable mouse capture in the TUI (default: `true`). When disabled, the terminal's native mouse selection/scrolling behavior is preserved. +- `attention` - Configures TUI desktop notifications and sounds. Disabled by default. + +Use `CODEV_TUI_CONFIG` to load a custom TUI config path. + +### Attention + +The TUI can request attention for questions, permissions, session errors, and completed sessions. Enable it with `attention.enabled`; built-in events play sounds when triggered, and non-subagent events request desktop notifications only when the terminal is blurred. + +- `enabled` - Enable all attention notifications and sounds. Defaults to `false`. +- `notifications` - Allow terminal-mediated desktop notifications when attention is enabled. Defaults to `true`. +- `sound` - Allow attention sounds when attention is enabled. Defaults to `true`. +- `volume` - Default sound volume from `0` to `1`. Defaults to `0.4`. +- `sound_pack` - Sound pack ID to use. Defaults to `opencode.default`. +- `sounds` - Override sound files for `default`, `question`, `permission`, `error`, `done`, or `subagent_done`. Paths can be absolute, `file://` URLs, or relative to `tui.json`. + +--- + +## Customization + +You can customize various aspects of the TUI view using the command palette (`ctrl+p`). These settings persist across restarts. + +--- + +#### Username display + +Toggle whether your username appears in chat messages. Access this through: + +- Command palette: Search for "username" or "hide username" +- The setting persists automatically and will be remembered across TUI sessions diff --git a/packages/web/src/content/docs/web.mdx b/packages/web/src/content/docs/web.mdx new file mode 100644 index 0000000000..42e7f53282 --- /dev/null +++ b/packages/web/src/content/docs/web.mdx @@ -0,0 +1,142 @@ +--- +title: Web +description: Using CoDev Code in your browser. +--- + +CoDev Code can run as a web application in your browser, providing the same powerful AI coding experience without needing a terminal. + +![CoDev Code Web - New Session](../../assets/web/web-homepage-new-session.png) + +## Getting Started + +Start the web interface by running: + +```bash +codev web +``` + +This starts a local server on `127.0.0.1` with a random available port and automatically opens CoDev Code in your default browser. + +:::caution +If `CODEV_SERVER_PASSWORD` is not set, the server will be unsecured. This is fine for local use but should be set for network access. +::: + +:::tip[Windows Users] +For the best experience, run `codev web` from [WSL](/docs/windows-wsl) rather than PowerShell. This ensures proper file system access and terminal integration. +::: + +--- + +## Configuration + +You can configure the web server using command line flags or in your [config file](/docs/config). + +### Port + +By default, CoDev Code picks an available port. You can specify a port: + +```bash +codev web --port 4096 +``` + +### Hostname + +By default, the server binds to `127.0.0.1` (localhost only). To make CoDev Code accessible on your network: + +```bash +codev web --hostname 0.0.0.0 +``` + +When using `0.0.0.0`, CoDev Code will display both local and network addresses: + +``` + Local access: http://localhost:4096 + Network access: http://192.168.1.100:4096 +``` + +### mDNS Discovery + +Enable mDNS to make your server discoverable on the local network: + +```bash +codev web --mdns +``` + +This automatically sets the hostname to `0.0.0.0` and advertises the server as `opencode.local`. + +You can customize the mDNS domain name to run multiple instances on the same network: + +```bash +codev web --mdns --mdns-domain myproject.local +``` + +### CORS + +To allow additional domains for CORS (useful for custom frontends): + +```bash +codev web --cors https://example.com +``` + +### Authentication + +To protect access, set a password using the `CODEV_SERVER_PASSWORD` environment variable: + +```bash +CODEV_SERVER_PASSWORD=secret codev web +``` + +The username defaults to `opencode` but can be changed with `CODEV_SERVER_USERNAME`. + +--- + +## Using the Web Interface + +Once started, the web interface provides access to your CoDev Code sessions. + +### Sessions + +View and manage your sessions from the homepage. You can see active sessions and start new ones. + +![CoDev Code Web - Active Session](../../assets/web/web-homepage-active-session.png) + +### Server Status + +Click "See Servers" to view connected servers and their status. + +![CoDev Code Web - See Servers](../../assets/web/web-homepage-see-servers.png) + +--- + +## Attaching a Terminal + +You can attach a terminal TUI to a running web server: + +```bash +# Start the web server +codev web --port 4096 + +# In another terminal, attach the TUI +codev attach http://localhost:4096 +``` + +This allows you to use both the web interface and terminal simultaneously, sharing the same sessions and state. + +--- + +## Config File + +You can also configure server settings in your `codev.json` config file: + +```json +{ + "server": { + "port": 4096, + "hostname": "0.0.0.0", + "mdns": true, + "cors": ["https://example.com"] + } +} +``` + +Command line flags take precedence over config file settings. diff --git a/packages/web/src/content/docs/windows-wsl.mdx b/packages/web/src/content/docs/windows-wsl.mdx new file mode 100644 index 0000000000..d1db4c18d4 --- /dev/null +++ b/packages/web/src/content/docs/windows-wsl.mdx @@ -0,0 +1,112 @@ +--- +title: Windows (WSL) +description: Run CoDev Code on Windows using WSL for the best experience. +--- + +import { Steps } from "@astrojs/starlight/components" + +While CoDev Code can run directly on Windows, we recommend using [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/install) for the best experience. WSL provides a Linux environment that works seamlessly with CoDev Code's features. + +:::tip[Why WSL?] +WSL offers better file system performance, full terminal support, and compatibility with development tools that CoDev Code relies on. +::: + +--- + +## Setup + + + +1. **Install WSL** + + If you haven't already, [install WSL](https://learn.microsoft.com/en-us/windows/wsl/install) using the official Microsoft guide. + +2. **Install CoDev Code in WSL** + + Once WSL is set up, open your WSL terminal and install CoDev Code using one of the [installation methods](/docs/). + + ```bash + npm install -g codev-code + ``` + +3. **Use CoDev Code from WSL** + + Navigate to your project directory (access Windows files via `/mnt/c/`, `/mnt/d/`, etc.) and run CoDev Code. + + ```bash + cd /mnt/c/Users/YourName/project + codev + ``` + + + +--- + +## Desktop App + WSL Server + +If you prefer using the CoDev Code Desktop app but want to run the server in WSL: + +1. **Start the server in WSL** with `--hostname 0.0.0.0` to allow external connections: + + ```bash + codev serve --hostname 0.0.0.0 --port 4096 + ``` + +2. **Connect the Desktop app** to `http://localhost:4096` + +:::note +If `localhost` does not work in your setup, connect using the WSL IP address instead (from WSL: `hostname -I`) and use `http://:4096`. +::: + +:::caution +When using `--hostname 0.0.0.0`, set `CODEV_SERVER_PASSWORD` to secure the server. +::: + +```bash +CODEV_SERVER_PASSWORD=your-password codev serve --hostname 0.0.0.0 +``` + +--- + +## Web Client + WSL + +For the best web experience on Windows: + +1. **Run `codev web` in the WSL terminal** rather than PowerShell: + + ```bash + codev web --hostname 0.0.0.0 + ``` + +2. **Access from your Windows browser** at `http://localhost:` (CoDev Code prints the URL) + +Running `codev web` from WSL ensures proper file system access and terminal integration while still being accessible from your Windows browser. + +--- + +## Accessing Windows Files + +WSL can access all your Windows files through the `/mnt/` directory: + +- `C:` drive → `/mnt/c/` +- `D:` drive → `/mnt/d/` +- And so on... + +Example: + +```bash +cd /mnt/c/Users/YourName/Documents/project +codev +``` + +:::tip +For the smoothest experience, consider cloning/copying your repo into the WSL filesystem (for example under `~/code/`) and running CoDev Code there. +::: + +--- + +## Tips + +- Keep CoDev Code running in WSL for projects stored on Windows drives - file access is seamless +- Use VS Code's [WSL extension](https://code.visualstudio.com/docs/remote/wsl) alongside CoDev Code for an integrated development workflow +- Your CoDev Code config and sessions are stored within the WSL environment at `~/.local/share/codev/` diff --git a/packages/web/src/content/docs/zen.mdx b/packages/web/src/content/docs/zen.mdx new file mode 100644 index 0000000000..45469c9151 --- /dev/null +++ b/packages/web/src/content/docs/zen.mdx @@ -0,0 +1,331 @@ +--- +title: Zen +description: Curated list of models provided by OpenCode. +--- + +import config from "../../../config.mjs" +export const console = config.console +export const email = `mailto:${config.email}` + +OpenCode Zen is a list of tested and verified models provided by the OpenCode team. + +Zen works like any other provider in CoDev Code. You login to OpenCode Zen and get +your API key. It's **completely optional** and you don't need to use it to use +CoDev Code. + +--- + +## Background + +There are a large number of models out there but only a few of +these models work well as coding agents. Additionally, most providers are +configured very differently; so you get very different performance and quality. + +:::tip +We tested a select group of models and providers that work well with CoDev Code. +::: + +So if you are using a model through something like OpenRouter, you can never be +sure if you are getting the best version of the model you want. + +To fix this, we did a couple of things: + +1. We tested a select group of models and talked to their teams about how to + best run them. +2. We then worked with a few providers to make sure these were being served + correctly. +3. Finally, we benchmarked the combination of the model/provider and came up + with a list that we feel good recommending. + +OpenCode Zen is an AI gateway that gives you access to these models. + +--- + +## How it works + +OpenCode Zen works like any other provider in CoDev Code. + +1. You sign in to **OpenCode Zen**, add your billing + details, and copy your API key. +2. You run the `/connect` command in the TUI, select OpenCode Zen, and paste your API key. +3. Run `/models` in the TUI to see the list of models we recommend. + +You are charged per request and you can add credits to your account. + +--- + +## Endpoints + +You can also access our models through the following API endpoints. + +| Model | Model ID | Endpoint | AI SDK Package | +| ---------------------- | ---------------------- | ---------------------------------------------------- | --------------------------- | +| GPT 5.6 Sol | gpt-5.6-sol | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.6 Terra | gpt-5.6-terra | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.6 Luna | gpt-5.6-luna | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.5 | gpt-5.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.5 Pro | gpt-5.5-pro | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.4 | gpt-5.4 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.4 Pro | gpt-5.4-pro | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.4 Mini | gpt-5.4-mini | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.4 Nano | gpt-5.4-nano | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.3 Codex | gpt-5.3-codex | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.3 Codex Spark | gpt-5.3-codex-spark | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.2 | gpt-5.2 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.2 Codex | gpt-5.2-codex | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.1 | gpt-5.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.1 Codex | gpt-5.1-codex | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.1 Codex Max | gpt-5.1-codex-max | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5.1 Codex Mini | gpt-5.1-codex-mini | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5 | gpt-5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5 Codex | gpt-5-codex | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| GPT 5 Nano | gpt-5-nano | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` | +| Claude Fable 5 | claude-fable-5 | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Claude Opus 4.8 | claude-opus-4-8 | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Claude Opus 4.7 | claude-opus-4-7 | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Claude Opus 4.6 | claude-opus-4-6 | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Claude Opus 4.5 | claude-opus-4-5 | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Claude Sonnet 5 | claude-sonnet-5 | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Claude Sonnet 4.6 | claude-sonnet-4-6 | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Claude Sonnet 4.5 | claude-sonnet-4-5 | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Claude Haiku 4.5 | claude-haiku-4-5 | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Gemini 3.5 Flash | gemini-3.5-flash | `https://opencode.ai/zen/v1/models/gemini-3.5-flash` | `@ai-sdk/google` | +| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` | +| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | +| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| Qwen3.5 Plus | qwen3.5-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` | +| DeepSeek V4 Pro | deepseek-v4-pro | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| DeepSeek V4 Flash | deepseek-v4-flash | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.2 | glm-5.2 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| Kimi K2.6 | kimi-k2.6 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| Kimi K2.7 Code | kimi-k2.7-code | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| MiMo-V2.5 Free | mimo-v2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| North Mini Code Free | north-mini-code-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| Nemotron 3 Ultra Free | nemotron-3-ultra-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| DeepSeek V4 Flash Free | deepseek-v4-flash-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | + +The [model id](/docs/config/#models) in your CoDev Code config +uses the format `opencode/`. For example, for GPT 5.5, you would +use `opencode/gpt-5.5` in your config. + +--- + +### Models + +You can fetch the full list of available models and their metadata from: + +``` +https://opencode.ai/zen/v1/models +``` + +--- + +## Pricing + +We support a pay-as-you-go model. Below are the prices **per 1M tokens**. + +| Model | Input | Output | Cached Read | Cached Write | +| --------------------------------- | ------ | ------- | ----------- | ------------ | +| Big Pickle | Free | Free | Free | - | +| DeepSeek V4 Flash Free | Free | Free | Free | - | +| MiMo-V2.5 Free | Free | Free | Free | - | +| North Mini Code Free | Free | Free | Free | - | +| Nemotron 3 Ultra Free | Free | Free | Free | - | +| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | +| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | - | +| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | - | +| GLM 5.2 | $1.40 | $4.40 | $0.26 | - | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | +| GLM 5 | $1.00 | $3.20 | $0.20 | - | +| Kimi K2.7 Code | $0.95 | $4.00 | $0.19 | - | +| Kimi K2.6 | $0.95 | $4.00 | $0.16 | - | +| Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | +| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | +| Qwen3.7 Plus | $0.40 | $1.60 | $0.04 | $0.50 | +| Qwen3.6 Plus | $0.50 | $3.00 | $0.05 | $0.625 | +| Qwen3.5 Plus | $0.20 | $1.20 | $0.02 | $0.25 | +| DeepSeek V4 Pro | $1.74 | $3.48 | $0.145 | - | +| DeepSeek V4 Flash | $0.14 | $0.28 | $0.028 | - | +| Claude Fable 5 | $10.00 | $50.00 | $1.00 | $12.50 | +| Claude Opus 4.8 | $5.00 | $25.00 | $0.50 | $6.25 | +| Claude Opus 4.7 | $5.00 | $25.00 | $0.50 | $6.25 | +| Claude Opus 4.6 | $5.00 | $25.00 | $0.50 | $6.25 | +| Claude Opus 4.5 | $5.00 | $25.00 | $0.50 | $6.25 | +| Claude Sonnet 5 | $2.00 | $10.00 | $0.20 | $2.50 | +| Claude Sonnet 4.6 | $3.00 | $15.00 | $0.30 | $3.75 | +| Claude Sonnet 4.5 (≤ 200K tokens) | $3.00 | $15.00 | $0.30 | $3.75 | +| Claude Sonnet 4.5 (> 200K tokens) | $6.00 | $22.50 | $0.60 | $7.50 | +| Claude Haiku 4.5 | $1.00 | $5.00 | $0.10 | $1.25 | +| Gemini 3.5 Flash | $1.50 | $9.00 | $0.15 | - | +| Gemini 3.1 Pro (≤ 200K tokens) | $2.00 | $12.00 | $0.20 | - | +| Gemini 3.1 Pro (> 200K tokens) | $4.00 | $18.00 | $0.40 | - | +| Gemini 3 Flash | $0.50 | $3.00 | $0.05 | - | +| Grok 4.5 (≤ 200K tokens) | $2.00 | $6.00 | $0.30 | - | +| Grok 4.5 (> 200K tokens) | $4.00 | $12.00 | $0.60 | - | +| Grok Build 0.1 | $1.00 | $2.00 | $0.20 | - | +| GPT 5.6 Sol (≤ 272K tokens) | $5.00 | $30.00 | $0.50 | $6.25 | +| GPT 5.6 Sol (> 272K tokens) | $10.00 | $45.00 | $1.00 | $12.50 | +| GPT 5.6 Terra (≤ 272K tokens) | $2.50 | $15.00 | $0.25 | $3.125 | +| GPT 5.6 Terra (> 272K tokens) | $5.00 | $22.50 | $0.50 | $6.25 | +| GPT 5.6 Luna (≤ 272K tokens) | $1.00 | $6.00 | $0.10 | $1.25 | +| GPT 5.6 Luna (> 272K tokens) | $2.00 | $9.00 | $0.20 | $2.50 | +| GPT 5.5 (≤ 272K tokens) | $5.00 | $30.00 | $0.50 | - | +| GPT 5.5 (> 272K tokens) | $10.00 | $45.00 | $1.00 | - | +| GPT 5.5 Pro | $30.00 | $180.00 | $30.00 | - | +| GPT 5.4 (≤ 272K tokens) | $2.50 | $15.00 | $0.25 | - | +| GPT 5.4 (> 272K tokens) | $5.00 | $22.50 | $0.50 | - | +| GPT 5.4 Pro | $30.00 | $180.00 | $30.00 | - | +| GPT 5.4 Mini | $0.75 | $4.50 | $0.075 | - | +| GPT 5.4 Nano | $0.20 | $1.25 | $0.02 | - | +| GPT 5.3 Codex Spark | $1.75 | $14.00 | $0.175 | - | +| GPT 5.3 Codex | $1.75 | $14.00 | $0.175 | - | +| GPT 5.2 | $1.75 | $14.00 | $0.175 | - | +| GPT 5.2 Codex | $1.75 | $14.00 | $0.175 | - | +| GPT 5.1 | $1.07 | $8.50 | $0.107 | - | +| GPT 5.1 Codex | $1.07 | $8.50 | $0.107 | - | +| GPT 5.1 Codex Max | $1.25 | $10.00 | $0.125 | - | +| GPT 5.1 Codex Mini | $0.25 | $2.00 | $0.025 | - | +| GPT 5 | $1.07 | $8.50 | $0.107 | - | +| GPT 5 Codex | $1.07 | $8.50 | $0.107 | - | +| GPT 5 Nano | $0.05 | $0.40 | $0.005 | - | + +You might notice _Claude Haiku 3.5_ in your usage history. This is a [low cost model](/docs/config/#models) that's used to generate the titles of your sessions. + +:::note +Credit card fees are passed along at cost (4.4% + $0.30 per transaction); we don't charge anything beyond that. +::: + +The free models: + +- DeepSeek V4 Flash Free is available on OpenCode for a limited time. The team is using this time to collect feedback and improve the model. +- MiMo-V2.5 Free is available on OpenCode for a limited time. The team is using this time to collect feedback and improve the model. +- North Mini Code Free is available on OpenCode for a limited time. The team is using this time to collect feedback and improve the model. +- Nemotron 3 Ultra Free is available on OpenCode for a limited time. The team is using this time to collect feedback and improve the model. +- Big Pickle is a stealth model that's free on OpenCode for a limited time. The team is using this time to collect feedback and improve the model. + +Contact us if you have any questions. + +--- + +### Auto-reload + +If your balance goes below $5, Zen will automatically reload $20. + +You can change the auto-reload amount. You can also disable auto-reload entirely. + +--- + +### Monthly limits + +You can also set a monthly usage limit for the entire workspace and for each +member of your team. + +For example, let's say you set a monthly usage limit to $20, Zen will not use +more than $20 in a month. But if you have auto-reload enabled, Zen might end up +charging you more than $20 if your balance goes below $5. + +--- + +### Deprecated models + +| Model | Deprecation date | +| ------------------ | ----------------- | +| GPT 5.2 Codex | July 23, 2026 | +| GPT 5.1 Codex | July 23, 2026 | +| GPT 5.1 Codex Max | July 23, 2026 | +| GPT 5.1 Codex Mini | July 23, 2026 | +| GPT 5 Codex | July 23, 2026 | +| Claude Opus 4.1 | August 5, 2026 | +| Claude Sonnet 4 | June 15, 2026 | +| Claude Haiku 3.5 | February 16, 2026 | +| Gemini 3 Pro | March 9, 2026 | +| MiniMax M2.5 | August 5, 2026 | +| MiniMax M2.1 | March 15, 2026 | +| GLM 5 | May 14, 2026 | +| GLM 4.7 | March 15, 2026 | +| GLM 4.6 | March 15, 2026 | +| Kimi K2.5 | August 5, 2026 | +| Kimi K2 Thinking | March 6, 2026 | +| Kimi K2 | March 6, 2026 | +| Qwen3 Coder 480B | February 6, 2026 | + +--- + +## Privacy + +All our models are hosted in the US. Our providers follow a zero-retention policy and do not use your data for model training, with the following exceptions: + +- Big Pickle: During its free period, collected data may be used to improve the model. +- DeepSeek V4 Flash Free: During its free period, collected data may be used to improve the model. +- MiMo-V2.5 Free: During its free period, collected data may be used to improve the model. +- North Mini Code Free: During its free period, collected data may be retained and used to improve the model. Do not submit personal or confidential data. See our [Terms of Use](https://cohere.com/terms-of-use) and [Privacy Policy](https://cohere.com/privacy). +- Nemotron 3 Ultra Free (NVIDIA free endpoints): Trial use only — do not submit personal or confidential data. Your use is logged for security purposes and to improve NVIDIA products and services. The logged session data for improvement purposes is not linked to your identity or any persistent identifier. For more information about our data processing practices, see our [Privacy Policy](https://assets.ngc.nvidia.com/products/api-catalog/legal/NVIDIA%20API%20Trial%20Terms%20of%20Service.pdf). By interacting with this endpoint, you consent to our collection, recording, and use of such information and the [NVIDIA API Trial Terms of Service](https://assets.ngc.nvidia.com/products/api-catalog/legal/NVIDIA%20API%20Trial%20Terms%20of%20Service.pdf). +- OpenAI APIs: Requests are retained for 30 days in accordance with [OpenAI's Data Policies](https://platform.openai.com/docs/guides/your-data). +- Anthropic APIs: Requests are retained for 30 days in accordance with [Anthropic's Data Policies](https://docs.anthropic.com/en/docs/claude-code/data-usage). + +--- + +## For Teams + +Zen also works great for teams. You can invite teammates, assign roles, curate +the models your team uses, and more. + +:::note +Workspaces are currently free for teams as a part of the beta. +::: + +Managing your workspace is currently free for teams as a part of the beta. We'll be +sharing more details on the pricing soon. + +--- + +### Roles + +You can invite teammates to your workspace and assign roles: + +- **Admin**: Manage models, members, API keys, and billing +- **Member**: Manage only their own API keys + +Admins can also set monthly spending limits for each member to keep costs under control. + +--- + +### Model access + +Admins can enable or disable specific models for the workspace. Requests made to a disabled model will return an error. + +This is useful for cases where you want to disable the use of a model that +collects data. + +--- + +### Bring your own key + +You can use your own OpenAI or Anthropic API keys while still accessing other models in Zen. + +When you use your own keys, tokens are billed directly by the provider, not by Zen. + +For example, your organization might already have a key for OpenAI or Anthropic +and you want to use that instead of the one that Zen provides. + +--- + +## Goals + +We created OpenCode Zen to: + +1. **Benchmark** the best models/providers for coding agents. +2. Have access to the **highest quality** options and not downgrade performance or route to cheaper providers. +3. Pass along any **price drops** by selling at cost; so the only markup is to cover our processing fees. +4. Have **no lock-in** by allowing you to use it with any other coding agent. And always let you use any other provider with CoDev Code as well.