diff --git a/.opencode/skills/codenomad-architecture-guide/SKILL.md b/.opencode/skills/codenomad-architecture-guide/SKILL.md index cabcb7667..f70346934 100644 --- a/.opencode/skills/codenomad-architecture-guide/SKILL.md +++ b/.opencode/skills/codenomad-architecture-guide/SKILL.md @@ -18,7 +18,7 @@ description: | - Runtime requirements live in `opencode/runtime-support.ts`; each blocking requirement needs demonstrated API/behavior evidence. Distinguish technically incompatible, recommended/tested and unverified versions. Setup uses bundled Node/npm and a versioned user prefix; shared-daemon restart is explicit and uses the existing native-parent launch bridge. Retire obsolete wire translations while retaining current identity/authority checks. See `dev-docs/OPENCODE_V2_POST_BETA.md` for precise retirement boundaries and validation evidence. -- Server and UI pin the official `@opencode/client@2.0.20` together; the pruning plugin pins `@opencode/plugin@2.0.20`. Review official V2 docs, installed declarations, generated wire paths and native integration tests when upgrading. Qualify against the latest published stable runtime, but never infer the minimum from that version or from the dependency pin. Record technical minimum requirements and tested scenarios in PR/CI logs and update `dev-docs/OPENCODE_V2_COMPATIBILITY.md` in place rather than adding per-version reports. The runtime CLI is managed independently. +- Server and UI pin the official `@opencode/client@2.0.21` together; the pruning plugin pins `@opencode/plugin@2.0.21`. Review official V2 docs, installed declarations, generated wire paths and native integration tests when upgrading. Qualify against the latest published stable runtime, but never infer the minimum from that version or from the dependency pin. Record technical minimum requirements and tested scenarios in PR/CI logs and update `dev-docs/OPENCODE_V2_COMPATIBILITY.md` in place rather than adding per-version reports. The runtime CLI is managed independently. - Do not use `@opencode-ai/sdk`, `@opencode-ai/sdk/v2/client`, or `createOpencodeClient()`; follow installed `@opencode/client` declarations. - There is no legacy `packages/opencode-plugin/`. Do not restore the V1 compatibility runtime or add general plugin extension points. The narrow integrations are the bundled `codenomad.automation` plugin and bundled session-pruning RPC; see `dev-docs/DEVELOPER_MODE.md`, `dev-docs/BROWSER_AUTOMATION.md` and `dev-docs/SESSION_PRUNING_RPC.md`. All automation tools follow backend presence without a Developer Mode gate, sharing the authenticated native transport and execution-time session/window fences. - The server uses the selected host or WSL CLI's official `service status`, `service start`, and `service get password` lifecycle to connect to one externally owned global OpenCode daemon. It owns no private port/database/registration/PID and never stops the daemon on backend shutdown. WSL requires Windows localhost forwarding and uses no cross-namespace PID operations. diff --git a/.opencode/skills/codenomad-architecture-guide/references/architecture-overview.md b/.opencode/skills/codenomad-architecture-guide/references/architecture-overview.md index 4d3db075c..c269dcc8e 100644 --- a/.opencode/skills/codenomad-architecture-guide/references/architecture-overview.md +++ b/.opencode/skills/codenomad-architecture-guide/references/architecture-overview.md @@ -20,7 +20,7 @@ Client-state V3 is a per-window envelope over the V2 content-addressed partition | Owner | Responsibilities | Main paths | |---|---|---| -| OpenCode V2 | Sessions, messages, permissions, Forms, files, session Shell/instructions, background Shells, interactive PTYs | pinned stable `@opencode/client@2.0.20` contract across server and UI | +| OpenCode V2 | Sessions, messages, permissions, Forms, files, session Shell/instructions, background Shells, interactive PTYs | pinned stable `@opencode/client@2.0.21` contract across server and UI | | CodeNomad server | Shared service lifecycle, locations, proxy authorization, Git mutations, Yolo, auth, storage, speech, SSE multiplexing, Developer Mode bridge | `packages/server/src/` | | CodeNomad UI | Generated Promise clients, state reconciliation, interaction and rendering | `packages/ui/src/` | | Desktop hosts | Start CodeNomad and provide native OS integration | `packages/electron-app/`, `packages/tauri-app/` | diff --git a/.opencode/skills/codenomad-architecture-guide/references/sdk-api-reference.md b/.opencode/skills/codenomad-architecture-guide/references/sdk-api-reference.md index 59b8e1cbc..ed0261088 100644 --- a/.opencode/skills/codenomad-architecture-guide/references/sdk-api-reference.md +++ b/.opencode/skills/codenomad-architecture-guide/references/sdk-api-reference.md @@ -2,9 +2,9 @@ ## Package -CodeNomad server and UI pin `@opencode/client@2.0.20`. The runtime CLI is managed independently; startup validates authenticated loopback `/api/status`, then `/api/health`, then `/api/info`, advancing only on HTTP 404 with the same endpoint, credentials and deadline. Each response has its own validated schema and a 64 KiB bound. The shared transport maps canonical `server.info()` to the discovered route. Older services do not expose `paths.tmp`; consumers may use only the metadata actually provided. Discovery does not prove compatibility for other APIs. Review official V2 docs, installed declarations, generated routes and native regression tests together when upgrading. +CodeNomad server and UI pin `@opencode/client@2.0.21`. The runtime CLI is managed independently; startup validates authenticated loopback `/api/status`, then `/api/health`, then `/api/info`, advancing only on HTTP 404 with the same endpoint, credentials and deadline. Each response has its own validated schema and a 64 KiB bound. The shared transport maps canonical `server.info()` to the discovered route. Older services do not expose `paths.tmp`; consumers may use only the metadata actually provided. Discovery does not prove compatibility for other APIs. Review official V2 docs, installed declarations, generated routes and native regression tests together when upgrading. -Runtime requirements live in `packages/server/src/opencode/runtime-support.ts`: minimum 2.0.7 for native step-start timestamps, independently of recommended/tested 2.0.20. The shared connection binds authenticated runtime identity, the canonical client and forwarding transport. Admission precedes functional requests/plugin provisioning; unlisted versions, including custom/prerelease/future labels, require authenticated bounded API recognition. Legacy request/response/event and live location translations are retired. Never add operation-specific retry fallbacks in UI stores or Yolo. See `dev-docs/OPENCODE_V2_POST_BETA.md` for precise boundaries, setup and migration evidence. +Runtime requirements live in `packages/server/src/opencode/runtime-support.ts`: minimum 2.0.7 for native step-start timestamps, independently of recommended/tested 2.0.21. The shared connection binds authenticated runtime identity, the canonical client and forwarding transport. Admission precedes functional requests/plugin provisioning; unlisted versions, including custom/prerelease/future labels, require authenticated bounded API recognition. Legacy request/response/event and live location translations are retired. Never add operation-specific retry fallbacks in UI stores or Yolo. See `dev-docs/OPENCODE_V2_POST_BETA.md` for precise boundaries, setup and migration evidence. The Promise client preserves the full `baseUrl` path prefix. Forward its generated URL unchanged through `createInstanceFetch`; remove the proxy prefix only when classifying reads for scheduling. Declared API errors are `Error` instances retaining their native `_tag`/data fields. Client errors retain structured `reason`/`cause`; 2.0.16 adds status, content type or cause detail to `message`. Classify by structured fields rather than exact message text. diff --git a/.opencode/skills/codenomad-architecture-guide/references/sdk-critical-behaviors.md b/.opencode/skills/codenomad-architecture-guide/references/sdk-critical-behaviors.md index b51f4cdb6..0a9aab076 100644 --- a/.opencode/skills/codenomad-architecture-guide/references/sdk-critical-behaviors.md +++ b/.opencode/skills/codenomad-architecture-guide/references/sdk-critical-behaviors.md @@ -2,12 +2,12 @@ ## Contract -- Server and UI pin `@opencode/client@2.0.20`. Manage the runtime CLI independently: startup checks authenticated loopback `/api/status`, then `/api/health`, then `/api/info`, advancing only on HTTP 404. All probes share the endpoint, credentials, 64 KiB response bound and absolute deadline; authentication, transport and malformed response failures do not trigger fallback. The shared transport maps canonical `server.info()` to the discovered route. Older services do not provide `paths.tmp`; never infer that path from the backend host. Discovery alone does not prove client/API compatibility. Review documentation, installed declarations and proxy/API parity whenever the client contract changes. +- Server and UI pin `@opencode/client@2.0.21`. Manage the runtime CLI independently: startup checks authenticated loopback `/api/status`, then `/api/health`, then `/api/info`, advancing only on HTTP 404. All probes share the endpoint, credentials, 64 KiB response bound and absolute deadline; authentication, transport and malformed response failures do not trigger fallback. The shared transport maps canonical `server.info()` to the discovered route. Older services do not provide `paths.tmp`; never infer that path from the backend host. Discovery alone does not prove client/API compatibility. Review documentation, installed declarations and proxy/API parity whenever the client contract changes. - The package root is the generated zero-Effect Promise client. Use installed declarations, not current public `@opencode-ai/sdk` examples. - Native routes are `/api/*`; CodeNomad exposes them only through the authorized `/workspaces/:id/instance` proxy. - That proxy is an explicit method/path allowlist. Future upstream APIs are not exposed automatically. - Proxy authorization and forwarding share one acquired connection. A stale generation must be rejected at actual HTTP dispatch, including after asynchronous body preparation; late streams cannot invalidate a replacement connection. -- The technical minimum is 2.0.7: native `session.step.started.data.started` is consumed directly after removing its older fallback. Recommendation/qualification 2.0.20 is independent. Unknown version labels, prereleases and future majors require bounded authenticated API recognition, including session environment support; they are not rejected solely by label. Legacy HTTP inbox and event conversions are retired. Native `session.inbox.enqueued` still has a distinct shape: its timestamp belongs to event metadata, not an HTTP inbox record. +- The technical minimum is 2.0.7: native `session.step.started.data.started` is consumed directly after removing its older fallback. Recommendation/qualification 2.0.21 is independent. Unknown version labels, prereleases and future majors require bounded authenticated API recognition, including session environment support; they are not rejected solely by label. Legacy HTTP inbox and event conversions are retired. Native `session.inbox.enqueued` still has a distinct shape: its timestamp belongs to event metadata, not an HTTP inbox record. - Never retry a write using another contract after a 400/404/transport failure. Keep the setup/recovery path distinct from functional transport and never replay prompts. ## Location Is Authority diff --git a/.opencode/skills/codenomad-architecture-guide/references/sdk-integration-patterns.md b/.opencode/skills/codenomad-architecture-guide/references/sdk-integration-patterns.md index c40f78e76..3b48a6bc3 100644 --- a/.opencode/skills/codenomad-architecture-guide/references/sdk-integration-patterns.md +++ b/.opencode/skills/codenomad-architecture-guide/references/sdk-integration-patterns.md @@ -10,7 +10,7 @@ OpenCode owns standard state/database. Allowed configured environment variables Workspace creation calls `client.location.get({ location: { directory } })` and records the returned directory. Its `project` field supplies project metadata. Public locations have no workspace selector. Explicit Stop Workspace calls `client.debug.location.evict` before removing the logical workspace. Ordinary tab/window close only detaches local UI and never evicts. -The technical minimum is 2.0.7 for the native step-start timestamp, with 2.0.20 independently recommended/tested; old request/response/event and live location translations are retired. Preserve historical `workspaceID` validation internally: obsolete public selectors must be rejected rather than erased from imports, cursors, pending Forms or move rollback. Native historical migrations collapse workspace selectors to local directory scope while preserving session IDs. See `dev-docs/OPENCODE_V2_COMPATIBILITY.md` for current qualification and `dev-docs/OPENCODE_V2_POST_BETA.md` for the transition record. +The technical minimum is 2.0.7 for the native step-start timestamp, with 2.0.21 independently recommended/tested; old request/response/event and live location translations are retired. Preserve historical `workspaceID` validation internally: obsolete public selectors must be rejected rather than erased from imports, cursors, pending Forms or move rollback. Native historical migrations collapse workspace selectors to local directory scope while preserving session IDs. See `dev-docs/OPENCODE_V2_COMPATIBILITY.md` for current qualification and `dev-docs/OPENCODE_V2_POST_BETA.md` for the transition record. The instance proxy is method/path allowlisted, rejects unowned paths, `directory`, `location.directory`, and `location[directory]` values, and verifies session location before forwarding. Keep this check at the server trust boundary; new upstream routes require explicit review. diff --git a/README.md b/README.md index 10f1efe19..422dc6014 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ npx @neuralnomads/codenomad-dev --password "your-password" --launch ## OpenCode V2 and upgrading from 0.19.x -CodeNomad **0.20.0 requires OpenCode V2**: **2.0.7 minimum**, with **2.0.20 recommended and qualified for this release**. OpenCode V1 and the former V2 beta protocol are not supported. The current requirements are maintained in [`runtime-support.ts`](packages/server/src/opencode/runtime-support.ts). +CodeNomad **0.20.0 requires OpenCode V2**: **2.0.7 minimum**, with **2.0.21 recommended and qualified for this release**. OpenCode V1 and the former V2 beta protocol are not supported. The current requirements are maintained in [`runtime-support.ts`](packages/server/src/opencode/runtime-support.ts). - **One shared OpenCode service** owns sessions and messages. Closing a CodeNomad tab, window, or backend leaves that service running. Desktop tabs, drafts, and layout are restored separately for each window. - **Use an existing CLI or install from CodeNomad.** Executables on `PATH` are preferred; the setup screen also supports a selected executable and a shared user npm installation. The former private CodeNomad OpenCode installation is no longer used. @@ -147,7 +147,7 @@ Add SideCar as: ## Requirements -- **[OpenCode V2](https://opencode.ai/v2/docs/)** — 2.0.7 minimum; 2.0.20 recommended for CodeNomad 0.20.0. Install/select it through desktop setup or provide a compatible CLI on the server host. +- **[OpenCode V2](https://opencode.ai/v2/docs/)** — 2.0.7 minimum; 2.0.21 recommended for CodeNomad 0.20.0. Install/select it through desktop setup or provide a compatible CLI on the server host. - **[Git](https://git-scm.com/downloads)** — a prerequisite for full functionality (repository identity, Git operations and worktrees). Git must be executable in the CodeNomad backend's `PATH`; it is not bundled with the desktop installers. - **Node.js and npm** — required for the standalone npm server and source builds, bundled with desktop releases. Use **Node.js 24 LTS**; development and release builds use the version in [`.node-version`](.node-version) (currently 24.20.0). diff --git a/dev-docs/OPENCODE_V2_COMPATIBILITY.md b/dev-docs/OPENCODE_V2_COMPATIBILITY.md index 4d486dc3f..4c31a9a67 100644 --- a/dev-docs/OPENCODE_V2_COMPATIBILITY.md +++ b/dev-docs/OPENCODE_V2_COMPATIBILITY.md @@ -15,7 +15,7 @@ runtimes. Keep detailed results in the change's PR and CI logs, not in per-versi reports. Update this reference in place. PR #696's corrected technical minimum is **2.0.7**, when native step-start events -gain the `data.started` field consumed by the current Solid reducer. **2.0.20** +gain the `data.started` field consumed by the current Solid reducer. **2.0.21** is the recommended release-tested target, not the minimum. Unlisted versions, including prereleases/custom labels/future majors, undergo authenticated contract recognition rather than being refused solely for their label. Missing canonical @@ -47,7 +47,7 @@ Isolated HTTP/generated-client and rendered Solid fixtures cover these boundarie `node scripts/test-provider-usage-native.mjs ` additionally exercises the production quota adapter against a fresh native daemon/database with synthetic OAuth/key credentials and mocked quota HTTP only. It passed on Windows -with 2.0.20: active-account selection and `metadata.accountID`, warm-cache revocation +with 2.0.20 and 2.0.21: active-account selection and `metadata.accountID`, warm-cache revocation after switching to a key, and recovery despite a stale legacy file. This is not a real WSL or live ChatGPT quota test; no real credentials or shared daemon are used. @@ -247,7 +247,7 @@ before the native fixture. That run changes import order, not the assertions or runtime; it provides acceptance coverage without proving the ordinary launcher is reliable. Keep both outcomes visible in the PR. -### Current stable target: 2.0.20 +### Previous stable target: 2.0.20 The recommendation and synchronized server/UI client and plugin pins advance to **2.0.20**; the demonstrated timestamp-based minimum remains **2.0.7**. Authenticated @@ -275,6 +275,34 @@ documented above. Historical migrations, standalone plugin acceptance and isolat npm upgrade pass; upgrade preserves the running 2.0.15 daemon's version and PID. Detailed test counts, environment and final review/CI outcomes belong in the PR. +### Current stable target: 2.0.21 + +The recommendation and synchronized server/UI client and plugin pins advance to +**2.0.21**; the global minimum remains **2.0.7**, and Codex Usage's feature-local +credential-list requirement remains **2.0.20**. Authenticated native OpenAPI keeps +116 paths: only form cancellation changes, with an optional `message` query and +optional `message` in cancelled `Form.State`. Existing cancellation without a +message remains supported. A synthetic native fixture verifies session/global +cancellation both ways, including exact preservation of URL-sensitive text. + +Published declarations change in two client files, one protocol file and one +schema file; all 60 plugin declaration files are unchanged. No new consumed API +or required field justifies an adapter or higher minimum. Plugin optional OpenTUI +peer floors advance to 0.5.14; CodeNomad does not install these terminal peers. +The release also fixes provider context-overflow classification, passthrough and +prompt-cache behavior, avoids reinjecting ancestor instructions, adds namespaced +session identity headers to provider requests, and makes native browser tools +conditional on desktop attachment. CodeNomad's own automation acceptance passes. + +Seven native suites pass on both 2.0.7 and 2.0.21 with the new pins. The native +Codex Usage fixture also passes on 2.0.21 with synthetic credentials and mocked +quota HTTP. Ordinary-launcher native/UI acceptance, standalone plugin acceptance, +historical migrations and isolated npm upgrade pass. Upgrade leaves the running +2.0.15 daemon and PID unchanged. The full server run has one Windows Git-fixture +cleanup `EPERM`; its unchanged focused rerun passes. Retain this failure and the +historical intermittent Vite/import limitation rather than claiming either fixed. +Detailed counts, review and CI outcomes belong in the PR. + The audit and implementation record below is historical context, not a runtime qualification matrix to maintain. diff --git a/package-lock.json b/package-lock.json index 475b58ace..a549b0e90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4843,14 +4843,14 @@ } }, "node_modules/@opencode/ai": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/@opencode/ai/-/ai-2.0.20.tgz", - "integrity": "sha512-OgLbrorEgk38TCZIzoMkcUbe2DiARYPWD4Kp5pInlrI/s1aAAm38GydYDYEJHgkCd5FBerv1dKWGefpyMjTUMg==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@opencode/ai/-/ai-2.0.21.tgz", + "integrity": "sha512-eB4M0O44VoX075Kv+vIVxIpiKSrfjSXpNaeBSjtPgZdhZCjKN5CxjJXtyPbhrDxvmDf0PxLcvjGNKQBRMkZ0fw==", "dev": true, "license": "MIT", "dependencies": { "@aws-sdk/credential-providers": "3.1057.0", - "@opencode/schema": "2.0.20", + "@opencode/schema": "2.0.21", "@smithy/eventstream-codec": "4.2.14", "@smithy/util-utf8": "4.2.2", "aws4fetch": "1.0.20", @@ -4859,13 +4859,13 @@ } }, "node_modules/@opencode/client": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/@opencode/client/-/client-2.0.20.tgz", - "integrity": "sha512-gTwZCVv7tNwOLPZXZyUDF9tZnEsKuchkjXv1l98I+sTWJJNRqsEM5wnvjlOJEiwiqWZTeBk1UIk2QpR5PDGzwA==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@opencode/client/-/client-2.0.21.tgz", + "integrity": "sha512-cX9sj9qpaTlkVfdaeLCFeV43+1mcSHVhvgjkVLCYyfQJj0MmBGgx/x9AM/GHVZDEX6T2mUljn0Qh5XhFM9CgrQ==", "license": "MIT", "dependencies": { - "@opencode/protocol": "2.0.20", - "@opencode/schema": "2.0.20" + "@opencode/protocol": "2.0.21", + "@opencode/schema": "2.0.21" }, "peerDependencies": { "effect": "4.0.0-rc.112", @@ -4881,26 +4881,26 @@ } }, "node_modules/@opencode/plugin": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/@opencode/plugin/-/plugin-2.0.20.tgz", - "integrity": "sha512-RMJQH3cgOw7hztUUTnnv1WJ3veKYV2oxkasfEYEdzVIVvIK3LYwYZqrnlZS4VLRNOkyCeypfPDKrt0iYNPmPUw==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@opencode/plugin/-/plugin-2.0.21.tgz", + "integrity": "sha512-ZLagbklGyYPg77GvK//ir3LaNXBsZQENU8APCnaT4elsBk7YzoVt8stR6+b4wH7Sfadw76cWSaNiWgDo2QOSHA==", "dev": true, "license": "MIT", "dependencies": { "@ai-sdk/provider": "3.0.8", - "@opencode/ai": "2.0.20", - "@opencode/client": "2.0.20", - "@opencode/protocol": "2.0.20", - "@opencode/schema": "2.0.20", - "@opencode/util": "2.0.20", + "@opencode/ai": "2.0.21", + "@opencode/client": "2.0.21", + "@opencode/protocol": "2.0.21", + "@opencode/schema": "2.0.21", + "@opencode/util": "2.0.21", "@standard-schema/spec": "1.1.0", "effect": "4.0.0-rc.112", "zod": "4.1.8" }, "peerDependencies": { - "@opencode/theme": "2.0.20", - "@opentui/core": ">=0.5.12", - "@opentui/solid": ">=0.5.12", + "@opencode/theme": "2.0.21", + "@opentui/core": ">=0.5.14", + "@opentui/solid": ">=0.5.14", "solid-js": ">=1.9.0" }, "peerDependenciesMeta": { @@ -4929,19 +4929,19 @@ } }, "node_modules/@opencode/protocol": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/@opencode/protocol/-/protocol-2.0.20.tgz", - "integrity": "sha512-5tN25fwpc/2blCFpZgl9fkU92diHAVuk88TGxHH1LO27Ib/lJFWBxTvMUImrCmbyBv70f8W8MMkjkFhA5ryWVA==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@opencode/protocol/-/protocol-2.0.21.tgz", + "integrity": "sha512-KvcpCPpIXPMkJaffUFwLxUAZwf6SiNf/8qFW/ZR7LEHFBcnmzyl7hPk5QthAHmnTRoR+dU2U/WMakj06ePRPyg==", "license": "MIT", "dependencies": { - "@opencode/schema": "2.0.20", + "@opencode/schema": "2.0.21", "effect": "4.0.0-rc.112" } }, "node_modules/@opencode/schema": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/@opencode/schema/-/schema-2.0.20.tgz", - "integrity": "sha512-rutVd9rYHa/WTZA3glLQY3pbMN/SZ6Q4yd8XrpRtbGN+2u3fukz4mTXy8QQY1mVSabdX5jYTmzPi0QJMpmGSUQ==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@opencode/schema/-/schema-2.0.21.tgz", + "integrity": "sha512-HMIU9sCNOvbMWQeslxbTtCLfvhMyar40+VHkZq9hNjXTaPWJrGxSzbuHJQhKzeOeDaiP7t1zllUDHTxTA/5SOw==", "license": "MIT", "dependencies": { "@standard-schema/spec": "1.1.0", @@ -4949,9 +4949,9 @@ } }, "node_modules/@opencode/util": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/@opencode/util/-/util-2.0.20.tgz", - "integrity": "sha512-+Vjkjaz7EXXp5AkIVu1ETC4TcxTa+jLtdnzCKVZQf3OuH0Z0MllbcaYaJj/ks1m8T4F7OemITM5bFWr7vBllcQ==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@opencode/util/-/util-2.0.21.tgz", + "integrity": "sha512-wQaa4Q19zbK+B76Pzf2NV3eE8orwWw7IDlBi/Y4WpUaHwaaF+fCQGQxkByyOeWmSy38IQEX93c8RyLPB+WWjog==", "dev": true, "license": "MIT", "dependencies": { @@ -18680,7 +18680,7 @@ "@fastify/cors": "^8.5.0", "@fastify/reply-from": "^9.8.0", "@fastify/static": "^7.0.4", - "@opencode/client": "2.0.20", + "@opencode/client": "2.0.21", "commander": "^12.1.0", "fastify": "^4.28.1", "fuzzysort": "^2.0.4", @@ -18697,7 +18697,7 @@ "codenomad": "dist/bin.js" }, "devDependencies": { - "@opencode/plugin": "2.0.20", + "@opencode/plugin": "2.0.21", "@types/node-forge": "^1.3.14", "@types/yauzl": "^2.10.0", "cross-env": "^7.0.3", @@ -18737,7 +18737,7 @@ "dependencies": { "@git-diff-view/solid": "^0.0.8", "@kobalte/core": "0.13.11", - "@opencode/client": "2.0.20", + "@opencode/client": "2.0.21", "@solidjs/router": "^0.13.0", "@suid/icons-material": "^0.9.0", "@suid/material": "^0.19.0", diff --git a/packages/server/package.json b/packages/server/package.json index e91985a27..56c04dab7 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -30,7 +30,7 @@ "@fastify/cors": "^8.5.0", "@fastify/reply-from": "^9.8.0", "@fastify/static": "^7.0.4", - "@opencode/client": "2.0.20", + "@opencode/client": "2.0.21", "commander": "^12.1.0", "fastify": "^4.28.1", "fuzzysort": "^2.0.4", @@ -45,7 +45,7 @@ }, "devDependencies": { "esbuild": "^0.25.12", - "@opencode/plugin": "2.0.20", + "@opencode/plugin": "2.0.21", "@types/node-forge": "^1.3.14", "@types/yauzl": "^2.10.0", "cross-env": "^7.0.3", diff --git a/packages/server/src/opencode-update/service.test.ts b/packages/server/src/opencode-update/service.test.ts index 9e936202d..cebfaa3a7 100644 --- a/packages/server/src/opencode-update/service.test.ts +++ b/packages/server/src/opencode-update/service.test.ts @@ -277,29 +277,29 @@ test("beta version comparison remains numeric", () => { assert.equal(compareOpenCodeVersionStrings("0.0.0-beta-10000", "0.0.0-beta-9999") > 0, true) }) -test("2.0.7 through 2.0.20 remain usable; recommendation only offers an optional update", async () => { - for (const version of ["2.0.7", "2.0.8", "2.0.9", "2.0.10", "2.0.11", "2.0.12", "2.0.13", "2.0.14", "2.0.15", "2.0.16", "2.0.17", "2.0.18", "2.0.19", "2.0.20"]) { +test("2.0.7 through 2.0.21 remain usable; recommendation only offers an optional update", async () => { + for (const version of ["2.0.7", "2.0.8", "2.0.9", "2.0.10", "2.0.11", "2.0.12", "2.0.13", "2.0.14", "2.0.15", "2.0.16", "2.0.17", "2.0.18", "2.0.19", "2.0.20", "2.0.21"]) { const endpoint: Endpoint = { url: "http://127.0.0.1:9876" } rememberRuntime(endpoint, { version, pid: 123, discovery: "info" }) const service = new OpenCodeUpdateService(deps({ - probeBinary: () => ({ valid: true, version }), resolveLatestVersion: async () => "2.0.20", + probeBinary: () => ({ valid: true, version }), resolveLatestVersion: async () => "2.0.21", lifecycle: async () => ({ discover: async () => endpoint, ensure: async () => { throw new Error("must retain daemon") } }), })) const status = await service.start() assert.equal(status.minimumVersion, "2.0.7") - assert.equal(status.recommendedVersion, "2.0.20") + assert.equal(status.recommendedVersion, "2.0.21") assert.equal(status.state, "ready") assert.equal(status.serviceState, "ready") - assert.equal(status.versionAssessment, version === "2.0.20" ? "tested" : "untested", "only the current recommendation is release-qualified") + assert.equal(status.versionAssessment, version === "2.0.21" ? "tested" : "untested", "only the current recommendation is release-qualified") assert.equal(status.incompatibilityReason, undefined) - assert.equal(status.canUpgrade, version !== "2.0.20") + assert.equal(status.canUpgrade, version !== "2.0.21") assert.equal(status.canRestart, false) } }) test("a current daemon remains usable through an older selected discovery CLI", async () => { const endpoint: Endpoint = { url: "http://127.0.0.1:9876" } - rememberRuntime(endpoint, { version: "2.0.20", pid: 123, discovery: "info" }) + rememberRuntime(endpoint, { version: "2.0.21", pid: 123, discovery: "info" }) const service = new OpenCodeUpdateService(deps({ probeBinary: () => ({ valid: true, version: "2.0.3" }), lifecycle: async () => ({ discover: async () => endpoint, ensure: async () => { throw new Error("must retain daemon") } }), diff --git a/packages/server/src/opencode/runtime-support.test.ts b/packages/server/src/opencode/runtime-support.test.ts index b2dfa20b2..5a71060fe 100644 --- a/packages/server/src/opencode/runtime-support.test.ts +++ b/packages/server/src/opencode/runtime-support.test.ts @@ -7,8 +7,8 @@ import { OpenCodeSharedService } from "../workspaces/opencode-service" test("native timestamp minimum is distinct from recommendation and unfamiliar version labels", () => { assert.equal(MINIMUM_OPENCODE_VERSION, "2.0.7") - assert.equal(RECOMMENDED_OPENCODE_VERSION, "2.0.20") - for (const version of ["2.0.7", "2.0.8", "2.0.9", "2.0.10", "2.0.11", "2.0.12", "2.0.13", "2.0.14", "2.0.15", "2.0.16", "2.0.17", "2.0.18", "2.0.19", "2.0.20", "2.1.0", "2.0.20-dev.1", "3.0.0", "custom-build"]) { + assert.equal(RECOMMENDED_OPENCODE_VERSION, "2.0.21") + for (const version of ["2.0.7", "2.0.8", "2.0.9", "2.0.10", "2.0.11", "2.0.12", "2.0.13", "2.0.14", "2.0.15", "2.0.16", "2.0.17", "2.0.18", "2.0.19", "2.0.20", "2.0.21", "2.1.0", "2.0.21-dev.1", "3.0.0", "custom-build"]) { assert.equal(isBelowOpenCodeMinimum(version), false, version) } for (const version of ["2.0.0", "2.0.4", "2.0.5", "2.0.6", "0.0.0-beta-19507"]) assert.equal(isBelowOpenCodeMinimum(version), true, version) diff --git a/packages/server/src/opencode/runtime-support.ts b/packages/server/src/opencode/runtime-support.ts index 3662fc404..da72bc80b 100644 --- a/packages/server/src/opencode/runtime-support.ts +++ b/packages/server/src/opencode/runtime-support.ts @@ -5,7 +5,7 @@ */ export const MINIMUM_OPENCODE_VERSION = "2.0.7" /** Qualification target, independent of the technically required minimum. */ -export const RECOMMENDED_OPENCODE_VERSION = "2.0.20" +export const RECOMMENDED_OPENCODE_VERSION = "2.0.21" export const OPENCODE_UPDATE_REQUIRED = "opencode_update_required" export function isBelowOpenCodeMinimum(version: string): boolean { diff --git a/packages/server/src/opencode/session-pruning/package.json b/packages/server/src/opencode/session-pruning/package.json index 34d18f1ff..4eda2391f 100644 --- a/packages/server/src/opencode/session-pruning/package.json +++ b/packages/server/src/opencode/session-pruning/package.json @@ -17,7 +17,7 @@ "transaction.ts", "tui.ts", "tui-reload.ts" ], "dependencies": { - "@opencode/plugin": "2.0.20", + "@opencode/plugin": "2.0.21", "zod": "^3.25.76" } } diff --git a/packages/ui/package.json b/packages/ui/package.json index c31c09d99..570efdd0d 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -14,7 +14,7 @@ "dependencies": { "@git-diff-view/solid": "^0.0.8", "@kobalte/core": "0.13.11", - "@opencode/client": "2.0.20", + "@opencode/client": "2.0.21", "@solidjs/router": "^0.13.0", "@suid/icons-material": "^0.9.0", "@suid/material": "^0.19.0",