Dashboard › opencode › Distillation
c5e146a9-ce04-4a17-b373-9195b5d5919b["lore_tm_v1_oMe3F3kVHMJkviIEIJgk8OPApD8Mq10MQxxxUDTubXc","lore_tm_v1_8P-PgstKEviJ7krUJe9FSz8DYSwGVSvR4PsVf5q8Ooc","lore_tm_v1_GPeaFn_T1pnaMxOWVR6d5uSFRQpZ1mCBK-3sIH5juAM","lore_tm_v1_SAyFUQQft4FEiOMC_pj5tbfjGdWPYRYqGqnZR8-WflU"]
Date: Sep 8, 2026
/home/byk/Code/opencode-v2-pilot/packages/core/test/tool-registry.test.ts:18-43 defines an imageStore mock for Image.Service.normalize: corrupt.png fails with Image.DecodeError; too-large.png fails with Image.SizeError using width: 9_000, height: 9_000, maxWidth: 2_000, maxHeight: 2_000, and maxBytes: 5; other images have " normalized" appended to their decoded content, are re-encoded as base64, and change MIME type to image/jpeg. registryLayer uses AppNodeBuilder.build(LayerNode.group([Tool.node, PluginHooks.node]), [Image.node.replace(imageStore)])./home/byk/Code/opencode-v2-pilot/packages/core/test/tool-registry.test.ts:44-53 defines tool-call identity with agent: Agent.ID.make("build"), messageID: SessionMessage.ID.make("msg_registry"), and sessionID: Session.ID.make("ses_registry"). Helper call(name, id = \call-${name}`)creates a"tool-call"with{ id, name, input: { text: name } }`./home/byk/Code/opencode-v2-pilot/packages/core/test/tool-registry.test.ts:55-74 defines helpers: make() returns an echo tool with Schema.Struct({ text: Schema.String }) input/output and echoes { output: { text }, content: text }; constant(text) returns a constant tool that always emits that text; transform(service, tools, options?) invokes service.transform(...) and adds each tool under its record key, using options ?? tool.options./home/byk/Code/opencode-v2-pilot/packages/core/test/tool-registry.test.ts:77-87 tests editor lookup by effective name: adding echo with { namespace: "acme", codemode: false } yields ID acme_echo; editor.get("acme_echo") returns a tool whose original name remains "echo"; editor.get("missing") is undefined./home/byk/Code/opencode-v2-pilot/packages/core/test/tool-registry.test.ts:90-100 begins the test "replays mutations on refreshed sources and restores tools on disposal and scope cleanup": it creates a scope, adds a namespaced echo constant with { namespace: "acme", codemode: false }, adds a hidden echo tool, and provides the mutation effect to that scope./home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/tool.ts exports CallID and Error plus types Metadata, Options, and Result from @opencode/schema/tool. Its promise-facing ToolContext replaces Effect-based progress with (update: Tool.Metadata) => Promise<void>, and its generic Info replaces execute with an async function returning Promise<Tool.Result<Output>>./home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/tool.ts:25-35 defines ToolEditor: list(), get(id), namespace(namespace), add(tool), update(id, update), and remove(id). update receives Types.Mutable<Info>, and missing IDs are explicitly ignored./home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/tool.ts:37-62 defines ToolHooks: "execute.before" carries mutable tool and input plus readonly sessionID, agent, messageID, and id; "execute.after" carries the same identity and readonly input, then either { status: "completed", result: Tool.Result } or { status: "error", error: Tool.Error }./home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/tool.ts:65-69 defines ToolDomain with transform: Transform<ToolEditor>, reload: () => Promise<void>, and hook: Hooks<ToolHooks>.ctx.tool.transform((editor) => ...) usages: /home/byk/Code/opencode-v2-pilot/packages/sdk/test/instances-effect.test.ts:75 and /home/byk/Code/opencode-v2-pilot/packages/server/test/session-instances.test.ts:106./home/byk/Code/opencode-v2-pilot/packages/schema/src/tool.ts defines the canonical browser-safe tool contracts. Tool.CallID is Schema.String.pipe(Schema.brand("Tool.CallID")); Tool.Context contains readonly sessionID, agent, messageID, id, and Effect-based progress: (update: Metadata) => Effect.Effect<void>; Namespace contains readonly name and description./home/byk/Code/opencode-v2-pilot/packages/schema/src/tool.ts:27-42 defines Options as BaseOptions (namespace?, permission?) plus a discriminated constraint: when codemode?: true, pinned?: boolean is allowed; when codemode: boolean, pinned?: never, preventing pinning when codemode is explicitly false./home/byk/Code/opencode-v2-pilot/packages/schema/src/tool.ts:44-59 permits ValueSchema<A> to be Schema.Codec<A, any>, StandardSchemaV1<any, A>, or JsonSchema.JsonSchema. InputValue<S> derives decoded input from Effect Schema or Standard Schema and otherwise returns unknown; OutputValue<S> returns never for undefined, derives encoded output for Standard Schema, and otherwise falls back to any./home/byk/Code/opencode-v2-pilot/packages/schema/src/tool.ts:61-65 defines Tool.Error as Schema.TaggedError with required message: Schema.String and optional error: Schema.Defect() and string-keyed unknown metadata./home/byk/Code/opencode-v2-pilot/packages/schema/src/tool.ts:67-84 defines content variants: TextContent is { type: "text", text: string } with identifier Tool.TextContent; FileContent is { type: "file", uri: string, mime: string, name?: string } with identifier Tool.FileContent; Content is their tagged union on type, identified as Tool.Content./home/byk/Code/opencode-v2-pilot/packages/schema/src/tool.ts:86-102 defines Result<Output> with optional output, optional content as either a string or readonly Content[], and optional metadata. Info<Input, Output> requires readonly name, input, description, and Effect-returning execute(input, context); output and options are optional./home/byk/Code/opencode-v2-pilot/packages/schema/AGENTS.md establishes package boundaries: @opencode/schema owns browser-safe serializable wire/storage contracts, dependency direction must remain @opencode/schema <- @opencode/protocol <- @opencode/server, and runtime registries, service layers, side effects, and host-local behavior stay in their owning domain packages.V1 under src/v1/; permanent V2 names should be removed; new/current code must not depend on the V1 subtree; @opencode/protocol and @opencode/sdk represent current /api/... surfaces.current, shared transitional, or V1-only; V1 emission alone does not justify Protocol or SDK Next inclusion; message.updated and message.part.* remain outside current Protocol/SDK Next unless a current-client requirement is documented; preserve one canonical event definition.PluginID, PluginEvent, PtyInfo, and PtyEvent; use canonical namespace members such as Plugin.ID and Question.Info; domain facades must re-export the exact canonical Schema value; use flat exports plus namespace projections; public leaf packages re-export directly from @opencode/schema/<domain>; resolve collisions through qualified namespaces rather than aliases such as SessionSchema.PascalCase; combinators use camelCase; the static combinator is statics(...); public Schema.Struct records use same-name interface/value pairs; unions, scalars, arrays, branded scalars, and event helpers use type aliases; closed string sets use Schema.Literals(...).optional(...) helper so encoded objects omit undefined; raw Schema.optional(...) is reserved for intentionally encoded undefined; convenience defaults are normally decode-only via Schema.withDecodingDefault(...); public contracts are readonly and must not use Schema.mutable(...); runtime mutation should use Types.DeepMutable, a draft type, or another explicit mutable boundary.Schema.Any, preferring Schema.Json for JSON values and Schema.Unknown for opaque values; current ID constructors expose create(); directional constructors remain only for ordering semantics or compatibility; generated ID validators must exactly match emitted prefixes including _; legacy loose validators must not be tightened without an explicit compatibility/migration decision; public identifiers and brands must be unique and stable.undefined, absence of accidental current-contract Schema.Any, stable and unique public identifiers, exact facade/schema identity, and exclusion of V1-only events from current Protocol manifests.