feat(codemode): native coercion parity in interpreter#37608
Merged
Conversation
github-actions Bot
pushed a commit
to ReStranger/opencode
that referenced
this pull request
Jul 18, 2026
* upstream/v2: feat(core): publish pending MCP status during connect (anomalyco#37605) feat(codemode): native coercion parity in interpreter (anomalyco#37608) test(core): stabilize shell progress test (anomalyco#37643) fix(ai): parse compatible reasoning deltas (anomalyco#37558) fix(core): remove session import cycle (anomalyco#37596)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes six coercion-parity gaps from
interpreter-support.mdwhere ordinary model-written JavaScript failed in CodeMode but works natively.Changes
"v1.2".includes(1),"abc".slice("1"),"a1b".replace(1, 2)coerce like native JS (including the callback-replacer path). Opaque runtime references still reject as data errors;includes/startsWith/endsWithreject regular expressions with a native-styleTypeError;split(undefined)returns the whole string with zero limits honored.Number()andString()produce0and"";Number(undefined)staysNaN.isFinite/isNaN, usable as callbacks (values.filter(isFinite)).match()/matchAll()/search()with no argument behave as an empty pattern.++/--use CodeMode numeric coercion instead of hostNumber(...). This also fixes a real crash:x = {}; x++previously surfaced a raw hostTypeErrorbecause SafeObjects are null-prototype and hostToPrimitivethrows.coerceToNumbernow routes arrays through interpreter string coercion for the same reason ([{}]no longer leaks "No default value").undefinedon global namespaces and the coercion functions, so feature detection (typeof Math.sumPrecise,Object.groupBy === undefined) works like native JS. Reads are gated on the same known-member sets the invoke switches use; calling an undefined value reports a native-styleTypeErrornaming the callee (Math.sumPrecise is not a function.). Blocked members (constructor,__proto__, ...) still throw, and unknownPromisestatics keep their descriptive error.Deliberate documented deviations kept:
repeatstill requires a finite non-negative count (now brandedRangeError),match/searcharguments must still be a regex or string pattern, and opaque runtime references reject everywhere coercion happens.Testing
test/parity.test.ts, with odd edges (split(undefined, 0),padStart("3", 0),"abc".match().index) cross-checked against native JS.packages/codemode; typecheck clean.interpreter-support.mdchecklist updated in the same PR.