From 0086eaf3bdce6bb53b68a9c665691e2a2631fe4a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 27 Oct 2026 15:08:15 +0000 Subject: [PATCH 1/2] deps: bump @opencode/codemode to 2.2.0 Move the extension pin assertion with the dependency. effect stays 4.0.1. Co-authored-by: Hyein Cho --- package-lock.json | 8 ++++---- package.json | 2 +- test/extension.test.js | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 77418dc..eb60b8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.4", "license": "MIT", "dependencies": { - "@opencode/codemode": "2.1.4", + "@opencode/codemode": "2.2.0", "acorn": "8.15.0", "effect": "4.0.1" }, @@ -570,9 +570,9 @@ } }, "node_modules/@opencode/codemode": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@opencode/codemode/-/codemode-2.1.4.tgz", - "integrity": "sha512-1gFyokMI4EgFyu0NgaCPr/HPZQKasZuwCPX4v7Plm+dYANetRt98vv3BXG4pJpn4ERPI+mc86tsHfpulDdZEfA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@opencode/codemode/-/codemode-2.2.0.tgz", + "integrity": "sha512-U3oWOLB+rSSdqH4C6PDD+FqrYOBNgPaoo8Yc/lqUPI7cnUsynAXlHyUzmSaF6RKzE6FV2fhYJ2LPw8QWnwC9Ww==", "license": "MIT", "dependencies": { "acorn": "8.15.0", diff --git a/package.json b/package.json index 7d1b8de..53c24a1 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "test:pi-versions": "node --test test/pi-versions.test.js" }, "dependencies": { - "@opencode/codemode": "2.1.4", + "@opencode/codemode": "2.2.0", "acorn": "8.15.0", "effect": "4.0.1" }, diff --git a/test/extension.test.js b/test/extension.test.js index 5892ef5..6118cff 100644 --- a/test/extension.test.js +++ b/test/extension.test.js @@ -27,7 +27,7 @@ test("package is one OpenCode-backed pi extension", () => { const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")); assert.deepEqual(pkg.pi.extensions, ["./index.js"]); assert.deepEqual(Object.keys(pkg.dependencies).sort(), ["@opencode/codemode", "acorn", "effect"]); - assert.equal(pkg.dependencies["@opencode/codemode"], "2.1.4"); + assert.equal(pkg.dependencies["@opencode/codemode"], "2.2.0"); }); test("registration supplies conditional preference without routing or prompt hooks", () => { From 37a8c496316b53ed88ab474cc55fa3bb2182566d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 27 Oct 2026 22:16:01 +0000 Subject: [PATCH 2/2] docs: record @opencode/codemode 2.2.0 as the current baseline Name 2.2.0 in the README and preflight notes, add an Unreleased changelog entry, and record the re-run test counts in TESTING.md. Co-authored-by: Hyein Cho --- CHANGELOG.md | 7 +++++++ README.md | 4 ++-- TESTING.md | 11 +++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95eda1a..bd52d0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +### Changed + +- Use `@opencode/codemode` 2.2.0. The published interpreter sources are unchanged + from 2.1.4; Acorn stays 8.15.0 and Effect stays 4.0.1. The extension's tool + bridge, limits, preflight, and result contract are unchanged, including + rejection of `for...in`. + ## 0.1.4 — 2026-10-26 ### Changed diff --git a/README.md b/README.md index fcd0745..93b89a6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A small Pi extension that leaves native `codemode` in place and lets you choose OpenCode CodeMode too. -It registers **`codemode_o`**, backed by `@opencode/codemode` 2.1.4: another execution option for short, self-contained JavaScript-like programs that call Pi tools. Host calls retain Pi's validation, permission/result hooks, and nested-call audit; cancellation waits for host cleanup, and output keeps bounded, visible diagnostics. +It registers **`codemode_o`**, backed by `@opencode/codemode` 2.2.0: another execution option for short, self-contained JavaScript-like programs that call Pi tools. Host calls retain Pi's validation, permission/result hooks, and nested-call audit; cancellation waits for host cleanup, and output keeps bounded, visible diagnostics. Short programs can be quick: see the [benchmark snapshot](#benchmark-snapshot) for measured comparisons with native `codemode`. Both can batch tool calls; this extension lets you use the OpenCode interpreter in Pi without replacing the native tool. Performance depends on the workload, and lower latency does not imply stronger isolation. You choose the tool: preflight can reject an unsuitable OpenCode program, but never switches tools or falls back automatically. @@ -201,7 +201,7 @@ After the LLM explicitly calls `codemode_o`, `checkOpenCodeCompatibility(code)` The historical `selectCodemodeRoute` helper and `ROUTE_LIMITS` alias remain for API compatibility only; the extension does not call that helper. Its `requested: "auto"` result is a legacy static advisory, not the tool-selection policy. - OpenCode candidates are at most **8,192 UTF-8 source bytes**, **100 lines**, **2,000 AST nodes**, and **64 AST levels**. Acorn parses source without executing it; a conservative compatibility allowlist rejects unknown syntax. -- Pi globals (`text`, `image`, `exit`, `store`, `load`, `ALL_TOOLS`, `searchTools`, `describeTool`, `describeNamespace`, `models`), options comments (`@options:`), classes, BigInt literals, generators, accessors, and uncertain constructors are rejected by the OpenCode preflight. `switch`/`case` and `new Date`, `new RegExp`, `new Map`, `new Set`, `new URL`, `new EvalError`, and `new URIError` are admitted because CodeMode 2.1.4 runs them. Regular-expression literals (such as `/pattern/g`) are supported; malformed patterns or flags fail as source syntax errors. Other constructors, including `new Promise` and `new URLSearchParams`, stay rejected. `for...in` also stays rejected before execution: CodeMode 2.1.4 skips inherited properties and still visits keys deleted during iteration. Comments, strings, and ordinary property names do not count as global references; shadowed Pi names conservatively stay native. +- Pi globals (`text`, `image`, `exit`, `store`, `load`, `ALL_TOOLS`, `searchTools`, `describeTool`, `describeNamespace`, `models`), options comments (`@options:`), classes, BigInt literals, generators, accessors, and uncertain constructors are rejected by the OpenCode preflight. `switch`/`case` and `new Date`, `new RegExp`, `new Map`, `new Set`, `new URL`, `new EvalError`, and `new URIError` are admitted because CodeMode 2.2.0 runs them. Regular-expression literals (such as `/pattern/g`) are supported; malformed patterns or flags fail as source syntax errors. Other constructors, including `new Promise` and `new URLSearchParams`, stay rejected. `for...in` also stays rejected before execution: CodeMode 2.2.0 skips inherited properties and still visits keys deleted during iteration. Comments, strings, and ordinary property names do not count as global references; shadowed Pi names conservatively stay native. - This is a compatibility guard, **not** a tool selector, full JavaScript semantic validator, cost estimator, or security boundary. Tool availability, values, built-in methods, runtime failures, and actual running time cannot be proven statically. Rejection does not guarantee that native Pi supports the program either. - Native Pi `codemode` is **model-only**, so this extension cannot invoke it through `ctx.executeTool`. When preflight rejects a compatibility limitation, `codemode_o` returns `NativeCodemodeRequired` **before constructing the runtime or calling any host tool**. The caller must invoke the active built-in `codemode` itself, using its raw-source input contract. If it is disabled, report that native `codemode` is needed; this extension does not enable it. No tool name rewriting or permission bypass is used. - Invalid source in Acorn's script context returns `SourceSyntaxError` (`invalid-script-syntax`), not a native recommendation. Unexpected parser exceptions return `PreflightParserError` (`internal-parser-error`). Both stop before runtime construction, preserve a bounded original parser message without a stack or source excerpt, and never rewrite or replay source. Syntax errors should be fixed before running; internal parser failures should be reported. diff --git a/TESTING.md b/TESTING.md index dc02c3b..ae27544 100644 --- a/TESTING.md +++ b/TESTING.md @@ -23,8 +23,10 @@ npm test ``` After dependencies are installed, the tests do not install SDKs or use model -APIs. Without `PI_OPENCODE_SDK`, the session suite explicitly skips: the current -result is **77 passed, 1 skipped**. The boundary tests include literal 30-second +APIs. The release pin under test is `@opencode/codemode` **2.2.0**. Without +`PI_OPENCODE_SDK`, the session suite explicitly skips: the current result on +Node **v22.23.4** is **77 passed, 0 failed, 1 skipped** (78). The skip is +`isolated real Pi SDK session`. The boundary tests include literal 30-second timeout and delayed-cleanup probes, so the suite takes at least 30 seconds. ## Full suite with an existing SDK @@ -63,6 +65,11 @@ This opt-in command installs from npm. For each supported baseline it: 4. Removes the temp directory in `finally`, even on failure. It does not alter the source checkout's dependencies or personal Pi settings. +The release pin this command installs and verifies is `@opencode/codemode` +**2.2.0**. On Node **v22.23.4**, `npm run test:pi-versions` passed **3** tests +and failed **0**, one full suite each for Pi **0.99.0**, **1.3.0**, and +**1.4.0**, with no skipped tests inside those suites. + To test one baseline (the same command used in each CI job): ```sh