Dashboard › opencode › Distillation
94c3b916-6002-49d1-9066-9c78dbf9456f["lore_tm_v1_jM0-gw7qouVTWLeZX-Xnuj4KiOnMaDSD_kSdabQqi1E","lore_tm_v1_DjwWvj5r4qGowz65f0wWP1AJwm3WHxqEZsD-KKYq8mU","lore_tm_v1_gCcnF10dPqjWgySBFGXxJ0K6xbrXZdPzvOyGdjptZm8","lore_tm_v1_HSXkZK_JpChClCgpdPtsHxp0Bth2N8jC5SNPKv6TTG4","lore_tm_v1_1K9WL7dT2MbPY2Q_Prj_lORPiJktnXp4_iqib2IbtnQ","lore_tm_v1_4ElYaMw2qsMMnaRLsmnJi6o1E6rSkRdWYQh4jMUUoKQ","lore_tm_v1_n-KzXXlihLHNdQ_B4IbliH91YH3fLyuVz4hKN_fV7kc","lore_tm_v1_oSbjNM3Ct3hCwISo5ol52jwTNmM3qPMx6uMMNLinLUE","lore_tm_v1_K6a15eJr5StndIXjD_q7gzFOdVO5O9iS173ObycRZX4","lore_tm_v1_8-9RrPjaBdPN2BJ-MG06rXBrORnYvjY4H9CWCjSXjTU","lore_tm_v1_7wx9srZMTGcuteMxokiEfKafbdbbL4x7DDFHOuOO3wM","lore_tm_v1_qlP5wBUM4QajQAG95ysoNndacs7RRCvN2GaAOcgXzaQ","lore_tm_v1_-Em2ISR22oxH3J8aEYCGhi1a-R9WqtLrlIgdcwgNa70","lore_tm_v1_s3HVbFZaoTfCYIEOAY28QGyxdIkVNtVbOxsP91a8FDo"]
Date: Sep 8, 2026
/home/byk/Code/opencode-v2-pilot/packages/core/src/plugin/host.ts imports the plugin-facing domains and Core services used by PluginHost.make. atWorktree(ref, run) rejects workspace locations with Worktree.UnsupportedLocationError, runs directly against the current Worktree.Interface when ref is absent or current, and otherwise defers an import because Plugin construction depends on the host.packages/cli/dist-v2-pilot/cli-node-linux-x64/bin/opencode2-node is 210853060 bytes with SHA-256 7d6999a17d0eca17c8200c4d44679ff13dfa59dd873babb87d9ee9dfa99303b1; packages/cli/dist-v2-pilot-next/cli-node-linux-x64/bin/opencode2-node is 207920324 bytes with SHA-256 6eb1f3d481674cbd8a8f466f2d0943b5cd9f66df993c0ffa8ae91d60b1f1e6e1; packages/cli/dist-v2-pilot-final/cli-node-linux-x64/bin/opencode2-node is 207830212 bytes with SHA-256 67ecda49fa5be3ddb8f7fcb20a33f008a88dea093f0b8c8b10144afa0130f7cf. All have mode 755 and are ELF 64-bit LSB x86-64 SYSV executables, dynamically linked with /lib64/ld-linux-x86-64.so.2, BuildID 01ed129fb51ffd798127b17978435ef452e72ad4, GNU/Linux 3.2.0, debug info present, and not stripped.assert-related matches: /home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/permission.ts:33 exposes PermissionAssertInput => Promise<void>; /home/byk/Code/opencode-v2-pilot/packages/plugin/src/effect/permission.ts:34 exposes PermissionAssertInput => Effect.Effect<void, unknown>; /home/byk/Code/opencode-v2-pilot/packages/core/test/plugin/host.ts:108 has an unused assertion stub; /home/byk/Code/opencode-v2-pilot/packages/core/src/permission.ts:105 returns Effect.Effect<void, Error | SessionErrors.NotFoundError>; /home/byk/Code/opencode-v2-pilot/packages/core/test/plugin.test.ts:452 tests canonical Promise-plugin permission assertions; /home/byk/Code/opencode-v2-pilot/packages/core/src/plugin/host.ts:386 delegates to permission.assert; /home/byk/Code/opencode-v2-pilot/packages/ai/test/recorded-scenarios.ts:206 has an optional response assertion./home/byk/.local/share/opencode/repos/github.com/Effect-TS/effect-smol/packages/effect/src/internal/effect.ts:997-1005 implements Effect.promise(evaluate) with callbackOptions; Promise fulfillment resumes with succeed(a), while rejection resumes with die(e), converting every rejected Promise into a defect. By contrast, tryPromise at lines 1008-1034 catches rejection through a supplied catcher and resumes with a typed failure, while catcher exceptions become defects.worktree.ts, storage.ts, source.ts, source.node.ts, source.bun.ts, rpc.ts, host.ts, options.ts, and app.ts; TUI files tui/context.ts, tui/solid.ts, tui/plugin.ts, and tui/index.ts; Promise files promise/worktree.ts, promise/websearch.ts, promise/vcs.ts, promise/tool.ts, promise/storage.ts, promise/skill.ts, promise/session.ts, promise/rpc.ts, promise/registration.ts, promise/reference.ts, promise/plugin.ts, promise/permission.ts, promise/mcp.ts, promise/integration.ts, promise/index.ts, promise/event.ts, promise/command.ts, promise/catalog.ts, promise/aisdk.ts, promise/agent.ts, promise/adapter.ts, promise/types.ts, and promise/shell.ts; Effect files effect/worktree.ts, effect/websearch.ts, effect/vcs.ts, effect/tool.ts, effect/storage.ts, effect/skill.ts, effect/session.ts, effect/rpc.ts, effect/registration.ts, effect/reference.ts, effect/plugin.ts, effect/permission.ts, effect/mcp.ts, effect/integration.ts, effect/index.ts, effect/event.ts, effect/command.ts, effect/catalog.ts, effect/aisdk.ts, effect/agent.ts, and effect/shell.ts./home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/index.ts exports PluginOptions, storage types, and Plugin; it re-exports schema domains Agent, Command, Connection, Credential, Integration, Location, Mcp, Model, PersistentPty, Provider, Reference, Rpc, Skill, Vcs, WebSearch, and Worktree./home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/plugin.ts defines Promise-plugin Context domains: app, location, options, agent, aisdk, catalog, command, event, experimental.terminal.read, integration, mcp, generate, permission, plugin.list, reference, rpc, session, shell, skill, storage, tool, vcs, websearch, and worktree. Cleanup is () => Promise<void> | void; a Promise Plugin has readonly id and setup(context) returning Promise<Cleanup | void> | Cleanup | void; define(plugin) returns the plugin unchanged./home/byk/Code/opencode-v2-pilot/packages/core/test/plugin.test.ts contains plugin activation-order scenarios: 1. appending c to ["a","b"] expects ["start:c:1"]; 2. inserting x into ["a","b","c"] expects ["stop:c:1","stop:b:1","start:x:1","start:b:1","start:c:1"]; 3. revising b from revision "1" to "2" expects ["stop:c:1","stop:b:1","start:b:2","start:c:1"]; 4. removing trailing c expects ["stop:c:1"]. Another test confirms metadata can change to { type: "package", target: "fixture", outdated: true } without restarting unchanged revision "1" (loads === 1); a live test loads plugin/fixtures/greeting.ts with { description: "Configured greeting" }; an unload test verifies the greet command is removed and cleanup runs./home/byk/Code/opencode-v2-pilot/packages/core/test/plugin/fixture.ts defines PluginTestLayer. Its permission fixture implements ask as { id: input.id ?? Permission.ID.create(), effect: "ask" }, assert and reply as Effect.void, get as undefined, and forSession/list as empty arrays. The layer includes AppProcess.node, FileSystem.node, FSUtil.node, Location.node, Npm.node, Credential.node, Bus.node, Form.node, Generate.node, LayerNodePlatform.httpClient, Plugin.node, Agent.node, AISDK.node, Catalog.node, Command.node, Integration.node, KV.node, Mcp.node, Session.node, PersistentPty.node, LocationServiceMap.node, Permission.node, PluginHooks.node, Reference.node, Rpc.node, Skill.node, SkillDiscovery.node, Tool.node, Vcs.node, Watcher.node, WebSearch.node, and Worktree.node.packages/core/src/plugin/host.ts, packages/core/test/plugin.test.ts, packages/core/test/plugin/host.ts, packages/plugin/src/effect/permission.ts, packages/plugin/src/promise/adapter.ts, and packages/plugin/src/promise/permission.ts; untracked directories were packages/cli/dist-v2-pilot-final/, packages/cli/dist-v2-pilot-next/, and packages/cli/dist-v2-pilot/./home/byk/Code/opencode-v2-pilot/packages/core/src/tool/plugin/shell.ts constructs canonical permission source { type: "tool", messageID: context.messageID, id: context.id }; ShellTool.prepare resolves and canonicalizes cwd, scans the command with optional experimental.portable_shell_scanner, authorizes external directories, asserts shell permission for parsed command resources, then immediately revalidates that the working directory exists and is a directory before spawning. notifyWhenDone waits for a job, creates a synthetic session notification with completed/error/cancelled text, and completes a background notification when applicable.pty_write (pty.ts:261-273) and pty_kill (pty.ts:320-337) set permission: "shell" only for catalog filtering but perform mutations without ctx.permission.assert; both must assert immediately before the side effect using { type: "tool", messageID: context.messageID, id: context.id }. Session ownership at pty.ts:363-366 is not authorization. 2. Concurrent pty_spawn calls can both pass asynchronous authorization and stale count checks before either enters the session map (pty.ts:145-167, pty.ts:226), exceeding both MAX_SESSIONS_PER_OWNER and MAX_SESSIONS; admission must reserve capacity atomically before the first asynchronous spawn boundary and release it on failure. 3. Promise permission correction loses semantics because Effect.runPromiseWith rejects for typed failures and defects, then Promise tool execution wraps rejection in Effect.promise, converting Permission.CorrectedError into an unrecognized defect; the current test at packages/core/test/plugin.test.ts:452-478 covers only success and omits reject-without-feedback, reject-with-feedback, deny, and missing-session cases. 4. The PTY "close" handler resolves session.closed only after ctx.session.synthetic settles (pty.ts:199-225), so terminate may send needless SIGKILL, wait indefinitely, or signal a reused process-group ID; process lifecycle and notification completion need separate promises, with closure resolved immediately.linePage (pty.ts:387-397) emits a phantom empty trailing line because it iterates through index <= input.length; output ending in \n and empty buffers disagree with lineCount (pty.ts:369-374) and continuation metadata (pty.ts:286-298). 2. The write limit and reported βbytesβ use JavaScript data.length (pty.ts:49-53, pty.ts:270-272), so multibyte UTF-8 may exceed 65,536 bytes and be misreported; use Buffer.byteLength(data) or rename the measure to characters. 3. The code attaches the "close" listener only after awaiting "spawn" (pty.ts:164-167, pty.ts:199), allowing a fast child to close before listener attachment and remain permanently marked "running"; lifecycle listeners should be attached before awaiting spawn. 4. The three untracked binary distributions under packages/cli/dist-v2-pilot/, packages/cli/dist-v2-pilot-next/, and packages/cli/dist-v2-pilot-final/ total roughly 626 MB, carry three different pilot package versions, and must not enter the change accidentally.assert is plugin-context-only, not a Protocol or Server HTTP endpoint, so no client generation is needed. 2. PermissionDomain inherits list, get, and reply through Pick<PermissionApi<unknown>, "list" | "get" | "reply"> and adds only plugin-specific operations. 3. Core host delegates to Location-scoped Permission.Service.assert rather than reimplementing policy. 4. Spawn derives permission source from the active tool context. 5. External-directory and shell permission checks finish before process creation. 6. cwd is canonicalized, authorized, re-resolved after approval, identity-checked, verified as a directory, and used for spawn. 7. Command and arguments are independently single-quoted with embedded quotes escaped. 8. Spawn receives a restricted environment with fixed PATH and SHELL. 9. Read, write, list, and kill are scoped to context.sessionID. 10. Runtime output retains only the final MAX_BUFFER_SIZE characters. 11. Ordinary paging scans only until the requested page is filled. 12. Grep bounds pattern length, match count, runtime, stdout, and stderr. 13. Termination is idempotent, targets the process group, suppresses only ESRCH, escalates TERM to KILL, and awaits closure. 14. Session deletion and plugin cleanup terminate owned processes. 15. git diff --check passed.