Skip to content

refactor(tool): migrate tool framework + all 18 built-in tools to Effect Schema#23244

Merged
kitlangton merged 2 commits intodevfrom
kit/tools-schema
Apr 23, 2026
Merged

refactor(tool): migrate tool framework + all 18 built-in tools to Effect Schema#23244
kitlangton merged 2 commits intodevfrom
kit/tools-schema

Conversation

@kitlangton
Copy link
Copy Markdown
Contributor

@kitlangton kitlangton commented Apr 18, 2026

Note: this PR was previously titled "pin every tool's parameters schema before migration" and only contained the snapshot/parse safety net. The stacked migration (originally #23293) was merged into this branch and rebased against current dev, so this single PR now lands both the safety net and the full framework+tools migration.

Framework (tool/tool.ts)

  • Tool.Def.parameters typed as Schema.Decoder<unknown> (replaces z.ZodType).
  • Runtime validation uses Schema.decodeUnknownEffect + Effect.mapError instead of Effect.try wrapping toolInfo.parameters.parse(args) — matches idiomatic patterns already used elsewhere and satisfies AGENTS.md's avoid-try/catch rule.
  • formatValidationError?(error: unknown) — the hook is no longer zod-specific. No tool currently implements it.

JSON Schema pipeline

Extracted EffectZod.toJsonSchema(schema) into util/effect-zod.ts. Three emit sites share one implementation:

  • session/prompt.ts — every LLM tool registration
  • server/routes/instance/experimental.ts — was previously calling z.toJSONSchema(t.parameters) directly; would have failed at runtime once t.parameters became a Schema. Fixed here.
  • test/tool/parameters.test.ts — snapshot test mirrors the production path so any future drift fails the snapshot.

Tools (17 files — multiedit was deleted by #23701 on dev)

Mechanical conversion of each tool's Parameters:

Before (zod) After (Schema)
z.object({...}) Schema.Struct({...})
z.string().describe("x") Schema.String.annotate({ description: "x" })
z.string().optional() Schema.optional(Schema.String)
z.number().int().min(1) Schema.Number.check(Schema.isInt()).check(Schema.isGreaterThanOrEqualTo(1))
z.enum([...]) Schema.Literals([...])
z.array(X) Schema.mutable(Schema.Array(X))
z.number().min(1000).max(50000).default(5000) chained checks + Schema.withDecodingDefault(Effect.succeed(5000))
z.infer<typeof Parameters> Schema.Schema.Type<typeof Parameters>

Notable simplifications:

  • read.ts: dropped z.coerce.number() on offset/limit. LLM tool-call path receives typed JSON; string coercion was only relevant to CLI callers, of which there are none. JSON Schema output identical.
  • todo.ts: inlined the three todo fields rather than pulling Todo.Info.shape from the still-zod session/todo.ts. Removes the last zod import from the tool file; LLM-visible JSON Schema is identical.
  • question.ts: references Question.Prompt (already a Schema.Class) directly instead of Question.Prompt.zod.

Plugin tools (tool/registry.ts)

Plugin tool args are defined via zod (@opencode-ai/plugin API — external). The registry wraps the derived z.object(def.args) in a Schema.declare(typeGuard) so it slots into the Schema-typed framework, and annotates it with ZodOverride so the walker emits the original zod object when generating JSON Schema for the LLM. Runtime behaviour and JSON Schema for plugin tools unchanged.

Safety net (originally PR #23244)

  • Every tool exports its Parameters schema at module scope.
  • 17 JSON Schema snapshots + per-tool parse accepts/rejects assertions in test/tool/parameters.test.ts. These caught zero drift during the migration.

Rebase notes

Rebased onto current dev (was ~18 days old). Conflicts resolved:

  • multiedit was deleted on dev by chore: kill unused tool #23701; dropped from both commits.
  • edit.ts — kept HEAD's locks/lock() helper added on dev plus branch's Schema migration.
  • read.ts — kept HEAD's new readSample/isBinaryFile helpers plus branch's Schema migration.
  • skill.ts — kept HEAD's refactored execute body (no more nested return { description, parameters, execute } wrapper) plus branch's Schema migration.
  • todo.ts — kept branch's inlined Schema (matches HEAD's zod-inlined pattern semantically; same LLM-visible JSON Schema).
  • util/effect-zod.ts — merged dev's zodObject helper with branch's toJsonSchema helper.

Verification

  • bun typecheck clean
  • bun run test — 2123 pass / 0 fail (full suite)
  • 17 JSON Schema snapshots byte-identical — LLM view of every tool unchanged.
  • SDK byte-identical (types.gen.ts and openapi.json)

Scope notes

  • Tool authors now write pure Schema. No zod in any tool file.
  • The walker (@/util/effect-zod) and central EffectZod.toJsonSchema helper remain — they convert Schema → zod at the edge where ai SDK wants zod-style JSON Schema. Retirable when the runtime LLM layer accepts Effect Schema natively.
  • session/todo.ts still exports a zod Info; migration deferred (the tool's todowrite Parameters inlines the fields rather than depending on it).

Pre-migration safety net for the upcoming tool-by-tool zod\u2192Schema
conversion. Every tool's parameters schema now has:

1. A JSON Schema snapshot (`z.toJSONSchema` with `io: "input"`) \u2014 this
   captures exactly what the LLM sees at tool registration time, so any
   drift caused by a future migration fails the snapshot.
2. Parse-accept/parse-reject assertions per tool pinning the
   user-visible behavioural contract (required fields, refinement
   bounds, enum membership, default values).

To make the snapshots possible without standing up each tool's full
Effect runtime, every tool file now exports its parameters schema as
`Parameters` at module scope:

- 9 tools already had a module-level const \u2014 just added `export`, and
  standardised the name to `Parameters` (uppercase) where it was
  previously `parameters`.
- 9 tools had their schema inline inside `Tool.define` \u2014 hoisted to
  module scope under the same `Parameters` name and wired back through.

Zero behaviour change: Tool.define still sees the same schema, runtime
validation path is identical, SDK (types.gen.ts + openapi.json) is
byte-identical, and the full 2054-test suite passes.

18 JSON Schema snapshots and 43 explicit parse/reject assertions for the
18 built-in tools (apply_patch, bash, codesearch, edit, glob, grep,
invalid, lsp, multiedit, plan, question, read, skill, task, todo,
webfetch, websearch, write).
@kitlangton kitlangton changed the title test(tool): pin every tool's parameters schema before migration refactor(tool): migrate tool framework + all 18 built-in tools to Effect Schema Apr 23, 2026
@kitlangton kitlangton disabled auto-merge April 23, 2026 20:09
@kitlangton kitlangton merged commit 3910a6e into dev Apr 23, 2026
9 checks passed
@kitlangton kitlangton deleted the kit/tools-schema branch April 23, 2026 20:09
TTK95 pushed a commit to TTK95/opencode that referenced this pull request Apr 24, 2026
Conflict resolutions:
- packages/{opencode,plugin,web}/package.json: bump to 1.14.22-dev_ttk
- tool/bash.ts: port run_in_background param from zod to Effect Schema
  (upstream refactored tool params to Schema.Struct in anomalyco#23244)
- tool/task.ts: port isolation=worktree param from zod to Effect Schema,
  keep worktree helper imports (path/os/fs/spawn/Instance/Log)
TTK95 pushed a commit to TTK95/opencode that referenced this pull request Apr 24, 2026
…Schema

Matches the Tool.define schema migration in upstream anomalyco#23244. Without this
the tool registry can't construct these tools and runtime errors out with
"undefined is not an object (evaluating 'X.context')" on every prompt.
xywsxp pushed a commit to xywsxp/opencode that referenced this pull request Apr 24, 2026
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 27, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
Astro-Han added a commit to Astro-Han/pawwork that referenced this pull request Apr 28, 2026
Two PawWork product fixes (commits 34b37d3, af6c079) were silently
reverted when Stage E took theirs on tool/read.ts. Restore both on
top of the upstream-aligned read.ts:

* LSP warm hook removal — reading a file no longer calls
  lsp.touchFile. Aligns with industry baseline (Codex / Gemini /
  Claude Code skip this in their read paths) and matches PawWork's
  on-demand LSP activation model. LSP work happens only on edit /
  write / apply_patch where diagnostics are actually consumed.

* Binary detection split — extension-based check (isBinaryByExt)
  rejects known binary extensions before sampling, with the
  generic .bin / .dat sniff-first carve-out so renamed image / PDF
  attachments survive. Content-based check (isBinaryByContent)
  rejects on null bytes or >30% non-printable. Error messages
  include "(extension: .X)" or "(content inspection)" so the LLM
  can disambiguate the rejection cause when retrying.

* Oversized attachment guard — image / PDF over 5 MB is rejected
  before base64 encoding to keep the model context safe.

Fixes 4 read.test.ts failures inherited from PR4 base.

Refs anomalyco/opencode#23244 (Stage E origin), PawWork #232
PawWork issue: #209
balcsida added a commit to balcsida/opencode that referenced this pull request Apr 28, 2026
* refactor(core): migrate MessageV2 internal Cursor to Effect Schema (anomalyco#23763)

* refactor(core): migrate MessageV2 errors to Schema-backed named errors (anomalyco#23764)

* chore: generate

* chore: bump Bun to 1.3.13 (anomalyco#23791)

* fix(app): improve icon override handling in project edit dialog (anomalyco#23768)

* chore: update nix node_modules hashes

* fix: preserve BOM in text tool round-trips (anomalyco#23797)

* chore: generate

* test: fix cross-spawn stderr race on Windows CI (anomalyco#23808)

* chore: generate

* fix: consolidate project avatar source logic (anomalyco#23819)

* fix(tui): fail fast on invalid session startup (anomalyco#23837)

* chore: generate

* fix(session): improve session compaction (anomalyco#23870)

* chore: generate

* fix(project): use git common dir for bare repo project cache (anomalyco#19054)

* docs: add MiMo V2.5 to Go pages (anomalyco#23876)

* chore: generate

* chore: update nix bun version (anomalyco#23881)

* feat: support pull diagnostics in the LSP client (C#, Kotlin, etc) (anomalyco#23771)

* chore: generate

* log session sdk errors (anomalyco#23652)

* fix(beta): PR resolvers/smoke check should typecheck all pacakges (anomalyco#23913)

* tweak: codex model logic (anomalyco#23925)

* refactor: remove redundant pending check from working memo (anomalyco#23929)

* sync release versions for v1.14.21

* zen: hy3 preview

* fix: add keyed prop to Show components for proper reactivity (anomalyco#23935)

* feat(project): add icon_url_override field to projects (anomalyco#23955)

* chore: generate

* chore: add to TEAM_MEMBERS (anomalyco#23975)

* fix(npm): respect npmrc config (anomalyco#24001)

* fix(tui): render all non-synthetic text parts of a user message (anomalyco#24009)

* refactor(session): migrate session domain to Effect Schema (anomalyco#24005)

* chore: generate

* sync release versions for v1.14.22

* fix(npm): respect npmrc for version lookups (anomalyco#24016)

* chore: generate

* refactor(sync): make session events schema-first (anomalyco#24019)

* chore: generate

* docs(schema): mark sync/index.ts migrated with compat-bridge note (anomalyco#24024)

* sync

* refactor(provider): migrate provider domain to Effect Schema (anomalyco#24027)

* refactor(schema): use Schema.Int and consolidate PositiveInt/NonNegativeInt (anomalyco#24029)

* refactor(bus): migrate BusEvent to Effect Schema (anomalyco#24040)

* chore: generate

* refactor(tool): migrate tool framework + all 18 built-in tools to Effect Schema (anomalyco#23244)

* chore: generate

* feat(tui): support builtin protocol for handling context from editors (anomalyco#24034)

* chore: generate

* docs: update effect schema migration tracker (anomalyco#24054)

* refactor(control-plane): migrate workspace DTO schemas (anomalyco#24056)

* chore: generate

* chore: update copilot readme to symlink to an agents md to prevent dumbass agents from touching these files (anomalyco#24057)

* fix: account for additional openai retry case (anomalyco#24063)

* feat(httpapi): bridge workspace read endpoints (anomalyco#24062)

* feat(truncate): allow configuring tool output truncation limits (anomalyco#23770)

Co-authored-by: rgs_ramp <rgs@ramp.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>

* chore: generate

* ci: add platform-specific bun install flags (anomalyco#23822)

* fix(desktop): avoid relaunching without installing updates (anomalyco#23806)

* chore: generate

* feat(prompt): add shell mode UI with cancel button, custom icon, and example placeholder (anomalyco#24105)

* sync

* zen: deepseek v4 pro

* fix(app): conditionally show model variant selector (anomalyco#24115)

* test(prompt): align shell placeholder expectation (anomalyco#24147)

* fix: deepseek variants (anomalyco#24157)

* fix: preserve empty reasoning_content for DeepSeek V4 thinking mode (anomalyco#24146)

Co-authored-by: Simon Klee <hello@simonklee.dk>

* fix: support `max` for deepseek (anomalyco#24163)

* feat(httpapi): bridge file read endpoints (anomalyco#24098)

* sync release versions for v1.14.23

* feat(httpapi): bridge mcp status endpoint (anomalyco#24100)

* chore: generate

* fix: use existingModel as fallback for interleaved field (anomalyco#24172)

* fix: ensure assistant messages always have reasoning on them for deepseek (anomalyco#24180)

* Use OpenTUI theme detection for initial TUI mode, again (anomalyco#23846)

* chore: update nix node_modules hashes

* zen: deepseek v4 pro

* chore: generate

* sync release versions for v1.14.24

* zen: gpt-5.5

* zen: gpt-5.5

* zen: gpt-5.5

* zen: gpt-5.5

* Refactor HttpApi auth middleware wiring (anomalyco#24168)

* refactor(schema): decode effect schemas directly (anomalyco#24169)

* chore: generate

* Clarify HttpApi migration plan (anomalyco#24211)

* ignore: denounce ai spammer

* chore: generate

* fix: ensure gpt-5.5 compacts at correct context size when using openai oauth (anomalyco#24212)

* fix(opencode): clarify git amend condition to require verifying commit landed (anomalyco#19937)

Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>

* refactor(ripgrep): migrate result schemas to effect (anomalyco#24213)

* test(httpapi): cover hono bridge middleware (anomalyco#24216)

* chore: generate

* Add Roslyn support for Razor and C# scripts (anomalyco#24228)

* fix: validate beta before pushing (anomalyco#24230)

* chore: generate

* chore: group beta PR logs (anomalyco#24236)

* fix(build): add prettier to devDependencies (anomalyco#23255)

* chore: update nix node_modules hashes

* ci: adjust auto close issue script to use not planned instead of completed (anomalyco#24253)

* Fix shell cwd after login startup (anomalyco#24215)

* tool/lsp: include request details in permission metadata (anomalyco#24139)

* fix permission config order (anomalyco#24222)

* chore: generate

* ci: centralize opentui dependencies in workspace catalog

Use catalog references for @opentui/core, @opentui/solid, and opentui-spinner
across packages to ensure consistent versions and simplify updates.

* core: permission config schema now provides full IntelliSense for all tool permission keys

The permission configuration previously used a generic record type that didn't offer editor completions. Updated the schema to explicitly list all tool permission keys (read, edit, glob, grep, list, bash, task, external_directory, lsp, skill, todowrite, question, webfetch, websearch, codesearch, doom_loop) with proper types, enabling autocomplete when editing permission files.

* sync release versions for v1.14.25

* feat(httpapi): bridge instance read endpoints (anomalyco#24258)

* chore: generate

* refactor: remove lazy cross-spawn runtime (anomalyco#24305)

* refactor: rename shared package to core (anomalyco#24309)

* feat: add startup debug command (anomalyco#24310)

* chore: update nix node_modules hashes

* fix(config): preserve permission order with Effect decode (anomalyco#24308)

* core: consolidate shared infrastructure into core package

Moves effect logging, observability, runtime utilities, flags, installation
version info, and process utilities from opencode to core package. This
enables better code sharing across packages and establishes core as the
single source of truth for foundational utilities.

All internal imports updated to use @opencode-ai/core paths for consistency.

* chore: generate

* chore: update nix node_modules hashes

* ci: adjust review flow (anomalyco#24355)

* core: move Global module to @opencode-ai/core for centralized path management

Move the Global module from packages/opencode/src/global to packages/core/src/global
to provide a unified location for managing XDG directories and application paths.
This eliminates duplicate path definitions across packages and ensures consistent
access to data, config, cache, state, log, and bin directories throughout the codebase.

* feat(httpapi): bridge catalog read endpoints (anomalyco#24353)

* chore: generate

* feat(tui): read Zed editor context from state db (anomalyco#24352)

* feat(httpapi): bridge file search endpoints (anomalyco#24356)

* ci: fix model name

* chore: generate

* core: move cross-spawn-spawner from opencode to core package

Moved the cross-spawn-spawner module from packages/opencode to packages/core
to enable code sharing across the monorepo. This consolidates the process
spawning infrastructure into the core package so other packages can use
cross-platform child process spawning without duplicating the implementation.

Updated all import statements across the codebase to reference the new
location (@opencode-ai/core/effect/cross-spawn-spawner). Removed the
local copy from the opencode package along with its tests.

* core: move cross-spawn-spawner to root and remove unused types

The cross-spawn-spawner module has been moved from src/effect/ to src/
to simplify the core package structure. The src/types.d.ts file which
contained unused type declarations has also been removed. All imports
throughout the codebase have been updated to reflect the new location.

This change reduces the package's internal complexity by flattening the
module hierarchy and removing dead code, making future maintenance easier.

* core: move npm service to core package for shared dependency management

* feat(httpapi): bridge experimental read endpoints (anomalyco#24365)

* chore: generate

* chore: update nix node_modules hashes

* feat(httpapi): bridge worktree read endpoint (anomalyco#24366)

* chore: generate

* feat(tui): show /connect tip when user has no models configured (anomalyco#24014)

* feat(httpapi): bridge instance dispose endpoint (anomalyco#24368)

* chore: generate

* feat(httpapi): bridge worktree mutations (anomalyco#24371)

* chore: generate

* feat(httpapi): bridge config update endpoint (anomalyco#24387)

* feat(httpapi): bridge project git init endpoint (anomalyco#24394)

* chore: generate

* feat(httpapi): bridge project update endpoint (anomalyco#24398)

* feat(httpapi): bridge mcp control endpoints (anomalyco#24403)

* chore: generate

* feat(httpapi): bridge mcp oauth endpoints (anomalyco#24405)

* chore: generate

* feat(httpapi): bridge experimental tool routes (anomalyco#24407)

* chore: generate

* test(provider): avoid plugin dependency install timeout (anomalyco#24416)

* sync

* core: Add User-Agent header to identify client version in HTTP requests

* fix: bump openrouter sdk version to resolve deepseek reasoning issue (bug was in sdk pkg) (anomalyco#24435)

* chore: update nix node_modules hashes

* fix: correct typo in comment (anomalyco#24420)

* feat(httpapi): bridge experimental session list (anomalyco#24478)

* chore: generate

* feat(httpapi): bridge workspace mutations (anomalyco#24483)

* chore: generate

* fix(docs): correct OpenCode Go DeepSeek endpoints (anomalyco#24500)

* ci: update team assignments in github-triage

Update team member assignments in the triage tool:
- Remove thdxr from tui and core teams
- Add simonklee to tui team
- Add kitlangton to core team

* feat(httpapi): bridge sync routes (anomalyco#24484)

* chore: generate

* feat(httpapi): bridge session read routes (anomalyco#24485)

* chore: generate

* feat(httpapi): bridge session lifecycle routes (anomalyco#24486)

* chore: generate

* feat(httpapi): bridge session message mutations (anomalyco#24487)

* chore: generate

* feat(httpapi): bridge remaining session routes (anomalyco#24510)

* chore: generate

* sync

* sync

* chore: generate

* chore: rm empty file

* fix(editor): reject lock files with no workspace match for cwd (anomalyco#24323)

* feat(go): add Go model listing endpoint (anomalyco#24304)

Co-authored-by: Frank <frank@anoma.ly>

* upgrade opentui to 0.1.104 (anomalyco#24531)

* chore: update nix node_modules hashes

* sync release versions for v1.14.26

* fix(tui): update toast duration handling to use default value (anomalyco#23395)

Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>

* tui: remove excessive debug logging from workspace creation flow to reduce terminal output noise

* feat(httpapi): bridge event stream (anomalyco#24518)

* chore: generate

* feat: configurable shell selection + desktop settings UI (anomalyco#20602)

* feat(httpapi): bridge pty routes (anomalyco#24547)

* core: refactor Installation service to use a single consolidated result object

Reorganizes the Installation service implementation by grouping info, method, latest, and upgrade methods into a single result object. This improves code locality and makes the service interface more maintainable. Also adds a clarifying comment explaining why the package manager's resolver is used for version lookups (to ensure registries, mirrors, auth, proxies, and dist-tags match upgrade behavior).

* feat(httpapi): bridge tui routes (anomalyco#24548)

* fix(tui): hide provider checks before onboarding (anomalyco#24551)

* upgrade opentui to 0.1.105 (anomalyco#24555)

* chore: update nix node_modules hashes

* sync release versions for v1.14.27

* go: models endpoint

* Update VOUCHED list

anomalyco#24563 (comment)

* fix: ignore GitHub Actions changelog contributor (anomalyco#24567)

* Refactor npm config handling (anomalyco#24565)

* go: add deepseek icon

* chore: generate

* sync release versions for v1.14.28

* fix: default tool call streaming to false for google vertex (anomalyco#24573)

* sync

* ignore: split up reasoning transforms (anomalyco#24574)

* update Go DeepSeek request estimates for cache pricing changes (anomalyco#24575)

* fix(opencode): agent create generates permissions field with deny ins… (anomalyco#24482)

Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>

* chore: generate

* zen: coupons

* chore: generate

* fix: pass workspace symbol query to experimental LSP tool (anomalyco#24576)

* chore: generate

* update Go DeepSeek flash limits for cache pricing drop (anomalyco#24592)

* docs: fix duplicated word in CLI env var table (anomalyco#24614)

Co-authored-by: Seashore <ss@SeashoredeMac-mini.local>

* chore: generate

* tweak: make interleaved reasoning_content default to true for openai compat deepseek setups (anomalyco#24630)

* fix(httpapi): mount workspace bridge routes (anomalyco#24626)

* fix(httpapi): accept empty session create body (anomalyco#24640)

* refactor: remove module barrels (anomalyco#24554)

* chore: generate

* fix: ensure toolStreaming is set to off by default when using non anthropic models with anthropic sdk (anomalyco#24642)

* fix(tui): stabilize Zed editor context polling (anomalyco#24656)

* chore: generate

* fix(httpapi): enforce instance route parity (anomalyco#24660)

* feat(core): file context improvements and option to disable (anomalyco#24661)

* fix(tui): preserve Zed context on terminal focus (anomalyco#24662)

* test(httpapi): verify reflected route mounts (anomalyco#24663)

* chore: generate

* fix(tui): consume Enter in dialog useKeyboard handlers (anomalyco#23390)

* fix(session): harden shell cancellation (anomalyco#24553)

* test(httpapi): cover full OpenAPI route inventory (anomalyco#24667)

* chore: generate

* fix(httpapi): preserve optional session fields (anomalyco#24671)

* fix(session): omit undefined optional fields (anomalyco#24676)

* fix(session): remove compaction summary dividers (anomalyco#24677)

* test(httpapi): cover session json parity (anomalyco#24682)

* fix(httpapi): align session boolean query parsing (anomalyco#24693)

* chore: generate

* fix(httpapi): preserve provider oauth authorize parity (anomalyco#24703)

* chore: generate

* chore: bump effect beta (anomalyco#24705)

* chore: update nix node_modules hashes

* fix(tui): keep Zed context polling responsive (anomalyco#24711)

* fix(httpapi): preserve mcp oauth error parity (anomalyco#24706)

* chore: generate

* refactor(app): load sync state through TanStack Query (anomalyco#23792)

* fix: sanitize tools for moonshot (anomalyco#24730)

* chore: generate

* Update VOUCHED list

anomalyco#24732 (comment)

* fix(ui): remove redundant flex overrides in tool components (anomalyco#24749)

* ci: add release-cli workflow

---------

Co-authored-by: Kit Langton <kit.langton@gmail.com>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com>
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
Co-authored-by: Steven T. Cramer <Steven.Cramer@TimeWarp.Enterprises>
Co-authored-by: Jack <jack@anoma.ly>
Co-authored-by: Caleb Norton <n0603919@outlook.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: opencode <opencode@sst.dev>
Co-authored-by: Frank <frank@anoma.ly>
Co-authored-by: Simon Klee <hello@simonklee.dk>
Co-authored-by: James Long <longster@gmail.com>
Co-authored-by: rahul <gsr1998@gmail.com>
Co-authored-by: rgs_ramp <rgs@ramp.com>
Co-authored-by: 黑墨水鱼 <heimoshuiyu@gmail.com>
Co-authored-by: 07akioni <07akioni2@gmail.com>
Co-authored-by: Sebastian <hasta84@gmail.com>
Co-authored-by: Kyle Altendorf <sda@fstab.net>
Co-authored-by: Maddison Hellstrom <b0o@users.noreply.github.com>
Co-authored-by: Dax <mail@thdxr.com>
Co-authored-by: Dax Raad <d@ironbay.co>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
Co-authored-by: Ariane Emory <97994360+ariane-emory@users.noreply.github.com>
Co-authored-by: Jermiah Joseph <44614774+jjjermiah@users.noreply.github.com>
Co-authored-by: OpeOginni <107570612+OpeOginni@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: 21pounder <youngyepeng911@qq.com>
Co-authored-by: Seashore Shi <seashore.shi@gmail.com>
Co-authored-by: Seashore <ss@SeashoredeMac-mini.local>
Co-authored-by: Cas <10153929+CasualDeveloper@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant