mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-10-31 19:10:30 +00:00
10 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a2274d6c0f
|
chore(opencode): recommend OpenCode 2.2.5 (#1222)
## Summary - OpenCode **2.2.5** becomes the **recommended** (qualified) runtime. The **2.2.3 minimum** and the 2.1.0 `@opencode/client`/`plugin`/`schema` pins stay: neither 2.2.4 nor 2.2.5 changes a contract CodeNomad consumes. - `RECOMMENDED_OPENCODE_VERSION` is 2.2.5, and the reviewed-publication shortcut in `contractProfile` lists 2.2.3 and 2.2.5; other versions, 2.2.4 included, keep negotiating their authenticated schema. The CI `latest` lane already resolves the latest stable CLI. - Help (all ten locales), READMEs, `CONTRIBUTING.md`, `dev-docs/OPENCODE_COMPATIBILITY.md` and the architecture skill state two separate versions again: minimum 2.2.3 with its reason, recommendation 2.2.5. ## Contract review (v2.2.3 → v2.2.4 → v2.2.5; 31 + 19 commits) Reviewed from the exact tags `v2.2.3` (`082ac6281f`), `v2.2.4` (`45898d0f85`) and `v2.2.5` (`9bbb8ce18c`), the published npm packages, and an authenticated OpenAPI dump from each official CLI running in its own sandbox. The [changelog](https://opencode.ai/changelog) has full notes for 2.2.4 and 2.2.5 (both 30 October); everything below was also checked against the commit log and source. CodeNomad side: `origin/dev` ` |
||
|
|
77c24601a8
|
fix(opencode): require OpenCode 2.2.3 and adopt its image tool contract (#1209)
## Summary
- OpenCode **2.2.3** becomes both the **technical minimum** and the
**recommended** runtime. The minimum moves because upstream
[#60258](https://github.com/anomalyco/opencode/pull/60258) (shipped in
2.2.2) changed the image tool contract that CodeNomad's Images gallery,
Design agent and Images settings consume: one name,
`experimental_image_generate`, for the tool, its permission action, its
job type and its completion notices' `metadata.source`, and the tool on
by default (only `experimental.image_generate: false` disables it). On
2.2.2+, the gallery lost every generation entry and the Design companion
fixture timed out; 2.2.1 passed.
- Images are implemented for the 2.2.3 contract only, with no fallback
to the old name: `IMAGE_TOOL` drives the gallery and its proof;
`imageGenerationSelection` reads unset as on; the Design agent and
skills name the new tool; the activation fixture exercises the image
tool instead of falling back to webfetch; the gallery fixture represents
the 2.2.3 transcript format.
- Older daemons (2.1.x, 2.2.1, 2.2.2) go through the existing
below-minimum path (`native_contract`). The 2.1.0 client/plugin/schema
pins stay.
- Help (all ten locales), READMEs, `CONTRIBUTING.md`, `dev-docs`
(compatibility, pruning, panel extensions, settings) and the
architecture skill describe the new minimum, its reason and default-on
image generation. The setup minimum-reason UI string is updated in all
locales.
## Contract review (v2.2.1 → v2.2.2 → v2.2.3; 40 + 101 commits)
Reviewed from the exact tags `v2.2.1` (`3ebcf9a32c`), `v2.2.2`
(`098aa7fd6e`) and `v2.2.3` (`082ac6281f`), the published npm packages,
and an authenticated OpenAPI dump from each official CLI running in its
own sandbox. The [changelog](https://opencode.ai/changelog) has entries
for both 2.2.2 (29 October, highlights only) and 2.2.3 (30 October, full
notes); everything below was also checked against the commit log and
source.
**Headline:** the HTTP contract CodeNomad consumes didn't change, but
2.2.2 **renamed the image tool** from `image_generate` to
`experimental_image_generate` and **turned it on by default**
([#60258](https://github.com/anomalyco/opencode/pull/60258)).
CodeNomad's Images/Design features match the old name and the old
default, so they break on 2.2.2 and later (see [Design companion
finding](#design-companion-finding)). Nothing else found affects
CodeNomad.
- **Authenticated OpenAPI:** **134 paths and 162 operations** on all
three, the same operation set. Schemas 355 → 350 → 351.
- **Added/removed operations:** none in either release.
- **Changed operations (2.2.2):** `GET /api/model`, `GET /api/event`,
`PUT /api/pty/{ptyID}`, `POST /api/shell`, `GET /api/shell/{id}/output`,
`POST /api/debug/heap-dump` and `GET /api/experimental/migration/v1`.
All of these are **representation-only**: the Effect 4.0.6 JSON Schema
output flattens nested `anyOf`, bounds integers with `maximum:
9007199254740991` (and `minimum` for signed integers), and rewrites the
numeric-string query pattern. The event-type and model-type enums are
unchanged.
- **Changed operations (2.2.3):** only the description of `POST
/api/credential`, which can now be refused by an `integration.connect`
policy.
- **Consumed schemas:** the same family selector as the 2.2.1 review
(`V2EventEncoded`, `Session.*`, `SessionStats.*`, `Form.*`,
`Permission.*`, `Prompt*`, `Event.*`, `Location.*`, PTY/Shell).
Re-derived from that description it selects 104 schemas at 2.2.1 (the
2.2.1 file says 103), all byte-identical from 2.1.4 to 2.2.1.
- In 2.2.2 the seven alias copies `Form.Fields_1..3` and
`Session.Message.Native_1..4` collapse into their base schemas, which
are byte-identical to the copies, leaving **97**. Of these, 71 are
byte-identical and 24 differ only in generator representation.
- Two changes are additive and optional: `Session.Info.time.busy`, the
start of the latest execution
([#59910](https://github.com/anomalyco/opencode/pull/59910)), and the
input field `PromptInput.FileAttachment.source` (`Prompt.FileSource`,
inline or uri; CodeNomad doesn't send it).
- `V2EventEncoded`, `Session.Message.*` content, `Session.Inbox.*`,
`Form.*` semantics, `Permission.*` and `Event.SeqEncoded` are unchanged.
- From 2.2.2 to 2.2.3 the family is byte-identical.
- **`Config.InfoEncoded`:** no semantic change in 2.2.2 (representation
only). 2.2.3 extends the managed-policy `action` enum (top-level and
`experimental.policies`) with `integration.connect`, `mcp.use`,
`skill.use` and `plugin.use`
([#60315](https://github.com/anomalyco/opencode/pull/60315)); CodeNomad
writes no policies. The *meaning* of `experimental.image_generate`
changed: unset now means on, and only `false` turns it off. The schema
shape stayed the same and the OpenAPI carries no description, so no
contract signal reveals it.
- **Schedules (not consumed on dev):** `when` becomes optional;
`if`/`until` conditions (shell in 2.2.2, Code Mode in 2.2.3) are added;
outcomes gain `checked`/`expired`.
- **Admission:** every predicate in `compatibility/negotiate.ts`
(unchanged since the 2.2.1 review) holds on 2.2.1, 2.2.2 and 2.2.3.
- **Instance proxy:** no new routes and an unchanged allowlist. Proxied
routes whose representation changed: `GET /api/model`, `PUT
/api/pty/{id}`, `POST /api/shell` and `GET /api/shell/{id}/output`.
Integer bounds and an equivalent numeric pattern accept everything
CodeNomad sends.
- **Published declarations** (2.2.1 → 2.2.3):
- **Client:** 185 methods on all three; the method tree is identical.
2.2.2 adds the generated types `ScheduleCondition*`; `FormFields2` is
renamed to `FormFields1`, which is generated-type churn. 2.2.3 adds the
Promise media helpers `withMediaRefs`, `mediaHashFromUri` and
`MediaRequestOptions`
([#60116](https://github.com/anomalyco/opencode/pull/60116)) and
persistent-PTY frame helpers in `solid/pty`. CodeNomad imports none of
these.
- **Schema:** 2.2.2 adds schedule conditions (`ShellCondition`,
`CheckMode`, …) and exports `SessionLegacy.part`. 2.2.3 adds
`CodeCondition*` and `policy.Action`.
- **Plugin:** 2.2.2 adds the GUI
`ComposerQuoteAnchor`/`ComposerFocusOptions`. 2.2.3 has no export
changes, but the optional peers `@opentui/*` become `>=0.8.0`
([#60385](https://github.com/anomalyco/opencode/pull/60385)). The
published `dependencies.effect` moves from **4.0.1 to 4.0.6** (2.2.2).
- **Typecheck:** the server and UI typecheck with **0 errors** against
the 2.2.2 and 2.2.3 client/schema/plugin/effect declarations through
scratch `paths` overrides. The pinned 2.1.0 control is also clean. The
harness now also remaps `effect` itself; the 2.2.1 harness skipped it
because effect's `exports` are plain `.js` strings.
- **Host modules:** the three daemon-loaded bundles still import
`@opencode/plugin` (`Plugin`), `/effect` (`Plugin`, `Rpc`, `Location`),
`/promise/adapter` (`fromPromise`), `/rpc` (`Rpc`), `effect` and
`effect/encoding` (`Base64Url`) from the host. A probe plugin in an
isolated **2.2.3** daemon resolves every module and binding, as on
2.2.1. `runtime-modules.ts` is unchanged between the tags.
- **Host Effect: 4.0.1 → 4.0.6** (2.2.2,
[#59630](https://github.com/anomalyco/opencode/pull/59630)). The 2.1.0
`@opencode/schema`/`@opencode/client` code bundled into the Missions and
pruning plugins now runs on host Effect 4.0.6. The plugin-runtime,
pruning, Missions-contract, permission-receipts and image-settings
native suites pass on 2.2.3.
- **Private native services:** the keys (`LocationServiceMap`, `Form`,
`Permission`, `Location`, `Job`, `Database`, `Session`, `Bus`) and the
members CodeNomad calls are unchanged. The changes are additive:
`Permission.Unattended` (a reference that denies unanswerable asks for
schedule checks), a `CorrectedError.message` getter, and `Session`
deciding fork media from the parent's location.
- **Storage** (three migrations): `session_part` (new table),
`session_v2.time_busy` and four `schedule` check columns.
- **`session_part`**
([#58915](https://github.com/anomalyco/opencode/pull/58915)): history
reads now *prefer* `session_part` rows over
`session_message.data.content` for assistant messages. The projector
writes parts there only for messages that already have part rows, so new
messages stay inline. Every 2.2.3 fixture DB inspected has **0**
`session_part` rows, and upstream `dev` (`1e28374e48`, 30 October) has
no writer either.
- The tables CodeNomad reads directly keep their shape.
- **Forward risk:** when a release starts writing parts, CodeNomad's
direct `session_message.data.content` readers and the pruning `UPDATE …
json_set(data,'$.content',…)` (`session-pruning/transaction.ts`) would
silently miss or be shadowed by part rows. See Recommendations.
- **Behavior changes checked:**
- **Image generation** (2.2.2): renamed and on by default. See the
[dedicated section](#design-companion-finding).
- **Code Mode:** inner tool progress no longer replaces the `execute`
call rows ([#60480](https://github.com/anomalyco/opencode/pull/60480)),
and progress is throttled to at most one update per 100 ms
([#60120](https://github.com/anomalyco/opencode/pull/60120)). Programs
see the same failure text as direct calls
([#60109](https://github.com/anomalyco/opencode/pull/60109)), `fetch` in
Code Mode is now subject to `webfetch` permissions
([#59954](https://github.com/anomalyco/opencode/pull/59954)), `for…in`
visits inherited keys
([#59933](https://github.com/anomalyco/opencode/pull/59933)) and `null`
survives text encoding
([#57639](https://github.com/anomalyco/opencode/pull/57639)). The
run-to-completion regression behind the 2.1.2 minimum passes on 2.2.3:
`{ total: 2000, beforeAwait: 1000, count: 1000 }`.
- **Permissions and MCP:** permission reasons and feedback are kept in
MCP tool failures
([#60102](https://github.com/anomalyco/opencode/pull/60102)). Shell
permission checks moved fully off tree-sitter and now check redirects,
PowerShell method calls and dynamic directory changes
([#60332](https://github.com/anomalyco/opencode/pull/60332),
[#60376](https://github.com/anomalyco/opencode/pull/60376)), so some
shell commands may now ask where they didn't. The managed-policy split
(`integration.use` vs `mcp.use`/`skill.use`/`plugin.use`) is a changelog
"breaking change" for managed deployments only.
- **Sessions:** deleting a session removes its persistent terminals
([#60322](https://github.com/anomalyco/opencode/pull/60322)), and a
persistent terminal with a missing cwd is rejected
([#60300](https://github.com/anomalyco/opencode/pull/60300)). Forked and
imported sessions store media as blobs when `media_blob` is on
([#60118](https://github.com/anomalyco/opencode/pull/60118)). The native
fork suite passes on 2.2.3.
- **Providers:** a built-in **Claude Agent** provider uses the user's
Claude Code login
([#58782](https://github.com/anomalyco/opencode/pull/58782)).
Plugin-supplied model variants are preserved
([#60097](https://github.com/anomalyco/opencode/pull/60097)), and the
dynamic provider npm fallback runs after external SDK hooks
([#60380](https://github.com/anomalyco/opencode/pull/60380)). These are
source-reviewed and touch no consumed contract.
- **Persistent PTY binary** (the process daemon): 2.2.2 switches from
`@opencode-ai/pty` 0.3.1 to `@opencode/pty` **0.3.3**
([#60276](https://github.com/anomalyco/opencode/pull/60276)).
`process-daemon-v0.3.3` contains only the release commit after 0.3.2 (a
version bump of the `@opencode/pty-*` binaries). **v0.4.0** (terminal
renaming, [#60324](https://github.com/anomalyco/opencode/pull/60324)) is
**not** shipped in CLI 2.2.3, which pins 0.3.3. CodeNomad only lists
persistent PTYs (worktree deletion guard), whose schema is unchanged
apart from representation.
- **Client fix not inherited:** the 2.2.3 client evicts missing sessions
on 404 ([#60459](https://github.com/anomalyco/opencode/pull/60459)).
CodeNomad stays on the 2.1.0 client.
- **`@opencode/ai` breaking changes** (media moved to `/experimental`,
one `tool()`): CodeNomad doesn't import `@opencode/ai`.
- Desktop/TUI-only changes (timeline performance, side-panel tabs,
spellcheck, question sounds, OpenTUI 0.8) don't affect CodeNomad.
**Verdict:**
- The **2.1.0 client/plugin pins stay**. Bumping them would bring
nothing CodeNomad consumes.
- No consumed HTTP/plugin contract broke; the breaking change is the
image tool contract of #60258, consumed by the Images gallery, the
Design agent and the Images settings.
- **Decision applied in this PR:** 2.2.3 becomes both the minimum and
the recommendation, and Images are implemented for the 2.2.3 contract
only (see Summary). This replaces the review's initial suggestion to
keep the 2.1.2 minimum and accept both tool names.
**Not verified here:**
- the full native suite matrix on 2.2.2/2.2.3; only the runs in Appendix
I were performed;
- the forward-compatibility of the `session_part` readers against a
runtime that writes parts (no such runtime exists yet);
- the Claude Agent provider and shell-permission changes at runtime
(source only);
- macOS/Linux.
---
## Design companion finding
**Symptom:** `scripts/test-design-companion-native.mjs <cli>` passes on
2.2.1 and fails on 2.2.2 and 2.2.3 with `Error: Timed out: series 1
generated and read`. Reproduced independently in a scratch checkout of
`origin/dev` (`f39642bc4`), with `CODENOMAD_NATIVE_FIXTURE_PARENT`
outside the home:
```
test-design-companion-native 2.2.1 exit=0 PASS AC-16, AC-52
test-design-companion-native 2.2.2 exit=1 Timed out: series 1 generated and read
test-design-companion-native 2.2.3 exit=1 Timed out: series 1 generated and read
```
**What the step waits for**
(`test-design-companion-native.mjs:238-241`): the fixture's loopback
chat provider answers a `RUN [...]` turn with two tool calls `{ tool:
"image_generate", args: { prompt, path: ".codenomad/design/icon/<name>"
} }`. The step then waits until the transcript holds two synthetic
notices with `metadata.source === "image_generate"` (line 209) and two
`read` parts of the generated files. No HTTP generate route, file watch
or media blob is involved; it is the agent tool path.
**Cause: an intentional upstream contract change, not an upstream bug.**
In 2.2.2, [#60258](https://github.com/anomalyco/opencode/pull/60258)
(`d4e48f54da`, "turn experimental_image_generate on by default") changed
`packages/core/src/tool/plugin/image-generate.ts`:
- `export const name = "image_generate"` →
`"experimental_image_generate"`. That one constant is the tool name, the
permission action (`assertions: ["experimental_image_generate", "edit",
"read"]`), the Job `type`, and the completion notice's
`metadata.source`. `session/execution/restart.ts` also tags
restart-recovery notices `source: "experimental_image_generate"`.
- The opt-in became default-on: `if (!enabled || imageGenerate(entries)
=== false) return`. An unset `experimental.image_generate` now offers
the tool; only `false` removes it ("still honored for configs from when
the tool was opt-in; permissions are the supported way to turn it off").
- The 2.2.2 changelog states it: "agents can now use
`experimental_image_generate` without additional configuration".
2.2.2 also wraps the notice text as `<image id="…"
state="…">\n…\n</image>` and adds `id` to the tool output
([#60098](https://github.com/anomalyco/opencode/pull/60098)).
CodeNomad's `Saved image: (.+) \(` parse still matches; `jobID`, `state`
and `path` metadata are unchanged.
**Evidence** (fixture DBs copied read-only to `evidence/`):
```
2.2.3, original fixture (calls "image_generate"):
seq 5 tool image_generate error "No tool named \"image_generate\" is currently available. Please use a tool from the available tool list." (x2)
-> no image job, no notice, no read: the wait times out.
2.2.3, fixture with the tool name changed (scratch copy; CodeNomad server code unmodified):
seq 5 tool experimental_image_generate completed {path:…/icon-minimal-a, model:"fiximg/image", jobID:"image_18cfb59…"}
seq 18 synthetic {"source":"experimental_image_generate","jobID":"image_18cfb59…","state":"completed",…}
<image id="image_18cfb59…" state="completed"> | Image request finished. Saved image: …
seq 20 tool read completed (x2) … seq 40/48/49 refinement
-> files, image calls and reads all correct, then
AssertionError: generations.length 0 !== 3 (test line 260: gallery "generation" entries)
```
So the product bug is real and independent of the fixture: on 2.2.2+
CodeNomad's Images gallery finds **no generation entries**. Images still
appear through their `read` parts, but without prompt, model, lineage or
"proven" origin, and `galleryImageReference` refuses them as `changed`.
**CodeNomad code that assumes the 2.2.1 name or default** (origin/dev):
| Where | Assumption | Effect on 2.2.2+ |
| --- | --- | --- |
| `session-pruning/assets-gallery.ts:56,139` | `part.name ===
"image_generate"` | no generation entries; references refused `changed`
|
| `session-pruning/assets-gallery-proof.ts:104,130` | tool name and
notice `source === "image_generate"` | no calls or notices, so no
provenance proof |
| `opencode/image-settings.ts` `imageGenerationSelection(undefined) →
false` (doc: "Reads … as OpenCode does") | unset means off | Settings →
Images shows **Off** and `images.status()` returns `"disabled"` while
the tool is offered; help step "Turn on image generation"
(`docs/help/en/extensions.md:73`) is no longer needed |
| `opencode/design/opencode/agents/design.md`, `skills/design-core`,
`design-logo`, `design-ui-mockup` | the agent is told to call
`image_generate` | the model sees only `experimental_image_generate`;
the first call can fail with "No tool named …" |
| `scripts/test-design-companion-native.mjs:125,209,238,301` | fixture
calls/filters `image_generate` | red on 2.2.2+ |
| `scripts/test-design-activation-native.mjs:76,307` | ask rule on
action `image_generate`; tool detection by that name | **passes but
loses coverage**: `askTool` falls back to `webfetch` on 2.2.2/2.2.3
(logged) |
| `dev-docs/SESSION_PRUNING_RPC.md`, `PANEL_EXTENSIONS.md`,
`SETTINGS.md` | describe `image_generate` parts and opt-in | out of date
for 2.2.2+ |
User permission rules written for action `image_generate` no longer
match on 2.2.2+; that is an OpenCode-side change for users. CodeNomad's
help never names the permission action; the Design fixtures and agent
use `experimental_image_generate`.
**Fix in this PR** (2.2.3 contract only, no fallback):
1. One `IMAGE_TOOL = "experimental_image_generate"` constant drives the
gallery and its proof; the gallery reads the 2.2.3 notice format.
2. The native fixtures use the new tool; the activation fixture
exercises it (default on) instead of falling back to webfetch.
3. The Design agent and skills name `experimental_image_generate`.
4. `imageGenerationSelection` reads an unset
`experimental.image_generate` as on; only `false` disables it. Settings
→ Images and `images.status()` report it that way.
## Follow-up
- Hardening for `session_part` (independent of this upgrade, no 2.2.3
regression): make the direct readers and the pruning transaction fail
safe when `session_part` has rows for the target messages.
## Isolated Windows qualification
Base: dev `
|
||
|
|
34406b3ada
|
feat(help): add a download page with exact release links and a new home page (#1190)
## Summary
- New **Download** help page (10 languages): an OS-detecting button
linking straight to the recommended Tauri build, then a static
Tauri/Electron table with every asset and its size, version and publish
date, and the winget/npm commands. The header Download link,
`install.md`, `support.md` and the README point to it.
- New **help home page** (10 languages): cockpit positioning, a
*Download CodeNomad* call to action, a silent 46 s tour that autoplays
on desktop only (poster and YouTube link on narrow screens and with
reduced motion), and short Missions / phone access / long histories
sections before the existing orientation sections.
- **Exact links without network in the builder**: `release:<id>` links
and `{{release}}`, `{{download-button}}`, `{{tour-video}}` directives
resolve from `docs/help/downloads.json` and optional `--release` data;
without data, links fall back to the latest release page.
- **Automatic refresh**: `scripts/resolve-help-release.mjs` (CI only)
picks the newest stable release whose assets are fully uploaded;
`help-pages.yml` republishes after a successful *Release Binaries* push
run on `main`, building trusted `dev` sources with read-only
permissions, the token scoped to the resolver step and one production
concurrency group. Pull requests never resolve or publish.
## Safety
- Release data is revalidated in the builder (exact
`github.com/NeuralNomadsAI/CodeNomad/releases/download/<tag>/<asset>`
URLs, no credentials/query/fragment/traversal, positive sizes, UTC
dates) and escaped.
- CSP stays `default-src 'none'`; only `media-src 'self'` is added. The
download script is allowed on the download page only, the tour video on
the home page only.
## Validation
- `npm run test:help`: 27/27 (26 pages × 10 locales, offline; resolver
selection/pagination, release validation, directive problems, 22
detector cases, workflow gates).
- `npm run build:help` with and without the release fixture.
- `node scripts/test-help-browser.mjs`: 46/46 (download button,
JavaScript disabled, video playback, reduced motion, narrow widths,
RTL).
- Read-only resolver run against the live API resolved `v1.0.0`.
The `workflow_run` path can only be observed on the next stable release
on `main`; `workflow_dispatch` from `dev` exercises resolver → build →
deploy.
|
||
|
|
ca514ed2ea
|
chore(opencode): qualify and recommend runtime 2.2.1 (#1188)
## Summary
- Qualify OpenCode **2.2.1** (latest stable, 29 October) with the
existing locked **2.1.0 client/plugin** dependencies, and **recommend**
it.
- Keep the technical **minimum at 2.1.2**: no consumed contract changed,
so the minimum has no new reason to move.
- 2.1.2, 2.1.4 and 2.2.0 daemons stay ready and get an optional upgrade
offer. 2.2.1 is the `tested` version. Newer and custom labels keep
authenticated contract recognition.
- The reviewed-contract fast path lists the 2.1.2 minimum and the 2.2.1
target.
- The recommended version is updated in the help (all ten locales), both
READMEs, `CONTRIBUTING.md`, `dev-docs/OPENCODE_COMPATIBILITY.md` and the
architecture skill.
## Contract review (v2.1.4 → v2.2.0 → v2.2.1; 661 + 134 commits)
Reviewed from the exact tags `v2.1.4` (`68bc26b7da`), `v2.2.0`
(`1097e2668b`) and `v2.2.1` (`3ebcf9a32c`), the published npm packages,
and an authenticated OpenAPI dump from each official CLI running in its
own sandbox. The [changelog](https://opencode.ai/changelog) covers
2.2.0. It had no 2.2.1 entry at review time (29 October), so 2.2.1 was
reviewed from its commit log.
- **Authenticated OpenAPI:** 124 → 130 → **134 paths**, 149 → 156 →
**162 operations**. Each dump matches the tagged
`packages/protocol/openapi.json`.
- **2.2.0 adds** `GET /api/plugin/gui`; `POST
/api/experimental/generate/{text,image,decisions}`; `POST`/`DELETE
/api/experimental/fs/watch`; `GET /api/experimental/media/{hash}`; and
`GET /api/experimental/usage/limits`.
- **2.2.0 removes** `POST
/api/experimental/voice/session/{sessionID}/instructions`.
- **2.2.1 adds** six `/api/experimental/schedule` operations (list,
create, get, delete, pause, resume), gated by `experimental.schedules`.
- **Changed operations:**
- `GET /api/model` gains an optional `types` filter. Without it the
route lists chat models only. Image and decision models are new in
2.2.0, so the default listing matches 2.1.4.
- `GET /api/event` gains an optional `types` filter.
- `GET /api/vcs/diff` gains an optional `untracked` parameter.
- `POST /api/experimental/generate` becomes the deprecated alias of
`/generate/text`.
- Nine session, project and saved-permission routes drop
`LocationNotFoundError` from their 404 responses: they no longer boot a
Location ([#58997](https://github.com/anomalyco/opencode/pull/58997)).
- `GET /api/agent` can now answer 503 while plugins settle
([#59082](https://github.com/anomalyco/opencode/pull/59082)).
- In 2.2.1, the session log and persistent-PTY operation IDs move under
`experimental.*`. Their paths are unchanged.
- **Schemas:** all 103 consumed-family schemas are byte-identical from
2.1.4 to 2.2.1. These are `V2EventEncoded`, `Session.*` (messages,
parts, inbox, info), `Form.*`, `Permission.*`, `Prompt*`, `Event.*`,
`Location.*` and PTY/Shell. The session prompt, environment, message,
form/permission reply and RPC operations are unchanged too. The only
`Config.InfoEncoded` changes are additive opt-ins:
`experimental.media_blob`, `experimental.image_generate`,
`experimental.schedules` and `timezone`. Model `type`, prompt-cache
`cache` settings, `FileDiff.Info.more`, `Mcp.Server.title` and
`ServerInfo.hostname` are additive fields.
- **Admission:** every predicate CodeNomad's
`compatibility/negotiate.ts` checks holds on 2.2.0 and 2.2.1. That
covers the canonical API, `session_environment` and the 2.1 replay shape
(`native` without `state`, compaction `metadata` without `recent`).
- **Instance proxy:** none of the new routes is on the allowlist. That
includes the GUI plugin bundle, generation, file watch, media blobs,
usage limits and schedules. The removed voice route was never exposed.
The routes CodeNomad does proxy kept their paths.
- **Published declarations** (2.1.0 pins → 2.1.4 → 2.2.1):
- **Client:** 143 → 147 → 185 methods. 2.2.1 mirrors the experimental
methods under `client.experimental.*`. The only removal is
`voice.instructions`, which CodeNomad doesn't use. 2.2.1 doesn't send
the `experimental-media-uri` capability, so media reads stay inline.
- **Schema:** 2.2.0 adds media refs (`MediaRef`,
`Session.Message.MediaUser`, inbox `MediaUserPayload`), `generate`,
`usage-limits` and `Model.Type`. 2.2.1 adds `goal` and `schedule`. The
one removal since 2.1.0 is `SessionEvent.Source` (2.1.4).
- **Plugin:** 2.2.0 adds the `gui/*` SDK (excluded from the host
runtime) and `Host.packageID`. 2.2.1 adds
`SessionIdle`/`SessionIdleBackground`. The event `subscribe` domain
gains an optional `types` filter; CodeNomad's plugins don't subscribe
through it.
- **Typecheck:** the server and UI typecheck with **0 errors** against
the 2.1.4 and 2.2.1 client/schema/plugin declarations, through scratch
`paths` overrides. The pinned 2.1.0 control is also clean.
- **Host modules:** CodeNomad's three daemon-loaded bundles resolve
`@opencode/plugin` (`Plugin`), `/effect` (`Plugin`, `Rpc`, `Location`),
`/promise/adapter` (`fromPromise`), `/rpc` (`Rpc`), `effect` and
`effect/encoding` (`Base64Url`) from the host. `@opencode/schema` and
`@opencode/client` are bundled from the 2.1.0 pins, and
`@opencode/schema/location` imports are type-only. A probe plugin loaded
in an isolated **2.2.1** daemon resolves every one of these modules and
bindings, as on 2.1.4. The host Effect stays **4.0.1**, with the same
lockfile hash.
- **Private native services:** the pending-request reader and Missions
recurrence use keyed native services: `LocationServiceMap`, `Form`,
`Permission`, `Location`, `Job`, `Database`, `Session` and `Bus`. Their
keys are unchanged at v2.2.1, and the members CodeNomad calls are
unchanged. The changes are additive: `Permission.assertNotDenied`,
`Session.*WithRefs`, an `image` Job kind, and
`LocationServiceMap.canonical` normalizing paths.
- **Storage** (migrations from 2.1.4 to 2.2.1): `blob`/`blob_ref`
(always created; written only with `experimental.media_blob`) and
`schedule` are new. `session_pending` is dropped; CodeNomad never reads
it. A `session_v2.allowance` column is added and dropped within 2.2.0.
- The tables CodeNomad reads directly (`session_message`, `session_v2`,
`session_inbox`, `event`, `event_sequence`, `kv`) keep their shape.
- The pruning plugin's `media-blob.ts` already projects `media:<sha256>`
refs.
- The pruning fixture enables `media_blob` explicitly, so the
always-present `blob` table doesn't change its expectation.
- Missions reads `session_inbox` only by count and ID in production
code.
- **Behavior changes checked:**
- **Code Mode:** 2.2.1 moves programs onto one job queue
([#57976](https://github.com/anomalyco/opencode/pull/57976)). The
run-to-completion regression behind the 2.1.2 minimum passes on 2.1.4,
2.2.0 and 2.2.1: `{ total: 2000, beforeAwait: 1000, count: 1000 }`.
- **Session form polling** returns `[]` without booting a cold Location
([#59083](https://github.com/anomalyco/opencode/pull/59083)). Forms are
in memory, so nothing pending is hidden. This matches CodeNomad's
existing-only pending reader.
- **Location keys and `session.create` directories** are canonical on
POSIX too: trailing slash removed, `posix.normalize`
([#59327](https://github.com/anomalyco/opencode/pull/59327)). Windows
already normalized. This is low risk; it was reviewed in source only,
since the location and ownership fixtures run on Windows and the POSIX
certification covers migration, Code Mode and Git-degraded.
- **Location keep-alive:** the changelog line "keep project services
alive … with a 24-hour inactivity cap"
([#57274](https://github.com/anomalyco/opencode/pull/57274)) doesn't
match the shipped tree. That commit was superseded before 2.1.4, and no
cap exists at v2.2.0 or v2.2.1. From 2.1.4 to 2.2.1,
`location-activity.ts` only canonicalizes paths and generalizes Job
kinds. Long-waiting Missions sessions keep their Location as on 2.1.4.
- **Plugin readiness:** each runner step and tool call now waits for
plugin activation
([#51133](https://github.com/anomalyco/opencode/pull/51133)), and
agent/provider lists wait for plugins. Presence leases stay outside the
discovery root, so this adds no reload.
- **Service lifecycle:** registration and config renames are retried on
Windows. The managed service ignores a saved `XDG_STATE_HOME`
([#58815](https://github.com/anomalyco/opencode/pull/58815)); CodeNomad
never sets it. The `OPENCODE_SERVER_USERNAME` change was added and
reverted within 2.2.0. Detached POSIX children are killed when OpenCode
exits; service start uses its own spawn path.
- **2.2.1 opt-ins:**
- schedules, both the API and the agent tool, need
`experimental.schedules`;
- `image_generate` needs `experimental.image_generate`;
- `/goal` runs only when invoked;
- the subagent tool description now invites follow-ups to *running*
subagents, with the same mechanics as 2.1.4.
- **Other changes:** compaction sizing from the provider's count, MCP
malformed-tool tolerance, OAuth refresh coordination
([#54023](https://github.com/anomalyco/opencode/pull/54023)) and
webfetch redirect rules. They touch no consumed contract and were
reviewed in source; of these, the native suites exercise compaction
only.
- **Upstream #52922** (Bus routing before Location fanout) is still
open: keep the discovery and event-relay mitigations.
**Verdict:** no consumed contract changed from 2.1.4 to 2.2.1.
- The **2.1.0 client/plugin pins can stay**.
- The **2.1.2 minimum has no reason to move**.
- 2.2.1 is admitted through the existing contract recognition, and
nothing found blocks recommending it once the native suites pass on it.
- No CodeNomad bug was found.
Bumping the pins is optional. It would bring the 2.2 client's
discard-tool-result-payload option and its "register running sessions
missed while disconnected" fix
([#53012](https://github.com/anomalyco/opencode/pull/53012)). It would
also move the replay reducer, so it belongs in its own PR. The UI and
server already typecheck against 2.2.1.
**Not verified here:**
- the full native suites against 2.2.0/2.2.1 (only the Code Mode
regression and the host-module probe ran);
- the TUI pruning companion under OpenTUI 0.7. It uses only
`Plugin.define`, `ctx.data.session` and `ctx.data.listen`, so the 0.7
renderable changes don't apply, but this wasn't run;
- POSIX canonicalization on a real Linux/macOS runtime;
- the 2.2.1 release notes, which were unpublished at review time.
## Isolated Windows qualification
Base: dev `
|
||
|
|
39c0fa5833
|
chore(opencode): qualify and recommend runtime 2.1.4 (#1126)
## Summary
- Qualify OpenCode **2.1.4** (latest stable, 23 October) with the
existing locked **2.1.0 client/plugin** dependencies, and **recommend**
it.
- Keep the technical **minimum at 2.1.2**: no consumed contract changed,
so the minimum has no new reason to move.
- 2.1.2 and 2.1.3 daemons stay ready and get an optional upgrade offer.
2.1.4 is the `tested` version. Newer and custom labels keep
authenticated contract recognition.
- The reviewed-contract fast path lists the 2.1.2 minimum and the 2.1.4
target.
- The recommended version is updated in the help (all ten locales), both
READMEs, `CONTRIBUTING.md`, `dev-docs/OPENCODE_COMPATIBILITY.md` and the
architecture skill.
## Contract review (v2.1.3 → v2.1.4, 72 commits)
- **Authenticated OpenAPI:** 121 → **124 paths**, 146 → **149
operations**. No operation changed. The changes:
- added `POST /api/experimental/client-mcp/token`;
- added `GET /api/experimental/client-mcp` (WebSocket);
- added `POST /api/debug/heap-dump`;
- `Config.InfoEncoded` gains the opt-in
`experimental.background_compaction`.
The session event (`V2EventEncoded`) and message schemas are unchanged.
None of the new routes is on the instance proxy allowlist, and the proxy
relays WebSockets only for SideCars and previews.
- **Published declarations:**
- the client adds `mcp.client.token` and `debug.heapDump`;
- the schema and plugin changes are type refactors and unused-export
removals, among them `SessionID.descending`, `SessionEvent.Source` and
`PromptInput.FileAttachment.create`; `Session.Message.ID.fromEvent` now
takes any string instead of an event ID. CodeNomad uses none of these,
and every host module its native plugin bundles import
(`@opencode/plugin`, `/effect`, `/promise/adapter`, `/rpc`,
`@opencode/schema/location`, `/session`) still exists.
- **MCP elicitation forms**
([#58184](https://github.com/anomalyco/opencode/pull/58184)): an MCP
server asking for input during a tool call now creates a global-session
Form whose `form.created` event carries the server's location.
CodeNomad's live path requires that location for global Forms and shows
them as a **Project request**. Review found that the live path dropped
the location from the queued Form, so its reply lacked
`x-opencode-directory` and failed for a worktree or subdirectory until a
pending-request rescan. **#1127** fixes that; recovery already kept it.
A native probe (minimal stdio MCP server, a real Code Mode `execute`
call, CodeNomad-style reply) gives:
| Runtime | Form listed for the location | `form.created` carries the
location | Reply completes the tool |
| --- | --- | --- | --- |
| 2.1.3 | yes | **no** | yes |
| 2.1.4 | yes | **yes** | yes (`action: accept`, `channel: stable`) |
On 2.1.3 such a request only appeared after a pending-request rescan; on
2.1.4 it appears live. The probe sends the location header itself, so it
checks the runtime contract; #1127 covers CodeNomad's live reply path.
- **Other changes** are covered by the native suites below:
- compaction (oldest-first shortening, ignored buffers, overflow
detection);
- the agent's model for sessions without one;
- V2 agent files;
- V1 global-session import attribution;
- MCP lifecycle fixes.
- **Live check:** this machine's shared daemon runs 2.1.4, and the
CodeNomad desktop session works through it.
## Isolated Windows qualification
Base: dev `
|
||
|
|
01b20b5b78
|
chore(opencode): qualify and recommend runtime 2.1.3 (#1098)
## Summary
- Qualify OpenCode **2.1.3** (latest stable, 22 October) with the
existing locked **2.1.0 client/plugin** dependencies, and **recommend**
it.
- Keep the technical **minimum at 2.1.2**: nothing CodeNomad consumes
changed, so the minimum has no new reason to move.
- A 2.1.2 daemon stays ready and gets an optional upgrade offer. 2.1.3
is the `tested` version. Newer and custom labels keep authenticated
contract recognition.
- The reviewed-contract fast path lists 2.1.3 beside the 2.1.2 minimum.
- The recommended version is updated in the help (all ten locales), both
READMEs, `dev-docs/OPENCODE_COMPATIBILITY.md` and the architecture
skill.
## Contract review (v2.1.2 → v2.1.3, 66 commits)
- **Authenticated OpenAPI:** 119 → **121 paths**, 144 → **146
operations**. Every consumed operation is unchanged. The only changes:
- added `GET /api/experimental/voice/models`;
- added `POST /api/experimental/voice/session/{sessionID}/instructions`;
- an optional hosted `session.id` in the `POST
/api/experimental/voice/session` response.
None of these is on the instance proxy allowlist, so they stay closed.
- **Published declarations:** the client adds only `voice.models` /
`voice.instructions`. The schema changes only typing (agent `color`
decoding, `Durable` as a tagged union). The plugin is unchanged.
- **Windows managed services** move their default port from **45278 to
28894** ([#57428](https://github.com/anomalyco/opencode/pull/57428)).
CodeNomad discovers the daemon through the selected CLI's `service
status` and the service registration, and assumes no port.
- Live check: this machine's shared daemon was upgraded to 2.1.3 and
restarted on 28894, and the running CodeNomad desktop kept working
through it.
- **Core:** mostly refactors, plus behaviour fixes that the native
suites below exercise:
- compaction summary output limit;
- `keepID` validated as a message ID;
- MCP media kept out of attachments;
- only changed instruction entries resent;
- relative-directory V1 migration;
- legacy `apply_patch` permission mapped to `edit`.
## Isolated Windows qualification
Base: dev `
|
||
|
|
1dabb5110f
|
docs(help): bring the user guide back in line with the current app (#1079)
docs(help): bring the user guide back in line with the current app The help was written on 2026-10-14 and about forty user-visible changes merged since without touching it, so several pages described controls that no longer exist: Missions still listed four playbooks and a Save step for preferences that now save on each change, the depth editor kept its old names, notifications still had their former switches, and voice input pointed to a microphone button that is not in the composer. Every English page was re-checked claim by claim against the current labels (English UI messages) and behaviour, then the nine translations were updated to match, using each locale's own UI labels. Notable corrections: Missions (Compare two models, autosaving defaults with Apply to / Global / Reset, Subsession nesting depth, prepared hand-offs, retired-task interrupts, the named causes of "Mission Control is unavailable", standalone server support); conversations and history (reasoning/tool durations, token lines adding up the cleanup selection, presets including Nothing, timeline markers following Message content, in-place reveal of long text, Open in session, focus after send, Queue message / Steer now, Retrying); settings (notification routing table and defaults, Stats, Mode, info tips, Server setting badge, localized native menus); shortcuts (72 actions, Clear shortcut, Ctrl/Cmd+K); voice (More actions entries, Save status); files (live Workspace refresh, Show 200 more); OpenCode, install, server and updates (2.1.1 recommended, OpenCode 2 beside an older installation, version card first, private loopback listener for Missions, preview releases offered once all builds are published); providers, integrations, browser, SideCars, desktop and remote pages. Translations also repaired older drift, mainly the project-tab closing passages. The Chat settings table header (Default state, its title, item column, the thinking row and its accessible label) was still English in eight locales; it is now translated so the help can cite what users see. AGENTS.md now asks every PR changing user-visible behavior to update the affected help pages in the same PR, since CI validates structure and links but not whether the text still matches the UI; it also corrects the needs-input notification default. USER_HELP.md no longer claims native menus stay English. Validation: npm run test:help (all ten locales, 25 pages, heading ids unchanged), a full help build, and the i18n and transcript-visibility unit tests. |
||
|
|
f314123dd1
|
fix(opencode): qualify and require 2.1.2 for correct Code Mode execution (#1078)
Raise the approved external runtime minimum and recommendation to 2.1.2 after reproducing incorrect native Code Mode job ordering on 2.1.0/2.1.1. Keep the independently qualified 2.1.0 client/plugin build pins and preserve bounded contract recognition for custom/future runtimes. Add the real isolated execute regression to the minimum/latest compatibility matrix, align supported installer fixtures without weakening assertions, and update setup/help in all ten locales. Two author-side review passes found no blockers; the final focused set passes 93/93 and native Code Mode passes. Qualification includes builds/typechecks, UI/browser, native pruning/Missions/recurrence, migrations and isolated installation/upgrade. Record the broad server shutdown timeout and its two unchanged isolated passes precisely. Admin merge explicitly authorized by the maintainer without waiting for CI. |
||
|
|
d6a890fba7
|
chore(opencode): qualify 2.1.0 and adopt its native contracts (#1029)
Adopt the OpenCode 2.1 native replay and compaction contracts, align client/plugin pins and set minimum and recommended runtime to 2.1.0. Preserve authenticated contract recognition for future/custom runtimes and explicit installation/restart boundaries. Preserve historical conversations through official projection-based pruning revisions and independently checked migrations from 2.0.3, beta-19271 and 2.0.32. Retain ownership, execution claims, stale-selection checks and transaction fences. Update setup, help and qualification evidence. Isolated Windows native qualification and integration checks cover pruning UI, historical reimport, Compare/Wayfinder, recurring Missions, builds and typechecks. Document broad-suite limitations and outstanding platform/package/mobile acceptance; this merge does not publish CodeNomad 1.0.0. |
||
|
|
c0d53f13d4
|
docs(help): multilingual help site with in-app Help menu and palette entry (#859)
## Summary A complete public CodeNomad help site in the app's ten languages, published on GitHub Pages (https://neuralnomadsai.github.io/CodeNomad/) and opened from the app. - **Content:** 25 pages in 8 sections (Start, Workflows, OpenCode setup, Remote access, Customize, Extensions, Desktop, Help), written for OpenCode power users and covering the current version only. It includes everything user-relevant from `README.md`, `packages/server/README.md` (server, network, auth, TLS, Remote Control) and the user-facing dev-docs, with flags, defaults, labels and safety boundaries checked against source. - **Languages:** en, fr, de, es, he (RTL), ja, ne, ru, tr, zh-Hans. Interface labels reuse each locale's own app strings; native desktop menu names, code, commands, flags, paths and anchors stay unchanged. - **Site:** `scripts/build-help.mjs` renders `docs/help/<locale>/<slug>.md` with translated chrome (`docs/help/i18n/`), stable `{#id}` anchors identical across locales, same-article language links with hreflang, a root language chooser, and a first-party offline per-locale search (Ctrl/⌘+K, substring matching for CJK, Devanagari and Hebrew, hidden without JS). No analytics or remote resources. - **Validation:** `npm run test:help` fails on any missing page or string, heading drift, broken link/anchor/asset or invalid search target. `.github/workflows/help-pages.yml` validates PRs and deploys only from `dev`. - **App entry points:** one `open-help` command for the palette and a new **CodeNomad Help** item at the top of the Electron and Tauri Help menus. It opens the help in the invoking window's UI language through the existing external opener, falls back to the root URL for windows without the handler, and reports failures without replay. - Documents the strict boolean environment-variable rule from #959 and the updater entry points from #960. ## Review Delivered as a CodeNomad mission with independent review loops, each to zero findings: - English content audit (5 passes, 14 fixes) and technical gatekeeper (2 passes) before translation. - After translation: QA, UX review, and a final multilingual gatekeeper (35 translation/label findings fixed, then verified), plus a visual fix for the search focus ring and a verified sync with #960. ## Validation - `npm run test:help`: 9/9 (25 pages × 10 locales, strict, including negative tests); `npm run build:help`: 250 pages. - `node scripts/test-help-browser.mjs`: 44/44; Playwright: 500 page visits at 390 and 1280 px, all locales, no overflow, no external requests. - UI help-command and desktop-updates browser tests 19/19; help URL unit tests; Electron menu tests; UI and Electron typechecks; Tauri `cargo test` 272/272. |