Tianyi Cui fd9ecdce40 Merge remote-tracking branch 'origin/worktree-agent-handle' into worktree-bash-owner-token 3 meses atrás
..
acp fd9ecdce40 Merge remote-tracking branch 'origin/worktree-agent-handle' into worktree-bash-owner-token 3 meses atrás
agent 5a5b7d19c3 fix(agent): contain a throwing agent/disposed listener in the register disposer (Codex review) 3 meses atrás
agent-loop 29ce64b8bd Merge remote-tracking branch 'origin/worktree-cancel-primitive' into worktree-agent-handle 3 meses atrás
bash d1b7c3bf95 feat(bash): add an opaque owner token to the executor seam 3 meses atrás
bash-local d1b7c3bf95 feat(bash): add an opaque owner token to the executor seam 3 meses atrás
invariants 711245821b Handle corrupt JSONL sidecars during list 3 meses atrás
llm 7c400e9c02 docs: unify ADR/RFC trees into one lifecycle-organized RFC tree 3 meses atrás
llm-deepseek 922e2f913e fix(llm-pi-ai): preserve harness adapter contract 3 meses atrás
llm-pi-ai 0b036d808c test: cover new defensive branches 3 meses atrás
llm-replay 072f97c184 refactor(examples): extract reusable logic into tested packages 3 meses atrás
session 083a6fc990 fix(agent): re-check id in enter() + memoize AgentHandle.dispose() (review) 3 meses atrás
session-persistence 329e5c3e2e docs(session-persistence): state coordinator-contract role as current fact (review) 3 meses atrás
session-persistence-jsonl 3d67a98291 fix(session-persistence-jsonl): make loadLive cwd-scope-exact (Codex review) 3 meses atrás
session-persistence-sqlite ab02e9acec refactor(session-persistence): extract a shared write coordinator 3 meses atrás
system-prompt 4a3f3af296 Address Claude review follow-ups 3 meses atrás
tool-bash 8597cc2c58 docs(tool-bash): state ownership tests as current fact (review) 3 meses atrás
tools 4a3f3af296 Address Claude review follow-ups 3 meses atrás
ui-stdio 4f291953ea fix(ui-stdio): cancel EOF-exit timer on dispose; harden config defaults; doc fixes 3 meses atrás
AGENTS.md 7fa113be0e Merge remote-tracking branch 'origin/master' into codex/pr48-repo-hardening-rfcs 3 meses atrás
CLAUDE.md 7f024a1a9d Document the codebase thoroughly and tighten type safety 3 meses atrás
README.md 072f97c184 refactor(examples): extract reusable logic into tested packages 3 meses atrás

README.md

Packages

Harness packages, all under the @deepseek-ai/dsh-* scope. Each package is a Cordis plugin (microkernel-style): it exports either a default Service subclass or a functional plugin that gets registered via ctx.plugin(), declares its ctx key/events where applicable through declaration merging, and exposes extension points through ctx.effect(), ctx.on(), and ctx.waterfall().

Dependency graph

dsh-llm          (no harness deps — pure vocabulary)
dsh-bash          (no harness deps — abstract executor seam)
dsh-session       ← dsh-llm
dsh-system-prompt ← dsh-llm
dsh-agent         ← dsh-llm, dsh-session
dsh-tools         ← dsh-llm, dsh-system-prompt, dsh-agent
dsh-bash-local    ← dsh-bash                       (BashExecutor impl)
dsh-tool-bash     ← dsh-bash, dsh-tools            (bash tool schemas)
dsh-llm-deepseek  ← dsh-llm                        (DeepSeek adapter)
dsh-llm-pi-ai     ← dsh-llm                        (pi-ai-backed adapter)
dsh-agent-loop    ← dsh-llm, dsh-session, dsh-system-prompt, dsh-tools, dsh-agent
dsh-invariants    ← dsh-llm, dsh-session, dsh-agent (dev-mode contract checks)
dsh-acp           ← dsh-agent, dsh-llm, dsh-session, dsh-session-persistence  (ACP JSON-RPC bridge)
dsh-ui-stdio      ← dsh-agent, dsh-llm, dsh-session (stdio readline UI plugin)
dsh-llm-replay    ← dsh-llm, dsh-session            (record/replay adapter for keyless snapshot tests)

The rule: plugins depend on interfaces, never on the concrete loop. dsh-agent-loop is swappable — UI/hook/tool plugins keep working against the dsh-agent vocabulary if the loop is replaced. A swappable capability splits into interface / implementation / consumer packages (the bash trio is the template — see capability seams).

What goes where

Package Role ctx key
llm/ Abstract LLM service + content-block vocabulary + chunk assembler ctx.llm
session/ Event-sourced session log + in-memory store ctx.sessions
system-prompt/ Prompt-section + tool-schema assembly registry ctx.systemPrompt
tools/ Tool registry + tools/execute waterfall ctx.tools
agent/ Agent interface, registry, agent/* event vocabulary ctx.agents
agent-loop/ THE concrete loop plugin: ReactLoopAgent + the loop driver ctx.agentLoop
bash/ Abstract bash executor seam (interface + vocabulary) ctx.bash
bash-local/ Local-subprocess BashExecutor implementation (registers ctx.bash)
tool-bash/ Model-facing bash/bash_output/bash_kill tool schemas (registers on ctx.tools)
llm-deepseek/ DeepSeek API adapter (hand-rolled fetch/SSE) (registers on ctx.llm)
llm-pi-ai/ DeepSeek adapter via @earendil-works/pi-ai (design twin) (registers on ctx.llm)
invariants/ Dev-mode event-contract invariants + session-log freeze (listens on session/*, agent/*)
acp/ Agent Client Protocol bridge: serves the agent to an ACP editor over JSON-RPC stdio (drives ctx.agents/ctx.sessions)
ui-stdio/ Minimal stdio (readline) UI plugin: renders agent/* events, feeds stdin lines to the agent (drives ctx.agents)
llm-replay/ Record/replay adapter: short-circuits llm/stream with chunks from a recorded session JSONL (keyless snapshot tests) (listens on llm/stream)

Each package has its own README.md with purpose, service API, events, extension points, and deliberate non-goals (TODOs).

Conventions (applied across all harness packages)

  • Registrations are effects: every contribution (adapter, tool, section, agent, event listener) goes through ctx.effect() / ctx.on(), so disposal and HMR clean up automatically. Every register() returns the disposer.
  • Declaration merging for events and ctx: services declare their events in declare module 'cordis' { interface Events { ... } } and their ctx key in interface Context.
  • Waterfall semantics: ctx.waterfall listeners receive (...args, next) and MUST call next() to delegate; returning without it short-circuits (the veto mechanism).
  • Extensible unions: ContentBlockMap, MessageSourceMap, FinishReasonMap, TurnTriggerMap, TurnEndReasonMap, and SessionEventMap use the merge-extensible-map pattern so plugins can add variants via declaration merging.
  • ESM everywhere; imports use package names across package boundaries, .ts extensions within a package.
  • Tests: vitest, colocated under packages/<name>/tests/*.spec.ts. Every registry needs an HMR-safety test. Err on the side of more tests.