Dashboard › opencode › Distillation
c20b7207-131b-4362-bc17-c54793941b23["lore_tm_v1_T37h4PGnWSGXqYADFTHR6thMluoP4xi02vXe6jXTKxE","lore_tm_v1_j1mYXuLsa9zoUu6AeA8tn0CMUWi6Pm5ZAzwZYg0Cu64","lore_tm_v1_yhfknjbUgEfaUEulwq36yOrTiUIVaafoqt_eyCUNoD8","lore_tm_v1_rPwhlfyna6Q0rqz6jweuDY7Mroa_9VV_c7dqnqYvZWo","lore_tm_v1_tMDTUKqKH4h2jSqLmEnVh7_gipK5bX2gHWWfkn0lt7E","lore_tm_v1_YWEpFFtFxS7ongPUhqza5rEFSUvrFTYnuM2ZHOKRzRc","lore_tm_v1_yMgRBCWMLa6gXU6kupI6cQIXpl1HLwi1cA1RNVy09N4","lore_tm_v1_yxHH6LIHItZXi26HendddseNWWkIpix8rRvd29hCCYw","lore_tm_v1_RYrOZxGmmzFv0sffXK5Y55v1dnWct6C5n0kmz8ZrNOA"]
Date: Sep 16, 2026
/tmp/opencode/session-recovery-v5-review.r03hHL/AGENTS.md requires regenerating the legacy JavaScript SDK with ./packages/sdk/js/script/build.ts; after public Protocol or Server HttpApi changes, run bun run generate from packages/client and never edit src/generated or src/generated-effect directly.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 are session-recovery, fix-scroll-state, and regenerate-sdk.type(scope): summary; valid types are feat, fix, docs, chore, refactor, and test, with optional scopes such as core, opencode, tui, app, desktop, sdk, or plugin.try/catch, any, unnecessary destructuring, reassignment, and else; preferring Bun APIs, inferred types, functional array methods, const, ternaries, and early returns.import { foo as bar } from "..." or resolve as pathResolve.import * as Foo from "..." and import type * as Foo from "..."; import a moduleβs own exported namespace by name, such as import { Project } from "@opencode-ai/core/project", and reference Project.ID.await import("./module").then(...) or (await import("./module")).value() are disallowed.do-not-run-tests-from-root guard; tests must run from package directories such as packages/opencode. Tests should avoid mocks and globalThis.*, and exercise the actual implementation rather than duplicating logic.bun typecheck from package directories such as packages/opencode; never invoke tsc directly.SessionV2.prompt(...) to durably admit exactly one session_input row before advisory SessionExecution.wake(sessionID), except resume: false requests admit-only behavior; the serialized runner promotes admitted inputs at safe boundaries.SessionExecution must 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 should take a Session ID. V2 interruption targets the active process-local ownership chain, while idle or missing interruption is a no-op.SessionRunner, model resolution, tool registry, permissions, and filesystem must remain Location-scoped. Omitted Location.workspaceID means implicit-local placement; explicit workspace identity is reserved for future placement semantics.llm.stream(request) call and reload projected history 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 permits different Sessions to run concurrently. Advisory wakes drain only eligible durable inbox rows; post-crash provider-work continuation requires a separate explicit design. A drain has no durable identity or transcript boundary.queue remains pending until the Session would otherwise 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 remain with their observed domains; Session History selection and Context Epoch persistence remain Session-owned.CONTRIBUTING.md requires Bun 1.3+; repository setup uses bun install and bun dev. The default headless server port is 4096, overrideable with bun dev serve --port 8080; the web app starts with bun run --cwd packages/app dev and commonly serves at http://localhost:5173.Fixes #123 or Closes #123; UI PRs require before/after screenshots or videos, and logic changes must explain verification and reproduction. Net-new functionality requires a design conversation and approval before opening a feature PR.packages/opencode/AGENTS.md states Drizzle schema lives in packages/core/src/**/*.sql.ts, while migrations live in packages/core and are applied by core.bun dev from packages/opencode starts the interactive TUI and must not be left as a blocking foreground process when inspecting results. Required detached workflow: start with tmux new-session -d -s opencode-dev 'bun dev', inspect with tmux capture-pane -pt opencode-dev, and stop with tmux kill-session -t opencode-dev.export namespace Foo { ... }; use flat top-level exports and a self-reexport such as export * as Foo from "./foo". For a single-namespace directoryβs index.ts, use export * as Foo from ".". Multi-sibling directories such as src/session/ and src/config/ must not add barrel index.ts files; consumers import specific siblings.Effect.gen(function* () { ... }), Effect.fn("Domain.method") for named/traced effects, Effect.fnUntraced for internal helpers, Effect.callback for callback APIs, Effect.void instead of Effect.succeed(undefined) or Effect.succeed(void 0), and DateTime.nowAsDate instead of new Date(yield* Clock.currentTimeMillis).Schema.Class for multi-field data, Schema.brand for single-value types, Schema.TaggedErrorClass for typed errors, and Schema.Defect rather than unknown for defect-like causes. Direct early failures in Effect.gen/Effect.fn should use yield* new MyError(...).makeRuntime from src/effect/run-service.ts, which returns { runPromise, runFork, runCallback } backed by a shared memoMap. Per-directory/project state requiring cleanup must use InstanceState from src/effect/instance-state.ts, whose ScopedCache is keyed by directory.InstanceState.make must perform work directly without extra fibers, ensure() callbacks, or started flags. Cleanup uses Effect.addFinalizer or Effect.acquireRelease; background consumers use Effect.forkScoped. Non-blocking init() behavior is controlled at the call site with Effect.forkIn(scope), while src/project/bootstrap.ts already wraps every service init() in Effect.forkDetach.Effect.fork or Effect.forkDaemon; use Effect.forkIn(scope).FileSystem.FileSystem over raw fs/promises, ChildProcessSpawner.ChildProcessSpawner with ChildProcess.make(...) over custom process wrappers, HttpClient.HttpClient over raw fetch, and Effect-provided Path.Path, Config, Clock, and DateTime. Scheduled/background loops use Effect.repeat or Effect.schedule with Effect.forkScoped.Effect.cached, not manually stored Fiber | undefined or Promise | undefined. Native/external callbacks such as @parcel/watcher, node-pty, native fs.watch, and plugin callbacks should re-enter Effect through EffectBridge, not ambient instance-context shims.packages/schema/AGENTS.md defines @opencode-ai/schema as owner of browser-safe wire/storage contracts; runtime behavior, service layers, side effects, registries, and host-local implementation remain in their domain packages. Dependency direction is @opencode-ai/schema <- @opencode-ai/protocol <- @opencode-ai/server.Session, Permission, Question); retained legacy contracts use explicit V1 names. V2 must not remain as the permanent replacement-architecture name. New/current code must not depend on the future isolated src/v1/ subtree.current, shared transitional, or V1-only. V1-only events such as message.updated and message.part.* stay out of current Protocol/SDK Next unless a current-client requirement is documented; definitions must remain canonical rather than duplicated for generation.Schema.mutable(...); mutation belongs at runtime boundaries through Types.DeepMutable, a dedicated draft type, or another explicit mutable API.Schema.Any; use Schema.Json for JSON-serializable values and Schema.Unknown for opaque values needing consumer narrowing. Schema.Any is allowed only at explicitly unsafe compatibility boundaries with a documented reason.Model.Ref or Agent.Color.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.packages/opencode/src/server/routes/instance/httpapi/AGENTS.md requires HttpApiBuilder.group(...) for normal and SSE HTTP endpoints; SSE handlers return HttpServerResponse.stream(...) and annotate success with HttpApiSchema.asText({ contentType: "text/event-stream" }).HttpApiBuilder.group(...) with handleRaw(...). Raw HttpRouter.use(...) is only for routes outside the declared API, such as catch-all UI fallback.Effect.provide(SomeLayer) to rebuild stable layers per request. Stable services are yielded once while constructing the handler layer. HttpRouter.provideRequest(...) is reserved for intentional request-level dependencies; Effect.provideService(...) in middleware is only for request-derived context such as WorkspaceRouteContext, InstanceRef, or WorkspaceRef.Schema.ErrorClass contracts. Built-in HttpApiError.* is only appropriate when its empty/tagged body is the intended wire shape; SDK-visible errors with messages require an exact declared schema such as ApiNotFoundError. Domain/storage services remain free of HttpApi types, with expected errors translated at the handler boundary.package.json identifies package manager bun@1.3.14, root typecheck as bun turbo typecheck, root test as echo 'do not run tests from root' && exit 1, Prettier configuration semi: false and printWidth: 120, TypeScript 5.8.2, and Effect 4.0.0-beta.83.packages/core/package.json identifies @opencode-ai/core version 1.18.30; its test script is bun test --only-failures, and its typecheck script is tsgo --noEmit.packages/schema/package.json identifies @opencode-ai/schema; its typecheck script is tsgo --noEmit.packages/server/package.json identifies @opencode-ai/server version 1.18.30; its typecheck script is tsgo --noEmit, and its dependencies include @opencode-ai/core, @opencode-ai/protocol, drizzle-orm, and effect.