mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-10-23 23:01:06 +00:00
## Summary - Recommend and pin OpenCode **2.0.29** (`@opencode/client`, `@opencode/plugin`); the technical minimum stays **2.0.27** since 2.0.28/2.0.29 keep Effect 4.0.1. - Add 2.0.29 as a reviewed contract profile beside 2.0.27; 2.0.28 and future/custom labels keep authenticated negotiation. - Test fixture only: the recurring Missions host declares the `credential` domain that the 2.0.29 Promise adapter reads eagerly (the managed owner spreads `ctx`, dropping the Proxy fallback). No product code change. - Two new isolated fixtures for upstream behavior changes: bounded output-length continuation, and rejected Promise tools / native denial. - Compatibility docs, CONTRIBUTING, AGENTS and architecture guide updated. ## Upstream review - OpenAPI: same 118 paths; additive schema changes (config `policies`, provider/model `compatibility`, `encoding`). - Private LocationServiceMap/Form/Permission/queue contracts used by the pending snapshot: unchanged. - Effect stays 4.0.1. ## Validation (Windows, isolated CLIs/databases, never the shared daemon) - 2.0.29: plugin runtime, automation, pruning/history/proxy, Missions contract/family control/full journey, session environment, fork, aside, prompt skills, Git degraded/init, provider usage/accounts, temporary workspaces, blank-session cleanup, output-limit continuation, Promise tool failure, system settings discovery, native upgrade 2.0.15→2.0.29. - 2.0.27 (minimum): plugin runtime, automation, pruning, Missions contract/family, session environment, fork, aside, prompt skills, blank cleanup. - Server: 2235 passed / 7 skipped / 0 failed. UI: 1524 passed. Tauri crate 268/268, updater handoff 1/1, UI updater flow 13/13 (dev base includes #786). ## Known, not caused by this change `scripts/test-permission-receipts-native.mjs` times out identically on 2.0.27 with the previous pins; tracked separately.
43 lines
2.4 KiB
TypeScript
43 lines
2.4 KiB
TypeScript
/**
|
|
* Native plugins share the daemon's Effect/SDK rather than embedding a second
|
|
* runtime. 2.0.27 supplies Effect 4.0.1 and Schema.isStartingWith consumed by the
|
|
* current schemas; 2.0.26 fails the isolated plugin-loading regression.
|
|
* See dev-docs/OPENCODE_V2_COMPATIBILITY.md for the demonstrated ABI boundary.
|
|
*/
|
|
export const MINIMUM_OPENCODE_VERSION = "2.0.27"
|
|
/** Qualification target, independent of the technically required minimum. */
|
|
export const RECOMMENDED_OPENCODE_VERSION = "2.0.29"
|
|
export const OPENCODE_UPDATE_REQUIRED = "opencode_update_required"
|
|
|
|
export function isBelowOpenCodeMinimum(version: string): boolean {
|
|
// These historical V2 beta publications predate the stable event contract.
|
|
if (/^0\.0\.0-beta-\d+$/.test(version)) return true
|
|
const match = /^(\d+)\.(\d+)\.(\d+)(?:\+[\w.-]+)?$/.exec(version)
|
|
// Custom/prerelease labels are unverified, not automatically incompatible.
|
|
// Their authenticated API contract is inspected before functional requests.
|
|
if (!match) return false
|
|
const [major, minor, patch] = match.slice(1).map(Number)
|
|
const [minimumMajor, minimumMinor, minimumPatch] = MINIMUM_OPENCODE_VERSION.split(".").map(Number)
|
|
return major! < minimumMajor! || (major === minimumMajor && (minor! < minimumMinor!
|
|
|| (minor === minimumMinor && patch! < minimumPatch!)))
|
|
}
|
|
|
|
export type OpenCodeIncompatibility = "plugin_runtime" | "step_timestamp" | "canonical_api" | "session_environment"
|
|
|
|
export class UnsupportedOpenCodeError extends Error {
|
|
readonly code = OPENCODE_UPDATE_REQUIRED
|
|
readonly statusCode = 426
|
|
readonly minimumVersion = MINIMUM_OPENCODE_VERSION
|
|
constructor(readonly actualVersion: string, readonly reason: OpenCodeIncompatibility = "plugin_runtime") {
|
|
super(`${OPENCODE_UPDATE_REQUIRED}: OpenCode ${actualVersion}; ${reason === "plugin_runtime"
|
|
? `requires the native Effect 4.0.1/Schema plugin runtime introduced in ${MINIMUM_OPENCODE_VERSION}`
|
|
: reason === "step_timestamp" ? "requires the native session.step.started.data.started timestamp introduced in 2.0.7"
|
|
: reason === "session_environment" ? "requires PUT /api/session/{sessionID}/environment with variables"
|
|
: "does not expose the canonical session, permission, Form and inbox API contract"}`)
|
|
this.name = "UnsupportedOpenCodeError"
|
|
}
|
|
}
|
|
|
|
export function assertSupportedOpenCode(version: string): void {
|
|
if (isBelowOpenCodeMinimum(version)) throw new UnsupportedOpenCodeError(version)
|
|
}
|