2026-07-03 01:13:52 +08:00
<!-- Generated by scripts/gen - doc - graphs.ts - do not edit by hand.
Run `pnpm run gen-doc-graphs` to regenerate. -->
# Capability Seams And Core Services
A service can be a core spine service, a swappable capability seam, or a bundle/composition point. The graph shows the package that owns the service declaration, known implementation packages, and packages that consume the service directly.
```mermaid
flowchart LR
pkg_llm["llm"]
svc_llm["ctx.llm< br / > LLM adapter registry"]
pkg_llm_deepseek["llm-deepseek"]
pkg_llm_pi_ai["llm-pi-ai"]
pkg_llm_replay["llm-replay"]
pkg_agent_loop["agent-loop"]
pkg_compact_basic["compact-basic"]
2026-07-15 14:47:29 +08:00
pkg_token_meter["token-meter"]
svc_tokenMeter["ctx.tokenMeter< br / > Replay token measurement"]
2026-07-16 18:51:26 +08:00
pkg_compact_tool_result_prune["compact-tool-result-prune"]
2026-07-16 18:02:15 +08:00
svc_toolResultPrune["ctx.toolResultPrune< br / > Model-free tool-result pruning"]
2026-07-03 01:13:52 +08:00
pkg_session["session"]
svc_sessions["ctx.sessions< br / > In-memory session store"]
pkg_agent["agent"]
2026-07-15 21:21:24 +08:00
pkg_cli_demo["cli-demo"]
2026-07-03 01:13:52 +08:00
pkg_session_persistence["session-persistence"]
2026-07-10 16:51:19 +08:00
pkg_session_query["session-query"]
2026-07-15 10:51:38 +08:00
pkg_session_query_sqlite["session-query-sqlite"]
2026-07-03 01:13:52 +08:00
pkg_subagent_inprocess["subagent-inprocess"]
pkg_invariants["invariants"]
2026-07-19 19:19:57 +08:00
svc_invariants["ctx.invariants< br / > Package-owned invariant registry"]
pkg_scope["scope"]
2026-07-03 01:13:52 +08:00
svc_sessionPersistence["ctx.sessionPersistence< br / > Durable session persistence seam"]
pkg_session_persistence_jsonl["session-persistence-jsonl"]
pkg_session_persistence_sqlite["session-persistence-sqlite"]
fix(bash): close managed environment review gaps
The managed DSH_* runtime path was correct, but its public extension and documentation contracts were incomplete. A contributor following the README could access ctx.bashEnv without declaring an injection, the new environment types had no drift-checked catalog entries, and the capability graph omitted three packages that now query sessionPersistence.
Declare the README injection, catalog DshEnvironmentKey and DshEnvironment, and add tool-bash plus both hook bridges to the generated persistence consumer graph. Keep BashEnvRegistry.list() contributor-only for now because no production caller treats it as exhaustive, but record the built-in enumeration gap before diagnostics, prompt, or UI code depends on it.
Validated on the exact resulting tree with typecheck, lint, coverage, snapshot, documentation, module-graph, build, hygiene, demo-smoke, and built-artifact checks.
2026-07-15 00:04:00 +08:00
pkg_tool_bash["tool-bash"]
pkg_hooks_claude["hooks-claude"]
pkg_hooks_codex["hooks-codex"]
2026-07-03 01:13:52 +08:00
pkg_acp["acp"]
2026-07-23 20:16:14 +08:00
svc_sessionQuery["ctx.sessionQuery< br / > Session reads, traces, filters, and search"]
2026-07-21 16:46:48 +08:00
pkg_session_reference["session-reference"]
svc_sessionReferences["ctx.sessionReferences< br / > Cross-session snapshot preparation"]
pkg_tui["tui"]
2026-07-21 01:54:00 +08:00
pkg_session_title["session-title"]
svc_sessionTitle["ctx.sessionTitle< br / > Log-backed session titles"]
pkg_session_title_first_message_llm["session-title-first-message-llm"]
pkg_session_title_all_messages_llm["session-title-all-messages-llm"]
2026-07-03 01:13:52 +08:00
pkg_system_prompt["system-prompt"]
svc_systemPrompt["ctx.systemPrompt< br / > System prompt assembly registry"]
pkg_tools["tools"]
2026-07-04 12:50:06 +08:00
pkg_tool_fs["tool-fs"]
2026-07-21 16:01:00 +08:00
pkg_tool_pty["tool-pty"]
2026-07-04 12:50:06 +08:00
pkg_tool_web["tool-web"]
2026-07-11 22:55:40 +08:00
svc_tools["ctx.tools< br / > Tool registry and guarded execution pipeline"]
2026-07-05 17:05:33 +08:00
pkg_tool_ask_user["tool-ask-user"]
2026-07-08 11:50:12 +08:00
pkg_tool_cordis["tool-cordis"]
2026-07-05 16:50:29 +08:00
pkg_tool_skill["tool-skill"]
2026-07-03 01:13:52 +08:00
pkg_tool_subagent["tool-subagent"]
pkg_tool_todo["tool-todo"]
2026-07-05 17:05:33 +08:00
pkg_user_interaction["user-interaction"]
svc_userInteraction["ctx.userInteraction< br / > Human question/answer seam"]
2026-07-22 16:57:23 +08:00
pkg_plan_mode["plan-mode"]
svc_planMode["ctx.planMode< br / > Plan collaboration state"]
2026-07-19 22:11:59 +08:00
pkg_commands["commands"]
svc_commands["ctx.commands< br / > Human command registry"]
2026-07-22 21:30:08 -07:00
svc_tui["ctx.tui< br / > Mounted-terminal interaction service"]
2026-07-05 16:50:29 +08:00
pkg_skill["skill"]
2026-07-08 15:50:38 +08:00
svc_skills["ctx.skills< br / > Skill provider registry"]
pkg_skill_local["skill-local"]
2026-07-19 13:30:45 +08:00
svc_agents["ctx.agents< br / > Agent service"]
2026-07-20 19:26:04 +08:00
pkg_tui_demo["tui-demo"]
2026-07-03 01:13:52 +08:00
svc_agentLoop["ctx.agentLoop< br / > Concrete loop driver"]
2026-07-15 15:57:57 +08:00
pkg_agent_spine_demo["agent-spine-demo"]
2026-07-19 18:47:34 +08:00
pkg_goal["goal"]
svc_goals["ctx.goals< br / > Same-session goal domain"]
2026-07-03 01:13:52 +08:00
pkg_bash["bash"]
svc_bash["ctx.bash< br / > Bash executor seam"]
pkg_bash_local["bash-local"]
2026-07-09 16:05:44 +08:00
pkg_bash_sandbox["bash-sandbox"]
2026-07-12 15:41:42 +08:00
svc_bashEnv["ctx.bashEnv< br / > Managed bash environment registry"]
2026-07-21 16:01:00 +08:00
pkg_pty["pty"]
svc_pty["ctx.pty< br / > Persistent PTY session registry"]
pkg_pty_local["pty-local"]
2026-07-09 15:42:37 +08:00
pkg_sandbox["sandbox"]
svc_sandbox["ctx.sandbox< br / > Process-sandbox seam"]
pkg_sandbox_local["sandbox-local"]
2026-07-20 13:59:18 +08:00
pkg_sandbox_policy["sandbox-policy"]
feat(sandbox): cross-family file sandbox — one policy home, sandboxed fs provider, fs escalation parity
Extend SandboxMode enforcement from bash to the filesystem tools, the sandbox
RFC's deferred cross-family phase.
- dsh-sandbox-policy (new, ctx.sandboxPolicy): the single home for the
deployment default mode + workspaceRoot and the per-session override event,
renamed bash/sandbox-mode -> sandbox/mode and moved here with its fold/setter.
Decouples the bash seam from dsh-session.
- dsh-fs-sandbox (new): SandboxedFileSystem extends LocalFileSystem and fences
write/edit by the per-call mode (read-only denies, workspace-write contains to
the workspace + temp roots via the shared writableRoots, danger passes
through); reads pass through. Structured FS_SANDBOX_DENIED; in-lock parent
re-canonicalization. A policy fence in trusted code, not a kernel boundary.
- dsh-sandbox: the shared escalation kit (writableRoots, the strictly-wider
ladder, denial/hint markers, approveEscalation) both tool families use;
approveEscalation takes a structural approver so dsh-sandbox gains no
approval/agent dependency, and both tools stay duplication-free.
- tool-fs: write/edit advertise sandbox_permissions/justification under a
confining ctx.fs, map FS_SANDBOX_DENIED to the shared [sandbox: ...] marker,
and resolve the same one-approved-wider retry.
- examples/acp-agent: composes sandbox-policy + fs-sandbox, drops the gating
that disabled the fs stack under confined modes.
RFC docs/rfc/implemented/feature/2026-07-14-cross-family-fs-sandbox.md; the old
sandbox RFC's In-process/deferred/FAQ sections updated to shipped fact.
2026-07-14 20:05:57 +08:00
svc_sandboxPolicy["ctx.sandboxPolicy< br / > Sandbox policy home"]
pkg_fs_sandbox["fs-sandbox"]
2026-07-09 15:25:18 +08:00
pkg_approval["approval"]
svc_approval["ctx.approval< br / > Approval seam"]
feat(permission): user-facing permission presets — one Permissions select over the two knobs
A preset names a bundle of the two mechanism knobs — request =
workspace-write + ask, yolo = danger-full-access + never — so the editor
shows ONE 'Permissions' select where the sandbox-mode and approval-policy
tiers stay orthogonal capabilities (the Codex /approvals shape: presets over
two dials). ctx.permission (dsh-permission) owns the config-defined table,
validates the default preset's bundle against the composed knob defaults at
load (fails loud), and writes a switch THROUGH: one log-only
permission/preset event (the audit fact reverse-mapping cannot recover —
the planned 'agent' preset shares request's knob values and differs only in
composed policy) plus each knob event via its own setter, deduped — a
net-zero switch appends nothing. Every knob consumer keeps reading its own
fold, untouched.
The current preset DERIVES from the effective knob values — the fold breaks
bundle ties, a knob state outside the table is the reserved 'custom' value
(a state, not an error: shown while it holds, switchable FROM, never a
target), and defaultPreset disappears (zero-event state reverse-maps from
the composition defaults).
The ACP bridge drops the two per-knob selects for the one preset select
(advertised only when ctx.permission is composed); pending/anchor/no-op
semantics carry over unchanged, with the no-op echo acknowledged before
vocabulary validation so a client re-pushing a derived 'custom' current
never errors. The sandbox variant example composes the
service with a workspace-write default; the permission-switching,
escalation-approved and escalation-rejected scenarios are re-recorded under
it (escalations now target an outside-workspace /tmp path under
danger-full-access, self-cleaning) and config-options is re-authored on the
single-select wire.
2026-07-12 21:03:41 +08:00
pkg_permission["permission"]
svc_permission["ctx.permission< br / > Permission presets"]
2026-07-08 02:17:24 +08:00
pkg_code_runtime["code-runtime"]
svc_codeRuntime["ctx.codeRuntime< br / > Code-execution seam"]
feat: add the worker-thread code runtime (dsh-code-runtime-worker)
The shipped backend of the code-execution seam, per the Code Mode RFC's
worker-thread section: one fresh Node worker per run, executing the
model's TypeScript after a host-side type-strip (wrapped in an
async-function shell so top-level return/await parse, sliced back out
position-preserved), bindings bridged over the message port under
hostile-peer rules (own-property name lookup, at-most-once replies,
post-settlement drops, null-prototype namespaces), logs streamed eagerly
with an in-band truncation marker, and two independent budgets — measured
event-loop busy time (computeMs) plus a never-pausing wall ceiling
(maxWallMs) — funneling into worker.terminate(). env: {} and execArgv: []
keep the isolate hermetic; disposal aborts in-flight runs and awaits
worker exits.
The worker entry loads unbuilt via Node's native type stripping
(src/worker.ts, erasable-only) and ships built as a sibling tsdown bundle
(lib/worker.js); tests/built-lib.e2e.ts pins the built load path under
plain node and joins the built-artifact smoke gate. Unit suites cover the
bootstrap in-process (fake port) and the runtime over real workers,
per-file 100%.
2026-07-08 11:00:06 +08:00
pkg_code_runtime_worker["code-runtime-worker"]
2026-07-04 12:50:06 +08:00
pkg_fs["fs"]
svc_fs["ctx.fs< br / > Filesystem provider seam"]
pkg_fs_local["fs-local"]
pkg_fs_policy["fs-policy"]
2026-07-03 01:13:52 +08:00
pkg_compact["compact"]
svc_compact["ctx.compact< br / > Compaction seam"]
pkg_subagent["subagent"]
svc_subagents["ctx.subagents< br / > Subagent provider registry"]
pkg_subagent_spawn["subagent-spawn"]
pkg_subagent_fork["subagent-fork"]
pkg_subagent_acp["subagent-acp"]
2026-07-20 00:51:19 +08:00
pkg_tool_ralph["tool-ralph"]
feat(tasks): background task runtime, generic task_* control tools, bash/subagent producers
One shared ctx.tasks registry (branded <kind>-N ids, owner-fenced
read/kill/wait/list, attachSurface misconfiguration fence, reported-flag
notice dedup, atomic register) + dsh-tool-tasks (task_output/task_list/
task_kill, completion-notice injection, background prompt habit).
Producers opt in via their own enableRunInBackground config: bash
(stream kind; seam slimmed to resolve/run/start returning a BashProcess
handle, bash_output/bash_kill deleted) and subagent (final-output kind;
done settles after run.dispose()). Owner disposal drains tasks through
the new awaited ctx.agents.onCleanup seam in the loop's disposal chain.
Both RFCs moved to implemented/; docs, catalogs, snapshots re-pinned.
2026-07-09 21:22:54 +08:00
pkg_tasks["tasks"]
svc_tasks["ctx.tasks< br / > Background task registry"]
pkg_tool_tasks["tool-tasks"]
2026-07-04 12:50:06 +08:00
pkg_web["web"]
svc_web["ctx.web< br / > Web access provider registry"]
pkg_web_search_exa["web-search-exa"]
pkg_web_search_perplexity["web-search-perplexity"]
pkg_web_search_deepseek["web-search-deepseek"]
pkg_web_fetch_local["web-fetch-local"]
2026-07-08 19:20:50 +08:00
pkg_spill["spill"]
2026-07-13 11:07:27 +08:00
svc_spillStore["ctx.spillStore< br / > Spill storage seam"]
2026-07-08 19:20:50 +08:00
pkg_spill_local["spill-local"]
pkg_spill_policy["spill-policy"]
2026-07-06 03:14:07 +08:00
pkg_workflow["workflow"]
svc_workflows["ctx.workflows< br / > Workflow script engine"]
2026-07-09 19:06:55 +08:00
pkg_workflow_workerthread["workflow-workerthread"]
2026-07-06 03:14:07 +08:00
pkg_tool_workflow["tool-workflow"]
2026-07-09 15:36:08 +08:00
pkg_acp --> svc_approval
2026-07-05 17:05:33 +08:00
pkg_acp --> svc_userInteraction
2026-07-03 01:13:52 +08:00
pkg_agent --> svc_agents
pkg_agent_loop --> svc_agentLoop
2026-07-09 15:25:18 +08:00
pkg_approval --> svc_approval
2026-07-03 01:13:52 +08:00
pkg_bash --> svc_bash
pkg_bash_local --> svc_bash
2026-07-09 16:05:44 +08:00
pkg_bash_sandbox --> svc_bash
2026-07-08 02:17:24 +08:00
pkg_code_runtime --> svc_codeRuntime
feat: add the worker-thread code runtime (dsh-code-runtime-worker)
The shipped backend of the code-execution seam, per the Code Mode RFC's
worker-thread section: one fresh Node worker per run, executing the
model's TypeScript after a host-side type-strip (wrapped in an
async-function shell so top-level return/await parse, sliced back out
position-preserved), bindings bridged over the message port under
hostile-peer rules (own-property name lookup, at-most-once replies,
post-settlement drops, null-prototype namespaces), logs streamed eagerly
with an in-band truncation marker, and two independent budgets — measured
event-loop busy time (computeMs) plus a never-pausing wall ceiling
(maxWallMs) — funneling into worker.terminate(). env: {} and execArgv: []
keep the isolate hermetic; disposal aborts in-flight runs and awaits
worker exits.
The worker entry loads unbuilt via Node's native type stripping
(src/worker.ts, erasable-only) and ships built as a sibling tsdown bundle
(lib/worker.js); tests/built-lib.e2e.ts pins the built load path under
plain node and joins the built-artifact smoke gate. Unit suites cover the
bootstrap in-process (fake port) and the runtime over real workers,
per-file 100%.
2026-07-08 11:00:06 +08:00
pkg_code_runtime_worker --> svc_codeRuntime
2026-07-19 22:11:59 +08:00
pkg_commands --> svc_commands
2026-07-03 01:13:52 +08:00
pkg_compact --> svc_compact
pkg_compact_basic --> svc_compact
2026-07-16 18:51:26 +08:00
pkg_compact_tool_result_prune --> svc_toolResultPrune
2026-07-04 12:50:06 +08:00
pkg_fs --> svc_fs
pkg_fs_local --> svc_fs
feat(sandbox): cross-family file sandbox — one policy home, sandboxed fs provider, fs escalation parity
Extend SandboxMode enforcement from bash to the filesystem tools, the sandbox
RFC's deferred cross-family phase.
- dsh-sandbox-policy (new, ctx.sandboxPolicy): the single home for the
deployment default mode + workspaceRoot and the per-session override event,
renamed bash/sandbox-mode -> sandbox/mode and moved here with its fold/setter.
Decouples the bash seam from dsh-session.
- dsh-fs-sandbox (new): SandboxedFileSystem extends LocalFileSystem and fences
write/edit by the per-call mode (read-only denies, workspace-write contains to
the workspace + temp roots via the shared writableRoots, danger passes
through); reads pass through. Structured FS_SANDBOX_DENIED; in-lock parent
re-canonicalization. A policy fence in trusted code, not a kernel boundary.
- dsh-sandbox: the shared escalation kit (writableRoots, the strictly-wider
ladder, denial/hint markers, approveEscalation) both tool families use;
approveEscalation takes a structural approver so dsh-sandbox gains no
approval/agent dependency, and both tools stay duplication-free.
- tool-fs: write/edit advertise sandbox_permissions/justification under a
confining ctx.fs, map FS_SANDBOX_DENIED to the shared [sandbox: ...] marker,
and resolve the same one-approved-wider retry.
- examples/acp-agent: composes sandbox-policy + fs-sandbox, drops the gating
that disabled the fs stack under confined modes.
RFC docs/rfc/implemented/feature/2026-07-14-cross-family-fs-sandbox.md; the old
sandbox RFC's In-process/deferred/FAQ sections updated to shipped fact.
2026-07-14 20:05:57 +08:00
pkg_fs_sandbox --> svc_fs
2026-07-19 18:47:34 +08:00
pkg_goal --> svc_goals
2026-07-19 19:19:57 +08:00
pkg_invariants --> svc_invariants
2026-07-03 01:13:52 +08:00
pkg_llm --> svc_llm
pkg_llm_deepseek --> svc_llm
pkg_llm_pi_ai --> svc_llm
pkg_llm_replay --> svc_llm
feat(permission): user-facing permission presets — one Permissions select over the two knobs
A preset names a bundle of the two mechanism knobs — request =
workspace-write + ask, yolo = danger-full-access + never — so the editor
shows ONE 'Permissions' select where the sandbox-mode and approval-policy
tiers stay orthogonal capabilities (the Codex /approvals shape: presets over
two dials). ctx.permission (dsh-permission) owns the config-defined table,
validates the default preset's bundle against the composed knob defaults at
load (fails loud), and writes a switch THROUGH: one log-only
permission/preset event (the audit fact reverse-mapping cannot recover —
the planned 'agent' preset shares request's knob values and differs only in
composed policy) plus each knob event via its own setter, deduped — a
net-zero switch appends nothing. Every knob consumer keeps reading its own
fold, untouched.
The current preset DERIVES from the effective knob values — the fold breaks
bundle ties, a knob state outside the table is the reserved 'custom' value
(a state, not an error: shown while it holds, switchable FROM, never a
target), and defaultPreset disappears (zero-event state reverse-maps from
the composition defaults).
The ACP bridge drops the two per-knob selects for the one preset select
(advertised only when ctx.permission is composed); pending/anchor/no-op
semantics carry over unchanged, with the no-op echo acknowledged before
vocabulary validation so a client re-pushing a derived 'custom' current
never errors. The sandbox variant example composes the
service with a workspace-write default; the permission-switching,
escalation-approved and escalation-rejected scenarios are re-recorded under
it (escalations now target an outside-workspace /tmp path under
danger-full-access, self-cleaning) and config-options is re-authored on the
single-select wire.
2026-07-12 21:03:41 +08:00
pkg_permission --> svc_permission
2026-07-22 16:57:23 +08:00
pkg_plan_mode --> svc_planMode
2026-07-21 16:01:00 +08:00
pkg_pty --> svc_pty
pkg_pty_local --> svc_pty
2026-07-09 15:42:37 +08:00
pkg_sandbox --> svc_sandbox
pkg_sandbox_local --> svc_sandbox
2026-07-20 13:59:18 +08:00
pkg_sandbox_policy --> svc_sandboxPolicy
2026-07-03 01:13:52 +08:00
pkg_session --> svc_sessions
pkg_session_persistence --> svc_sessionPersistence
pkg_session_persistence_jsonl --> svc_sessionPersistence
pkg_session_persistence_sqlite --> svc_sessionPersistence
2026-07-10 16:51:19 +08:00
pkg_session_query --> svc_sessionQuery
2026-07-23 20:16:14 +08:00
pkg_session_query_sqlite --> svc_sessionQuery
2026-07-21 16:46:48 +08:00
pkg_session_reference --> svc_sessionReferences
2026-07-21 01:54:00 +08:00
pkg_session_title --> svc_sessionTitle
pkg_session_title_all_messages_llm --> svc_sessionTitle
pkg_session_title_first_message_llm --> svc_sessionTitle
2026-07-05 16:50:29 +08:00
pkg_skill --> svc_skills
2026-07-10 14:19:06 +08:00
pkg_skill_local --> svc_skills
2026-07-13 11:07:27 +08:00
pkg_spill --> svc_spillStore
pkg_spill_local --> svc_spillStore
2026-07-03 01:13:52 +08:00
pkg_subagent --> svc_subagents
pkg_subagent_acp --> svc_subagents
pkg_subagent_fork --> svc_subagents
pkg_subagent_spawn --> svc_subagents
pkg_system_prompt --> svc_systemPrompt
feat(tasks): background task runtime, generic task_* control tools, bash/subagent producers
One shared ctx.tasks registry (branded <kind>-N ids, owner-fenced
read/kill/wait/list, attachSurface misconfiguration fence, reported-flag
notice dedup, atomic register) + dsh-tool-tasks (task_output/task_list/
task_kill, completion-notice injection, background prompt habit).
Producers opt in via their own enableRunInBackground config: bash
(stream kind; seam slimmed to resolve/run/start returning a BashProcess
handle, bash_output/bash_kill deleted) and subagent (final-output kind;
done settles after run.dispose()). Owner disposal drains tasks through
the new awaited ctx.agents.onCleanup seam in the loop's disposal chain.
Both RFCs moved to implemented/; docs, catalogs, snapshots re-pinned.
2026-07-09 21:22:54 +08:00
pkg_tasks --> svc_tasks
2026-07-15 14:47:29 +08:00
pkg_token_meter --> svc_tokenMeter
2026-07-12 15:41:42 +08:00
pkg_tool_bash --> svc_bashEnv
2026-07-03 01:13:52 +08:00
pkg_tools --> svc_tools
2026-07-22 21:30:08 -07:00
pkg_tui --> svc_tui
2026-07-20 19:26:04 +08:00
pkg_tui --> svc_userInteraction
2026-07-05 17:05:33 +08:00
pkg_user_interaction --> svc_userInteraction
2026-07-04 12:50:06 +08:00
pkg_web --> svc_web
pkg_web_fetch_local --> svc_web
pkg_web_search_deepseek --> svc_web
pkg_web_search_exa --> svc_web
pkg_web_search_perplexity --> svc_web
2026-07-06 03:14:07 +08:00
pkg_workflow --> svc_workflows
2026-07-09 19:06:55 +08:00
pkg_workflow_workerthread --> svc_workflows
2026-07-15 15:57:57 +08:00
svc_agentLoop --> pkg_agent_spine_demo
2026-07-03 01:13:52 +08:00
svc_agents --> pkg_acp
svc_agents --> pkg_agent_loop
2026-07-15 21:21:24 +08:00
svc_agents --> pkg_cli_demo
2026-07-03 01:13:52 +08:00
svc_agents --> pkg_subagent_inprocess
2026-07-20 19:26:04 +08:00
svc_agents --> pkg_tui_demo
2026-07-09 16:37:10 +08:00
svc_approval --> pkg_tool_bash
2026-07-09 15:25:18 +08:00
svc_approval --> pkg_tools
2026-07-04 12:50:06 +08:00
svc_bash --> pkg_hooks_claude
svc_bash --> pkg_hooks_codex
2026-07-03 01:13:52 +08:00
svc_bash --> pkg_tool_bash
feat: Code Mode — the registry's mode config, the SDK codegen, and the run_code bridge
The dsh-tools half of the Code Mode RFC (its fourth, final change): the
registry gains its first config — mode: native | code | both — and OWNS how
its tools reach the model. 'code' contributes exactly one wire tool,
run_code, plus a lazy tools:sdk prompt section declaring every other tool
as a generated TypeScript API (jsonSchemaToTs: total over the defineTool
subset, unknown degradation, lexicographic byte-identical rendering);
'both' ships both representations; 'native' is byte-for-byte the old
behavior. Non-native modes fail every assembly loudly without a
typescript-language ctx.codeRuntime.
run_code's dispatch bridge: JSON-normalizes each binding argument before
dispatch (what dispatches is what the tool/code-dispatch event logs — the
append can never fail on payload shape; BigInt/circulars reject that one
call), serializes all program tool calls through a per-run queue (even
Promise.all — no concurrency-safety metadata yet), routes every sub-call
through tools/pre-execute → tools/post-execute (a deny rejects the
program-side promise), drops sub-call additionalContext (no safe outlet
mid-run; pinned), owns a run-scoped abort that follows the outer signal in
and fires on settlement (in-flight sub-dispatch aborted, queued abandoned,
queue drained before returning), and converts a failed run into
CodeRunFailedError → a structured isError carrying kind + captured logs.
tool/code-dispatch joins SessionEventMap by declaration merging (log-only;
deriveMessages ignores it).
The composed surface: the tools config forwards through agent-core and
both app packages; examples/code-agent + demo:code run the worker runtime
under mode code (keyless boot smoke + a with-key e2e proving the collapsed
[run_code] header, the dispatch events, and the file the program wrote);
two new snapshot scenarios (code-mode-turn, both-mode-turn) record the SDK
section, collapsed header, dispatch events, and result card — each its own
header-pinning class (the harness gains per-scenario config overlays and
per-class pins). Catalogs, graphs, cookbook, hooks-bridge notes, and the
RFC (moved to implemented/, restructured to decision-era headings) updated
in the same change.
2026-07-08 12:58:23 +08:00
svc_codeRuntime --> pkg_tools
2026-07-19 22:11:59 +08:00
svc_commands --> pkg_acp
svc_commands --> pkg_tui
2026-07-03 01:13:52 +08:00
svc_compact --> pkg_compact_basic
2026-07-04 12:50:06 +08:00
svc_fs --> pkg_tool_fs
2026-07-19 19:19:57 +08:00
svc_invariants --> pkg_agent
svc_invariants --> pkg_agent_loop
svc_invariants --> pkg_scope
svc_invariants --> pkg_session
2026-07-03 01:13:52 +08:00
svc_llm --> pkg_agent_loop
svc_llm --> pkg_compact_basic
feat(permission): user-facing permission presets — one Permissions select over the two knobs
A preset names a bundle of the two mechanism knobs — request =
workspace-write + ask, yolo = danger-full-access + never — so the editor
shows ONE 'Permissions' select where the sandbox-mode and approval-policy
tiers stay orthogonal capabilities (the Codex /approvals shape: presets over
two dials). ctx.permission (dsh-permission) owns the config-defined table,
validates the default preset's bundle against the composed knob defaults at
load (fails loud), and writes a switch THROUGH: one log-only
permission/preset event (the audit fact reverse-mapping cannot recover —
the planned 'agent' preset shares request's knob values and differs only in
composed policy) plus each knob event via its own setter, deduped — a
net-zero switch appends nothing. Every knob consumer keeps reading its own
fold, untouched.
The current preset DERIVES from the effective knob values — the fold breaks
bundle ties, a knob state outside the table is the reserved 'custom' value
(a state, not an error: shown while it holds, switchable FROM, never a
target), and defaultPreset disappears (zero-event state reverse-maps from
the composition defaults).
The ACP bridge drops the two per-knob selects for the one preset select
(advertised only when ctx.permission is composed); pending/anchor/no-op
semantics carry over unchanged, with the no-op echo acknowledged before
vocabulary validation so a client re-pushing a derived 'custom' current
never errors. The sandbox variant example composes the
service with a workspace-write default; the permission-switching,
escalation-approved and escalation-rejected scenarios are re-recorded under
it (escalations now target an outside-workspace /tmp path under
danger-full-access, self-cleaning) and config-options is re-authored on the
single-select wire.
2026-07-12 21:03:41 +08:00
svc_permission --> pkg_acp
2026-07-22 16:57:23 +08:00
svc_planMode --> pkg_acp
2026-07-21 16:01:00 +08:00
svc_pty --> pkg_tool_pty
2026-07-09 16:05:44 +08:00
svc_sandbox --> pkg_bash_sandbox
2026-07-21 16:01:00 +08:00
svc_sandbox --> pkg_pty_local
feat(sandbox): cross-family file sandbox — one policy home, sandboxed fs provider, fs escalation parity
Extend SandboxMode enforcement from bash to the filesystem tools, the sandbox
RFC's deferred cross-family phase.
- dsh-sandbox-policy (new, ctx.sandboxPolicy): the single home for the
deployment default mode + workspaceRoot and the per-session override event,
renamed bash/sandbox-mode -> sandbox/mode and moved here with its fold/setter.
Decouples the bash seam from dsh-session.
- dsh-fs-sandbox (new): SandboxedFileSystem extends LocalFileSystem and fences
write/edit by the per-call mode (read-only denies, workspace-write contains to
the workspace + temp roots via the shared writableRoots, danger passes
through); reads pass through. Structured FS_SANDBOX_DENIED; in-lock parent
re-canonicalization. A policy fence in trusted code, not a kernel boundary.
- dsh-sandbox: the shared escalation kit (writableRoots, the strictly-wider
ladder, denial/hint markers, approveEscalation) both tool families use;
approveEscalation takes a structural approver so dsh-sandbox gains no
approval/agent dependency, and both tools stay duplication-free.
- tool-fs: write/edit advertise sandbox_permissions/justification under a
confining ctx.fs, map FS_SANDBOX_DENIED to the shared [sandbox: ...] marker,
and resolve the same one-approved-wider retry.
- examples/acp-agent: composes sandbox-policy + fs-sandbox, drops the gating
that disabled the fs stack under confined modes.
RFC docs/rfc/implemented/feature/2026-07-14-cross-family-fs-sandbox.md; the old
sandbox RFC's In-process/deferred/FAQ sections updated to shipped fact.
2026-07-14 20:05:57 +08:00
svc_sandboxPolicy --> pkg_bash_sandbox
svc_sandboxPolicy --> pkg_fs_sandbox
2026-07-21 16:01:00 +08:00
svc_sandboxPolicy --> pkg_pty_local
2026-07-03 01:13:52 +08:00
svc_sessionPersistence --> pkg_acp
svc_sessionPersistence --> pkg_agent_loop
fix(bash): close managed environment review gaps
The managed DSH_* runtime path was correct, but its public extension and documentation contracts were incomplete. A contributor following the README could access ctx.bashEnv without declaring an injection, the new environment types had no drift-checked catalog entries, and the capability graph omitted three packages that now query sessionPersistence.
Declare the README injection, catalog DshEnvironmentKey and DshEnvironment, and add tool-bash plus both hook bridges to the generated persistence consumer graph. Keep BashEnvRegistry.list() contributor-only for now because no production caller treats it as exhaustive, but record the built-in enumeration gap before diagnostics, prompt, or UI code depends on it.
Validated on the exact resulting tree with typecheck, lint, coverage, snapshot, documentation, module-graph, build, hygiene, demo-smoke, and built-artifact checks.
2026-07-15 00:04:00 +08:00
svc_sessionPersistence --> pkg_hooks_claude
svc_sessionPersistence --> pkg_hooks_codex
2026-07-10 16:51:19 +08:00
svc_sessionPersistence --> pkg_session_query
2026-07-15 10:51:38 +08:00
svc_sessionPersistence --> pkg_session_query_sqlite
fix(bash): close managed environment review gaps
The managed DSH_* runtime path was correct, but its public extension and documentation contracts were incomplete. A contributor following the README could access ctx.bashEnv without declaring an injection, the new environment types had no drift-checked catalog entries, and the capability graph omitted three packages that now query sessionPersistence.
Declare the README injection, catalog DshEnvironmentKey and DshEnvironment, and add tool-bash plus both hook bridges to the generated persistence consumer graph. Keep BashEnvRegistry.list() contributor-only for now because no production caller treats it as exhaustive, but record the built-in enumeration gap before diagnostics, prompt, or UI code depends on it.
Validated on the exact resulting tree with typecheck, lint, coverage, snapshot, documentation, module-graph, build, hygiene, demo-smoke, and built-artifact checks.
2026-07-15 00:04:00 +08:00
svc_sessionPersistence --> pkg_tool_bash
2026-07-21 16:46:48 +08:00
svc_sessionQuery --> pkg_session_reference
svc_sessionReferences --> pkg_acp
svc_sessionReferences --> pkg_tui
2026-07-03 01:13:52 +08:00
svc_sessions --> pkg_agent
svc_sessions --> pkg_agent_loop
2026-07-15 21:21:24 +08:00
svc_sessions --> pkg_cli_demo
2026-07-03 01:13:52 +08:00
svc_sessions --> pkg_invariants
svc_sessions --> pkg_session_persistence
2026-07-10 16:51:19 +08:00
svc_sessions --> pkg_session_query
2026-07-15 10:51:38 +08:00
svc_sessions --> pkg_session_query_sqlite
2026-07-03 01:13:52 +08:00
svc_sessions --> pkg_subagent_inprocess
2026-07-05 16:50:29 +08:00
svc_skills --> pkg_tool_skill
2026-07-13 11:07:27 +08:00
svc_spillStore --> pkg_spill_policy
2026-07-20 00:51:19 +08:00
svc_subagents --> pkg_tool_ralph
2026-07-03 01:13:52 +08:00
svc_subagents --> pkg_tool_subagent
svc_systemPrompt --> pkg_agent_loop
2026-07-04 12:50:06 +08:00
svc_systemPrompt --> pkg_tool_fs
2026-07-21 16:01:00 +08:00
svc_systemPrompt --> pkg_tool_pty
2026-07-04 12:50:06 +08:00
svc_systemPrompt --> pkg_tool_web
2026-07-03 01:13:52 +08:00
svc_systemPrompt --> pkg_tools
feat(tasks): background task runtime, generic task_* control tools, bash/subagent producers
One shared ctx.tasks registry (branded <kind>-N ids, owner-fenced
read/kill/wait/list, attachSurface misconfiguration fence, reported-flag
notice dedup, atomic register) + dsh-tool-tasks (task_output/task_list/
task_kill, completion-notice injection, background prompt habit).
Producers opt in via their own enableRunInBackground config: bash
(stream kind; seam slimmed to resolve/run/start returning a BashProcess
handle, bash_output/bash_kill deleted) and subagent (final-output kind;
done settles after run.dispose()). Owner disposal drains tasks through
the new awaited ctx.agents.onCleanup seam in the loop's disposal chain.
Both RFCs moved to implemented/; docs, catalogs, snapshots re-pinned.
2026-07-09 21:22:54 +08:00
svc_tasks --> pkg_tool_bash
2026-07-21 16:01:00 +08:00
svc_tasks --> pkg_tool_pty
feat(tasks): background task runtime, generic task_* control tools, bash/subagent producers
One shared ctx.tasks registry (branded <kind>-N ids, owner-fenced
read/kill/wait/list, attachSurface misconfiguration fence, reported-flag
notice dedup, atomic register) + dsh-tool-tasks (task_output/task_list/
task_kill, completion-notice injection, background prompt habit).
Producers opt in via their own enableRunInBackground config: bash
(stream kind; seam slimmed to resolve/run/start returning a BashProcess
handle, bash_output/bash_kill deleted) and subagent (final-output kind;
done settles after run.dispose()). Owner disposal drains tasks through
the new awaited ctx.agents.onCleanup seam in the loop's disposal chain.
Both RFCs moved to implemented/; docs, catalogs, snapshots re-pinned.
2026-07-09 21:22:54 +08:00
svc_tasks --> pkg_tool_subagent
svc_tasks --> pkg_tool_tasks
2026-07-15 14:47:29 +08:00
svc_tokenMeter --> pkg_compact_basic
2026-07-16 18:02:15 +08:00
svc_toolResultPrune --> pkg_compact_basic
2026-07-03 01:13:52 +08:00
svc_tools --> pkg_acp
svc_tools --> pkg_agent_loop
2026-07-05 17:05:33 +08:00
svc_tools --> pkg_tool_ask_user
2026-07-03 01:13:52 +08:00
svc_tools --> pkg_tool_bash
2026-07-08 11:50:12 +08:00
svc_tools --> pkg_tool_cordis
2026-07-04 12:50:06 +08:00
svc_tools --> pkg_tool_fs
2026-07-21 16:01:00 +08:00
svc_tools --> pkg_tool_pty
2026-07-05 16:50:29 +08:00
svc_tools --> pkg_tool_skill
2026-07-03 01:13:52 +08:00
svc_tools --> pkg_tool_subagent
svc_tools --> pkg_tool_todo
2026-07-04 12:50:06 +08:00
svc_tools --> pkg_tool_web
2026-07-05 17:05:33 +08:00
svc_userInteraction --> pkg_acp
svc_userInteraction --> pkg_tool_ask_user
2026-07-20 19:26:04 +08:00
svc_userInteraction --> pkg_tui
2026-07-04 12:50:06 +08:00
svc_web --> pkg_tool_web
2026-07-20 00:51:19 +08:00
svc_workflows --> pkg_tool_ralph
2026-07-06 03:14:07 +08:00
svc_workflows --> pkg_tool_workflow
2026-07-04 12:50:06 +08:00
svc_fs -. event gate .-> pkg_fs_policy
2026-07-03 01:13:52 +08:00
```
2026-07-04 12:50:06 +08:00
| ctx key | Role | Owner | Implementations | Direct consumers | Companion plugins | Note |
| --- | --- | --- | --- | --- | --- | --- |
2026-07-05 01:25:58 +08:00
| `ctx.llm` | `seam` | [`llm` ](../packages/llm/llm ) | [`llm-deepseek` ](../packages/llm/llm-deepseek ), [`llm-pi-ai` ](../packages/llm/llm-pi-ai ), [`llm-replay` ](../packages/support/llm-replay ) | [`agent-loop` ](../packages/core/agent-loop ), [`compact-basic` ](../packages/compact/compact-basic ) | - | Adapters register provider implementations; the loop and compaction call the provider-neutral stream service. |
2026-07-16 12:58:07 +08:00
| `ctx.tokenMeter` | `core` | [`token-meter` ](../packages/llm/token-meter ) | - | [`compact-basic` ](../packages/compact/compact-basic ) | - | Owns isolated per-session replay folds; pressure consumers share immutable revisioned measurements. |
2026-07-16 18:51:26 +08:00
| `ctx.toolResultPrune` | `core` | [`compact-tool-result-prune` ](../packages/compact/compact-tool-result-prune ) | - | [`compact-basic` ](../packages/compact/compact-basic ) | - | Rewrites oversized current tool results through replayable single-node surface replacements before summary compaction. |
2026-07-23 13:56:56 +08:00
| `ctx.sessions` | `core` | [`session` ](../packages/core/session ) | - | [`agent-loop` ](../packages/core/agent-loop ), [`agent` ](../packages/core/agent ), [`cli-demo` ](../packages/examples/cli-demo ), [`session-persistence` ](../packages/session-persistence/session-persistence ), [`session-query` ](../packages/session-query/session-query ), [`session-query-sqlite` ](../packages/session-query/session-query-sqlite ), [`subagent-inprocess` ](../packages/subagent/subagent-inprocess ), [`invariants` ](../packages/support/invariants ) | - | Owns append-only Session instances and emits the durable session event feed. |
2026-07-19 19:19:57 +08:00
| `ctx.invariants` | `core` | [`invariants` ](../packages/support/invariants ) | - | [`session` ](../packages/core/session ), [`agent` ](../packages/core/agent ), [`scope` ](../packages/core/scope ), [`agent-loop` ](../packages/core/agent-loop ) | - | Companion subpaths register owner-local checks; the service owns selection, uniqueness, child fibers, and package-attributed failures. |
2026-07-23 13:56:56 +08:00
| `ctx.sessionPersistence` | `seam` | [`session-persistence` ](../packages/session-persistence/session-persistence ) | [`session-persistence-jsonl` ](../packages/session-persistence/session-persistence-jsonl ), [`session-persistence-sqlite` ](../packages/session-persistence/session-persistence-sqlite ) | [`agent-loop` ](../packages/core/agent-loop ), [`tool-bash` ](../packages/bash/tool-bash ), [`hooks-claude` ](../packages/hooks/hooks-claude ), [`hooks-codex` ](../packages/hooks/hooks-codex ), [`acp` ](../packages/ui/acp ), [`session-query` ](../packages/session-query/session-query ), [`session-query-sqlite` ](../packages/session-query/session-query-sqlite ) | - | Backends persist the same SessionEvent vocabulary; apps choose a backend at composition time. |
2026-07-23 20:16:14 +08:00
| `ctx.sessionQuery` | `seam` | [`session-query` ](../packages/session-query/session-query ) | [`session-query-sqlite` ](../packages/session-query/session-query-sqlite ) | [`session-reference` ](../packages/context/session-reference ) | - | The interface supplies exact reads, filters, and traces; its concrete backend adds full-text reconciliation, ranking, snippets, and cursor generations on the same service. |
2026-07-21 16:46:48 +08:00
| `ctx.sessionReferences` | `core` | [`session-reference` ](../packages/context/session-reference ) | - | [`tui` ](../packages/ui/tui ), [`acp` ](../packages/ui/acp ) | - | Projects bounded current-surface conversation snapshots into durable untrusted message context; host adapters own mention syntax. |
2026-07-21 01:54:00 +08:00
| `ctx.sessionTitle` | `seam` | [`session-title` ](../packages/session-title/session-title ) | [`session-title-first-message-llm` ](../packages/session-title/session-title-first-message-llm ), [`session-title-all-messages-llm` ](../packages/session-title/session-title-all-messages-llm ) | - | - | Owns the deterministic fallback, latest-title fold, and sole optional asynchronous provider registration. |
2026-07-21 16:01:00 +08:00
| `ctx.systemPrompt` | `core` | [`system-prompt` ](../packages/core/system-prompt ) | - | [`agent-loop` ](../packages/core/agent-loop ), [`tools` ](../packages/core/tools ), [`tool-fs` ](../packages/fs/tool-fs ), [`tool-pty` ](../packages/pty/tool-pty ), [`tool-web` ](../packages/web/tool-web ) | - | Collects prompt sections and model-facing tool schemas for each step. |
| `ctx.tools` | `core` | [`tools` ](../packages/core/tools ) | - | [`agent-loop` ](../packages/core/agent-loop ), [`tool-ask-user` ](../packages/ui/tool-ask-user ), [`tool-bash` ](../packages/bash/tool-bash ), [`tool-cordis` ](../packages/cordis/tool-cordis ), [`tool-fs` ](../packages/fs/tool-fs ), [`tool-pty` ](../packages/pty/tool-pty ), [`tool-skill` ](../packages/skill/tool-skill ), [`tool-subagent` ](../packages/subagent/tool-subagent ), [`tool-todo` ](../packages/todo/tool-todo ), [`tool-web` ](../packages/web/tool-web ), [`acp` ](../packages/ui/acp ) | - | Registers capabilities, owns Code Mode transport, and routes calls through pre-policy, monotonic guards, around dispatch, post-policy, and final-result observation. |
2026-07-20 19:26:04 +08:00
| `ctx.userInteraction` | `seam` | [`user-interaction` ](../packages/ui/user-interaction ) | [`tui` ](../packages/ui/tui ), [`acp` ](../packages/ui/acp ) | [`tool-ask-user` ](../packages/ui/tool-ask-user ), [`tui` ](../packages/ui/tui ), [`acp` ](../packages/ui/acp ) | - | UI front doors provide the active human-answer provider; tool-ask-user pauses a tool call on the provider-neutral ask() promise. |
2026-07-22 16:57:23 +08:00
| `ctx.planMode` | `core` | [`plan-mode` ](../packages/plan/plan-mode ) | - | [`acp` ](../packages/ui/acp ) | - | Folds logged plan/mode state, flushes user selections at turn boundaries, renders deployment-owned guidance, registers /plan, and keeps the plan-exit schema stable across transitions. |
2026-07-20 20:43:02 +08:00
| `ctx.commands` | `core` | [`commands` ](../packages/ui/commands ) | - | [`tui` ](../packages/ui/tui ), [`acp` ](../packages/ui/acp ) | - | Plugins register direct human commands; TUI and ACP consume the same effective per-agent catalog without sending invocations to the model. |
2026-07-22 21:30:08 -07:00
| `ctx.tui` | `bundle` | [`tui` ](../packages/ui/tui ) | - | - | - | One TUI front door provides a FIFO overlay host; injected plugins receive caller-fiber ownership without access to pi-tui or terminal lifecycle state. |
2026-07-10 14:19:06 +08:00
| `ctx.skills` | `seam` | [`skill` ](../packages/skill/skill ) | [`skill-local` ](../packages/skill/skill-local ) | [`tool-skill` ](../packages/skill/tool-skill ) | - | Merges provider skill catalogs; tool-skill renders the session-prefix catalog and loads complete skill bodies. |
2026-07-20 20:58:46 +08:00
| `ctx.agents` | `core` | [`agent` ](../packages/core/agent ) | - | [`agent-loop` ](../packages/core/agent-loop ), [`acp` ](../packages/ui/acp ), [`cli-demo` ](../packages/examples/cli-demo ), [`subagent-inprocess` ](../packages/subagent/subagent-inprocess ), [`tui-demo` ](../packages/examples/tui-demo ) | - | Owns live Agent handles, the create/resume factory seam, and process-local initiator propagation. |
2026-07-15 15:57:57 +08:00
| `ctx.agentLoop` | `bundle` | [`agent-loop` ](../packages/core/agent-loop ) | - | [`agent-spine-demo` ](../packages/examples/agent-spine-demo ) | - | The one concrete loop plugin; extension packages depend on dsh-agent events and services, not on this package. |
2026-07-19 18:47:34 +08:00
| `ctx.goals` | `core` | [`goal` ](../packages/goal/goal ) | - | - | - | Folds revisioned objective state from the session log and keeps live continuation activation process-local. |
2026-07-09 16:05:44 +08:00
| `ctx.bash` | `seam` | [`bash` ](../packages/bash/bash ) | [`bash-local` ](../packages/bash/bash-local ), [`bash-sandbox` ](../packages/bash/bash-sandbox ) | [`tool-bash` ](../packages/bash/tool-bash ), [`hooks-claude` ](../packages/hooks/hooks-claude ), [`hooks-codex` ](../packages/hooks/hooks-codex ) | - | The model-facing bash tools and hook bridges consume this seam; sandboxed or remote executors replace bash-local without touching them. |
2026-07-12 15:41:42 +08:00
| `ctx.bashEnv` | `core` | [`tool-bash` ](../packages/bash/tool-bash ) | - | - | - | Plugins declare effect-scoped DSH_* facts; tool-bash collects one trusted snapshot per execution and the executor rebuilds the namespace. |
2026-07-21 16:01:00 +08:00
| `ctx.pty` | `seam` | [`pty` ](../packages/pty/pty ) | [`pty-local` ](../packages/pty/pty-local ) | [`tool-pty` ](../packages/pty/tool-pty ) | - | The registry owns exact-Agent session identity and cleanup; backends own terminal mechanics, while tool-pty exposes the owner-scoped model surface. |
| `ctx.sandbox` | `seam` | [`sandbox` ](../packages/sandbox/sandbox ) | [`sandbox-local` ](../packages/sandbox/sandbox-local ) | [`bash-sandbox` ](../packages/bash/bash-sandbox ), [`pty-local` ](../packages/pty/pty-local ) | - | Consumers hand over the exact argv they are about to spawn; same-world backends wrap it under a per-call policy and report enforcement. |
| `ctx.sandboxPolicy` | `core` | [`sandbox-policy` ](../packages/sandbox/sandbox-policy ) | - | [`bash-sandbox` ](../packages/bash/bash-sandbox ), [`fs-sandbox` ](../packages/fs/fs-sandbox ), [`pty-local` ](../packages/pty/pty-local ) | - | The one home for the deployment default mode + workspace root; only the sandboxed executor and provider read the service (the tool layers use the pure `sandbox/mode` fold it also exports). Both enforcing families read it so bash and fs cannot confine to different roots. |
2026-07-11 21:37:38 +08:00
| `ctx.approval` | `seam` | `approval` | [`acp` ](../packages/ui/acp ) | [`tools` ](../packages/core/tools ), [`tool-bash` ](../packages/bash/tool-bash ) | - | One-shot permission decisions dispatched over the `approval/request` waterfall; answerers are listeners (the ACP bridge for its own agents), absence fails closed to `unavailable` . |
2026-07-14 01:09:44 +08:00
| `ctx.permission` | `core` | [`permission` ](../packages/ui/permission ) | - | [`acp` ](../packages/ui/acp ) | - | User-facing preset table (`workspace-write` /`danger-full-access` ) bundling the sandbox-mode and approval-policy knobs; a switch writes one `permission/preset` event through to both knob events. |
feat: Code Mode — the registry's mode config, the SDK codegen, and the run_code bridge
The dsh-tools half of the Code Mode RFC (its fourth, final change): the
registry gains its first config — mode: native | code | both — and OWNS how
its tools reach the model. 'code' contributes exactly one wire tool,
run_code, plus a lazy tools:sdk prompt section declaring every other tool
as a generated TypeScript API (jsonSchemaToTs: total over the defineTool
subset, unknown degradation, lexicographic byte-identical rendering);
'both' ships both representations; 'native' is byte-for-byte the old
behavior. Non-native modes fail every assembly loudly without a
typescript-language ctx.codeRuntime.
run_code's dispatch bridge: JSON-normalizes each binding argument before
dispatch (what dispatches is what the tool/code-dispatch event logs — the
append can never fail on payload shape; BigInt/circulars reject that one
call), serializes all program tool calls through a per-run queue (even
Promise.all — no concurrency-safety metadata yet), routes every sub-call
through tools/pre-execute → tools/post-execute (a deny rejects the
program-side promise), drops sub-call additionalContext (no safe outlet
mid-run; pinned), owns a run-scoped abort that follows the outer signal in
and fires on settlement (in-flight sub-dispatch aborted, queued abandoned,
queue drained before returning), and converts a failed run into
CodeRunFailedError → a structured isError carrying kind + captured logs.
tool/code-dispatch joins SessionEventMap by declaration merging (log-only;
deriveMessages ignores it).
The composed surface: the tools config forwards through agent-core and
both app packages; examples/code-agent + demo:code run the worker runtime
under mode code (keyless boot smoke + a with-key e2e proving the collapsed
[run_code] header, the dispatch events, and the file the program wrote);
two new snapshot scenarios (code-mode-turn, both-mode-turn) record the SDK
section, collapsed header, dispatch events, and result card — each its own
header-pinning class (the harness gains per-scenario config overlays and
per-class pins). Catalogs, graphs, cookbook, hooks-bridge notes, and the
RFC (moved to implemented/, restructured to decision-era headings) updated
in the same change.
2026-07-08 12:58:23 +08:00
| `ctx.codeRuntime` | `seam` | [`code-runtime` ](../packages/code-runtime/code-runtime ) | [`code-runtime-worker` ](../packages/code-runtime/code-runtime-worker ) | [`tools` ](../packages/core/tools ) | - | Runs one model-written program against host-provided async bindings; backends differ by substrate and language (the tool registry consumes it for Code Mode). |
feat(sandbox): cross-family file sandbox — one policy home, sandboxed fs provider, fs escalation parity
Extend SandboxMode enforcement from bash to the filesystem tools, the sandbox
RFC's deferred cross-family phase.
- dsh-sandbox-policy (new, ctx.sandboxPolicy): the single home for the
deployment default mode + workspaceRoot and the per-session override event,
renamed bash/sandbox-mode -> sandbox/mode and moved here with its fold/setter.
Decouples the bash seam from dsh-session.
- dsh-fs-sandbox (new): SandboxedFileSystem extends LocalFileSystem and fences
write/edit by the per-call mode (read-only denies, workspace-write contains to
the workspace + temp roots via the shared writableRoots, danger passes
through); reads pass through. Structured FS_SANDBOX_DENIED; in-lock parent
re-canonicalization. A policy fence in trusted code, not a kernel boundary.
- dsh-sandbox: the shared escalation kit (writableRoots, the strictly-wider
ladder, denial/hint markers, approveEscalation) both tool families use;
approveEscalation takes a structural approver so dsh-sandbox gains no
approval/agent dependency, and both tools stay duplication-free.
- tool-fs: write/edit advertise sandbox_permissions/justification under a
confining ctx.fs, map FS_SANDBOX_DENIED to the shared [sandbox: ...] marker,
and resolve the same one-approved-wider retry.
- examples/acp-agent: composes sandbox-policy + fs-sandbox, drops the gating
that disabled the fs stack under confined modes.
RFC docs/rfc/implemented/feature/2026-07-14-cross-family-fs-sandbox.md; the old
sandbox RFC's In-process/deferred/FAQ sections updated to shipped fact.
2026-07-14 20:05:57 +08:00
| `ctx.fs` | `seam` | [`fs` ](../packages/fs/fs ) | [`fs-local` ](../packages/fs/fs-local ), [`fs-sandbox` ](../packages/fs/fs-sandbox ) | [`tool-fs` ](../packages/fs/tool-fs ) | [`fs-policy` ](../packages/fs/fs-policy ) | tool-fs executes read/write/edit through ctx.fs; fs-sandbox fences mutations by the shared sandbox mode; fs-policy contributes observed-state checks through the fs/* event gate. |
2026-07-15 16:50:44 +08:00
| `ctx.compact` | `seam` | [`compact` ](../packages/compact/compact ) | [`compact-basic` ](../packages/compact/compact-basic ) | [`compact-basic` ](../packages/compact/compact-basic ) | - | The basic backend consumes post-step pressure and request-error recovery events; a model-facing compact tool remains deferred. |
2026-07-20 00:51:19 +08:00
| `ctx.subagents` | `seam` | [`subagent` ](../packages/subagent/subagent ) | [`subagent-spawn` ](../packages/subagent/subagent-spawn ), [`subagent-fork` ](../packages/subagent/subagent-fork ), [`subagent-acp` ](../packages/subagent/subagent-acp ) | [`tool-subagent` ](../packages/subagent/tool-subagent ), [`tool-ralph` ](../packages/workflow/tool-ralph ) | - | Providers implement transports; tool-subagent exposes configured delegation while tool-ralph requires one fresh structured-output route. |
2026-07-21 16:01:00 +08:00
| `ctx.tasks` | `core` | [`tasks` ](../packages/tasks/tasks ) | - | [`tool-bash` ](../packages/bash/tool-bash ), [`tool-pty` ](../packages/pty/tool-pty ), [`tool-subagent` ](../packages/subagent/tool-subagent ), [`tool-tasks` ](../packages/tasks/tool-tasks ) | - | Producers (background bash, PTY sends, and subagent delegations) register running work; tool-tasks is the model-facing control surface that reads, lists, and kills it. |
2026-07-05 01:25:58 +08:00
| `ctx.web` | `seam` | [`web` ](../packages/web/web ) | [`web-search-exa` ](../packages/web/web-search-exa ), [`web-search-perplexity` ](../packages/web/web-search-perplexity ), [`web-search-deepseek` ](../packages/web/web-search-deepseek ), [`web-fetch-local` ](../packages/web/web-fetch-local ) | [`tool-web` ](../packages/web/tool-web ) | - | Search and fetch providers register into one ctx.web seam; tool-web owns the stable model-facing names. |
2026-07-13 11:07:27 +08:00
| `ctx.spillStore` | `seam` | [`spill` ](../packages/spill/spill ) | [`spill-local` ](../packages/spill/spill-local ) | [`spill-policy` ](../packages/spill/spill-policy ) | - | The backend saves oversized tool text and returns a model-facing locator plus retrieval hint; spill-policy is the tools/post-execute consumer that decides when to spill. |
2026-07-20 00:51:19 +08:00
| `ctx.workflows` | `seam` | [`workflow` ](../packages/workflow/workflow ) | [`workflow-workerthread` ](../packages/workflow/workflow-workerthread ) | [`tool-workflow` ](../packages/workflow/tool-workflow ), [`tool-ralph` ](../packages/workflow/tool-ralph ) | - | One engine per context (bash shape, no named-provider registry); the general workflow and fixed Ralph consumers start runs whose agent() calls fan out through ctx.subagents. |
2026-07-05 02:54:01 +08:00
Maintenance mode: hybrid: services are discovered from Cordis declarations; interface/implementation/consumer roles are classified in `scripts/gen-doc-graphs.ts` with a completeness guard.