Dashboard › opencode › Distillation
edc76571-17ee-4237-a5f4-f231d6d6a304["lore_tm_v1_UR-mxHPe8nAAcXmUJwN-rf7I4eeqExc310Bbjru3xPM","lore_tm_v1_ky5FDJrraCsTqh17Y-ItkBHco0PBJ43wx0V19BcKYGE","lore_tm_v1_o2B72laJXNnnNpMTF43FXBij1h4knl1xGRdsQfhTYOU","lore_tm_v1_L2a1rxPylG1fKOPjFkm5JmyEs6lAA4Ve2yrcPS6BuNM","lore_tm_v1_T021oyMtz2jZ1V2KvoPLg7iIpftCyg3U64fe1S2sCHw","lore_tm_v1_AA3SbYaaQY1aQ7GxCRI6d3v8LKkKqrLTLyuUiI5IK0A","lore_tm_v1_l7IAWUpbrIfsH_R5FsRR4sHrWQ1Fbb06LaQO01bRa4Q"]
Date: Sep 15, 2026
sdk-next composes Client, Core, and Server.dev; local main may not exist, so diffs should use dev or origin/dev.feat/ or fix/; examples: session-recovery, fix-scroll-state, regenerate-sdk.type(scope): summary form. Valid types: feat, fix, docs, chore, refactor, test; optional scopes include core, opencode, tui, app, desktop, sdk, and plugin.try/catch and any; prefer Bun APIs such as Bun.file(); rely on type inference; prefer flatMap, filter, and map over loops; bind Effect services to named variables rather than nested yields; inline values used once to reduce variable count.const over let, and ternaries or early returns over reassignment; avoid else statements.Schema.UnknownFromJsonString and Schema.decodeUnknownOption over manual JSON.parse wrapped in Effect.try.snake_case directly so column names do not need explicit string mappings.src/config modules to follow the self-export pattern, e.g. export * as ConfigAgent from "./agent"../packages/sdk/js/script/build.ts.bun run generate from packages/client after changing the public Protocol or Server HttpApi; src/generated and src/generated-effect must not be edited directly.import { foo as bar } from "..." and resolve as pathResolve.import * as Foo from "..." and import type * as Foo from "...". Namespace-style values should use the module’s own exported namespace, e.g. import { Project } from "@opencode-ai/core/project" followed by Project.ID.await import("./module").then((mod) => mod.value()) and (await import("./module")).value() are forbidden.globalThis.* unless they are the only option; test actual implementation without duplicating its logic; tests cannot run from repository root because of the do-not-run-tests-from-root guard and must run from package directories such as packages/opencode.bun typecheck from package directories such as packages/opencode; never run tsc directly.SessionV2.prompt(...) must durably admit one session_input row before advisory SessionExecution.wake(sessionID) scheduling, except resume: false requests admit-only behavior; the serialized runner promotes admitted inputs into visible user messages only at safe boundaries.SessionExecution to remain process-global and Session-ID based. Its local implementation owns the process-local Session coordinator and discovers placement through SessionStore plus LocationServiceMap.get(session.location) only when a drain starts; no layer takes a Session ID. V2 interruption targets the active local ownership chain, while idle or missing interruption is a no-op.SessionRunner, model resolution, tool registry, permissions, and filesystem to remain Location-scoped. Missing Location.workspaceID means implicit-local placement; explicit workspace identity is reserved for future placement semantics.llm.stream(request) call per provider turn and projected-history reload before durable continuation; orchestration must not bridge through legacy SessionPrompt.loop(...) or an in-memory tool loop.SessionRunCoordinator joins explicit same-Session resumes, coalesces prompt wakeups, and allows different Sessions to run concurrently. Advisory wakes drain only eligible durable inbox rows; post-crash provider-work retries require a separate explicit design. A drain has no durable identity or transcript boundary.steer and promote at the next safe provider-turn boundary while continuation is required; explicit queue input remains pending until the Session would otherwise become idle, then one queued input is promoted before continuation is reevaluated. Any promoted user input resets the selected agent’s provider-turn allowance; a batch of steers resets it once.src/system-context; Context Source producers stay with their observed domains; Session History selection and Context Epoch persistence remain Session-owned.packages/core/test/session-run-coordinator.test.ts has tests for: joining wake-started execution without forcing a successor; coalescing wakes during active execution; idle interruption as a no-op; interrupting active execution and clearing its pending wake; running a wake registered during interruption cleanup; starting a resume registered during interruption cleanup; starting one follow-up when wake races with failure; and not cancelling execution when a joined waiter is interrupted.packages/core/src/database/migration/20260914170650_session-recovery.ts with ID "20260914170650_session-recovery", dynamically imported by packages/core/src/database/migration.gen.ts; packages/core/src/session/recovery.ts names its node "session-recovery" with dependencies [Database.node, EventV2.node, SessionProjector.node, SessionExecution.node].packages/core/src/session.ts changed durable prompt admission to pass requestExecution: input.resume !== false alongside sessionID, prompt, and delivery, explicitly recording whether admitted input requests execution.packages/server/src/routes.ts includes SessionRecovery.node in applicationServices and builds the service layer with AppNodeBuilder.build(applicationServices, [[SessionExecution.node, SessionExecutionLocal.node]]), binding process-global SessionExecution to its local implementation.packages/server/src/routes.ts route construction provides, in order, handlers, sessionLocationLayer, locationLayer, authorizationLayer, schemaErrorLayer, authentication, and the built service layer to HttpApiBuilder.layer(Api, { openapiPath: "/openapi.json" }); webHandler disables logging via { disableLogger: true }.