3.8 KiB
Tool migration
Practical reference for the current tool-migration state in packages/opencode.
Status
Tool.Def.execute and Tool.Info.init already return Effect on this branch, and the built-in tool surface is now largely on the target shape.
The current exported tools in src/tool all use Tool.define(...) with Effect-based initialization, and nearly all of them already build their tool body with Effect.gen(...) and Effect.fn(...).
So the remaining work is no longer "convert tools to Effect at all". The remaining work is mostly:
- remove Promise and raw platform bridges inside individual tool bodies
- swap tool internals to Effect-native services like
AppFileSystem,HttpClient, andChildProcessSpawner - keep tests and callers aligned with
yield* info.init()and real service graphs
Current shape
Tool.define(...) is already the Effect-native helper here.
initis anEffectinfo.init()returns anEffectexecute(...)returns anEffect
That means a tool does not need a separate Tool.defineEffect(...) helper to count as migrated. A tool is effectively migrated when its init and execute path stay Effect-native, even if some internals still bridge to Promise-based or raw APIs.
Tests
Tool tests should use the existing Effect helpers in packages/opencode/test/lib/effect.ts:
- Use
testEffect(...)/it.live(...)instead of creating fake local wrappers around effectful tools. - Yield the real tool export, then initialize it:
const info = yield* ReadTool,const tool = yield* info.init(). - Run tests inside a real instance with
provideTmpdirInstance(...)orprovideInstance(tmpdirScoped(...))so instance-scoped services resolve exactly as they do in production.
This keeps tool tests aligned with the production service graph and makes follow-up cleanup mostly mechanical.
Exported tools
These exported tool definitions already exist in src/tool and are on the current Effect-native Tool.define(...) path:
apply_patch.tsbash.tscodesearch.tsedit.tsglob.tsgrep.tsinvalid.tsls.tslsp.tsmultiedit.tsplan.tsquestion.tsread.tsskill.tstask.tstodo.tswebfetch.tswebsearch.tswrite.ts
Notes:
batch.tsis no longer a current tool file and should not be tracked here.truncate.tsis an Effect service used by tools, not a tool definition itself.mcp-exa.ts,external-directory.ts, andschema.tsare support modules, not standalone tool definitions.
Follow-up cleanup
Most exported tools are already on the intended Effect-native shape. The remaining cleanup is narrower than the old checklist implied.
Current spot cleanups worth tracking:
read.ts— still bridges to Node stream /readlinehelpers and Promise-based binary detectionbash.ts— already uses Effect child-process primitives; only keep tracking shell-specific platform bridges and parser/loading details as they come upwebfetch.ts— already usesHttpClient; remaining work is limited to smaller boundary helpers like HTML text extractionfile/ripgrep.ts— adjacent to tool migration; still has raw fs/process usage that affectsgrep.tsandls.tspatch/index.ts— adjacent to tool migration; still has raw fs usage behind patch application
Notable items that are already effectively on the target path and do not need separate migration bullets right now:
apply_patch.tsgrep.tswrite.tscodesearch.tswebsearch.tsls.tsmultiedit.tsedit.ts
Filesystem notes
Current raw fs users that still appear relevant here:
tool/read.ts—fs.createReadStream,readlinefile/ripgrep.ts—fs/promisespatch/index.ts—fs,fs/promises