Document the codebase thoroughly and tighten type safety
Docs: per-folder README.md for packages/ (family overview + one per
package: service, events, API, extension points, TODOs), examples/,
and examples/echo-agent/; folder-level AGENTS.md (+ CLAUDE.md
symlinks) for packages/ and vendor/; module-level doc comments in
every packages/*/src file; richer JSDoc on all exported API
(event side effects, disposal contracts, error behavior). Root
AGENTS.md gains a "Type Safety and Documentation" policy section:
the codebase aims to be very type-safe and well documented; type
gymnastics are acceptable in core packages when they improve
plugin-author DX; verbose docs are fine as long as they stay strictly
in sync with the code.
Type safety: removed the upstream-inherited "noImplicitAny": false
from tsconfig.base.json — packages/* now compile under full strict
mode; vendor/loader and vendor/include set it locally (vendor/cordis
already did). Eliminated every `: any` / `as any` from packages and
examples (catch clauses use unknown + a CodedError narrowing type;
event data access uses discriminated-union narrowing).
Typed tool schemas: new @deepseek-ai/dsh-tools schema DSL —
SchemaSpec with per-property `required: true` booleans, type-level
InferArgs<S>, a runtime SchemaSpec → JSON Schema converter, and
defineTool() so first-party tools get typed execute(args) with zero
casts (raw JSON Schema still accepted for MCP interop; chosen over
schemastery because it targets JSON Schema generation directly).
echo-tool and all test tools migrated; +7 tests.
2026-06-11 12:39:27 +08:00
# Packages
2026-07-14 16:04:34 +08:00
Packages use the `@deepseek-ai/dsh-*` scope. Each is a Cordis `Service` subclass or function plugin; contributions use `ctx.effect()` , `ctx.on()` , or `ctx.waterfall()` . Authoring rules: [package ](AGENTS.md ) and [root ](../AGENTS.md#conventions ).
Document the codebase thoroughly and tighten type safety
Docs: per-folder README.md for packages/ (family overview + one per
package: service, events, API, extension points, TODOs), examples/,
and examples/echo-agent/; folder-level AGENTS.md (+ CLAUDE.md
symlinks) for packages/ and vendor/; module-level doc comments in
every packages/*/src file; richer JSDoc on all exported API
(event side effects, disposal contracts, error behavior). Root
AGENTS.md gains a "Type Safety and Documentation" policy section:
the codebase aims to be very type-safe and well documented; type
gymnastics are acceptable in core packages when they improve
plugin-author DX; verbose docs are fine as long as they stay strictly
in sync with the code.
Type safety: removed the upstream-inherited "noImplicitAny": false
from tsconfig.base.json — packages/* now compile under full strict
mode; vendor/loader and vendor/include set it locally (vendor/cordis
already did). Eliminated every `: any` / `as any` from packages and
examples (catch clauses use unknown + a CodedError narrowing type;
event data access uses discriminated-union narrowing).
Typed tool schemas: new @deepseek-ai/dsh-tools schema DSL —
SchemaSpec with per-property `required: true` booleans, type-level
InferArgs<S>, a runtime SchemaSpec → JSON Schema converter, and
defineTool() so first-party tools get typed execute(args) with zero
casts (raw JSON Schema still accepted for MCP interop; chosen over
schemastery because it targets JSON Schema generation directly).
echo-tool and all test tools migrated; +7 tests.
2026-06-11 12:39:27 +08:00
2026-06-20 23:25:33 +08:00
## Hierarchy
2026-07-11 23:12:45 +08:00
Packages live at `packages/<group>/<pkg>/` ; groups are containers, while names remain `@deepseek-ai/dsh-<pkg>` . **Each group README is the canonical package/ctx-key map.**
2026-06-20 23:25:33 +08:00
| Group | Role | Release expectation |
|---|---|---|
2026-07-19 13:37:11 +08:00
| [`core/` ](core/README.md ) | Product API spine: sessions, prompts, tools, agent services, and the concrete loop | Product — stable surface |
2026-07-19 18:47:34 +08:00
| [`goal/` ](goal/README.md ) | Persisted same-session goal state and lifecycle | Product — stable surface |
2026-06-20 23:25:33 +08:00
| [`llm/` ](llm/README.md ) | LLM capability family: the abstract service + provider adapters | Product — stable surface |
2026-07-22 02:13:39 +08:00
| [`bash/` ](bash/README.md ) | Bash capability family: executor seam, local impl, model-facing tool | Product — stable surface |
2026-07-21 16:01:00 +08:00
| [`pty/` ](pty/README.md ) | Persistent PTY capability family: owner-scoped sessions, local implementation, and model-facing tools | Product — stable surface |
2026-07-22 02:13:39 +08:00
| [`code-runtime/` ](code-runtime/README.md ) | Code-execution capability family: the runtime seam for model-written programs + a worker-thread backend | Product — stable surface |
2026-07-09 15:42:37 +08:00
| [`sandbox/` ](sandbox/README.md ) | Process-confinement seam; bwrap/Landlock/Seatbelt backends | Product — stable surface |
2026-07-22 02:13:39 +08:00
| [`fs/` ](fs/README.md ) | Filesystem capability family: seam, local impl, model-facing file tools, bash-backed discovery tools | Product — stable surface |
feat(lsp): LSP capability seam, generic stdio provider, and lsp tool
Implements the LSP capability seam RFC as three packages: dsh-lsp (the
ctx.lsp interface — provider registry by branded id + exclusive extension
mapping, per-query order-independent selection, closed request/result
vocabulary, LspError taxonomy), dsh-lsp-local (a generic stdio language-server
provider — Content-Length JSON-RPC framing, per-(provider, workspace) process
single-flight, transient didOpen/query/didClose, an abortable per-instance
queue, UTF-16 negotiation, host-namespace source reads outside ctx.fs, and
bounded shutdown/kill teardown), and dsh-tool-lsp (the model-facing lsp tool —
four operations, one-based UTF-16 cursor conversion, workspace-grouped location
rendering, hover capping, a required session workspace, and a timeout budget).
Why: an agent had text search and file reads but no way to identify a program
symbol — follow an alias, connect an interface to implementations, or read an
inferred type — before changing code. Splitting model contract, seam, and local
subprocess behavior keeps the four semantic queries stable across future remote
or sandbox-native providers without leaking a JSON-RPC escape hatch.
2026-07-16 12:05:35 +08:00
| [`lsp/` ](lsp/README.md ) | LSP capability family: seam, generic stdio provider, and the `lsp` tool | Product — stable surface |
2026-07-10 14:19:06 +08:00
| [`skill/` ](skill/README.md ) | Skill capability family: the provider registry, local provider, and model-facing catalog/loader | Product — stable surface |
2026-06-25 17:30:42 +08:00
| [`compact/` ](compact/README.md ) | Compaction capability family: the abstract seam + a basic backend (tool deferred) | Product — stable surface |
2026-07-16 16:01:06 +08:00
| [`context/` ](context/README.md ) | Model-visible request context, including workspace instructions and time context | Product — stable surface |
Add subagent capability seam: interface, mock backend, model-facing tool
Introduce the `packages/subagent/` group and the abstract subagent seam — an
agent delegating to a child agent — as a named-provider registry (`ctx.subagents`),
unlike the single-implementation bash seam, so multiple transports (in-process,
ACP, future A2A) coexist. This first PR lands the interface, a scripted test
backend, and the model-facing tool, validated through the real cordis load path.
- dsh-subagent: SubagentService registry + SubagentProvider/SubagentRun
vocabulary + subagent/start|end events. Start-time capabilities (outputSchema,
depthLimit, toolFilter) are checked pre-start and rejected loud; runtime
capabilities (sendMessage, resume) are optional methods on SubagentRun.
- dsh-subagent-mock (support): scripted provider for keyless, deterministic
tests through the real Loader/export path.
- dsh-tool-subagent: the model-facing `subagent` tool, config-bound to one
provider; synchronous collect with try/finally dispose, signal->cancel
bridging, and non-completed-stop-reason -> isError mapping.
- Proposed RFC documenting the seam, the fork-vs-spawn-as-separate-backends
decision, own-session isolation, synchronous-collect scope, and the deferral
of background/poll/spill to a future unification with bash.
- Wire the new group into tsconfigs, build refs, package hierarchy docs, the
module graph, and the cordis catalog.
RFC: docs/rfc/proposed/feature/2026-06-21-subagent-capability-seam.md
2026-06-21 22:31:56 +08:00
| [`subagent/` ](subagent/README.md ) | Subagent capability family: the provider-registry seam and the model-facing delegation tool | Product — stable surface |
2026-07-11 23:04:27 +08:00
| [`tasks/` ](tasks/README.md ) | Generic background-task runtime and model-facing `task_*` control tools | Product — stable surface |
2026-07-20 00:51:19 +08:00
| [`workflow/` ](workflow/README.md ) | Workflow capability family: the script-engine seam, worker-thread engine, and model-facing `workflow` and fresh-agent `ralph` tools | Product — stable surface |
2026-07-22 02:13:39 +08:00
| [`web/` ](web/README.md ) | Web capability family: seam, search/fetch provider impls, and the model-facing web tools | Product — stable surface |
| [`spill/` ](spill/README.md ) | Spill capability family: storage seam, local impl, tool-result spill policy | Product — stable surface |
2026-07-08 14:52:12 +08:00
| [`todo/` ](todo/README.md ) | Todo/planning family: the model-facing `todo_write` tool | Product — stable surface |
2026-07-22 16:57:23 +08:00
| [`plan/` ](plan/README.md ) | Plan collaboration state with a direct entry command and reviewed exit | Product — stable surface |
2026-07-08 15:46:46 +08:00
| [`timeout/` ](timeout/README.md ) | Tool-call timeout policy: the `tools/execute` deadline enforcer | Product — stable surface |
2026-07-08 14:52:12 +08:00
| [`guard/` ](guard/README.md ) | Loop-hygiene guards: advisory repeat-call reminders | Product — stable surface |
2026-07-19 22:50:49 +08:00
| [`cordis/` ](cordis/README.md ) | Self-referential runtime toolset: inspect the live runtime's plugins and services, mount/unmount model-written plugins ([design ](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md )) | Product — stable surface |
feat(hooks): dsh-hook-protocol — shared Claude Code / Codex hook wire-protocol core
The two hook bridges (dsh-hooks-claude, dsh-hooks-codex) would otherwise duplicate
the bulk of the protocol — Codex deliberately reimplements a SUBSET of the Claude
Code protocol (same hooks.json shape, exit-code/stdout contract, command-hook
model). This library holds the genuinely-identical primitives; each bridge owns
only what differs (per-event stdin payload, env/substitution, decision mapping).
New packages/hooks/ group; hook-protocol is a LIBRARY (no plugin, registers/injects
nothing):
- matcher: matchesMatcher(pattern, query, mode) — the one dialect axis collapsed to
a mode param (claude = literal-or-regex with pipe alternation; codex = always
unanchored regex). Match-all on absent/''/'*'; invalid regex matches nothing.
- codec: parseHookOutput(exit, stdout, stderr) → dialect-neutral HookOutput. Exit 0
→ lenient JSON; exit 2 → blocking error (stderr = reason, surfaced as
decision:'block'); other → non-blocking. Parses the CC superset
(continue/stopReason/decision/hookSpecificOutput.{permissionDecision,
additionalContext,updatedInput}/systemMessage); permissionDecision overrides the
legacy top-level decision.
- runner: runHook(bash, hook, opts, now) — runs a command hook via ctx.bash (stdin
payload + trusted-plugin env), honors timeoutSec, never throws (executor reject →
non-blocking-error HookOutput). Injected clock for testable durations.
- merge: mergeHookOutputs — most-restrictive fold (deny>ask>allow, sticky stop,
block reasons joined, context/system-messages accumulated).
- hook/* session events (declaration-merged into SessionEventMap, log-only like
compact/*) + appendHookInvoked/appendHookResult helpers.
updatedInput is parsed but NOT honored (deferred pre-tool-input-rewrite RFC); a
bridge logs+warns. 47 unit tests at per-file 100% (matcher per-mode, codec per
exit-code/field, runner plumbing w/ stub executor, merge precedence, hook/*
helpers). RFC: implemented/feature/2026-06-30-hook-protocol-lib.md.
2026-07-01 00:38:06 +08:00
| [`hooks/` ](hooks/README.md ) | Hook bridges + the shared Claude Code / Codex wire-protocol library | Product — stable surface |
2026-06-20 23:25:33 +08:00
| [`session-persistence/` ](session-persistence/README.md ) | Persistence capability family: the seam + JSONL/SQLite backends | Product — stable surface |
2026-07-23 13:56:56 +08:00
| [`session-query/` ](session-query/README.md ) | Session retrieval family: logical corpus, bounded reads, lineage, event relationships, semantic filtering, and SQLite full-text search | Product — stable surface |
2026-07-21 01:54:00 +08:00
| [`session-title/` ](session-title/README.md ) | Log-backed session titles: fallback service, shared LLM policy, and opt-in providers | Product — stable surface |
chore(storage,workspace): gates — coverage, catalogs, bilingual note
- Per-file 100% coverage across the five new packages (invariant
companion suites, failure-injection negatives, lifecycle and
malformed-medium branches).
- Canonical README Model Experience / Known Limitations sections; new
storage/ and workspace/ group READMEs; packages/README.md rows (budget
ceiling raised 760 → 790 for the two new groups).
- Cordis catalog/type-link registrations, service-role classification,
and regenerated catalogs/graphs for the new services and events.
- Agent Note: English body + i18n pairing record; design-sketch fences
opted out of doc-typecheck as ignore-check.
- Two exactOptionalPropertyTypes/discriminant fixes in new tests.
doc-sync (24 gates), typecheck, hygiene, and the five-package suite
(92 tests) all pass.
2026-07-24 22:49:57 +08:00
| [`storage/` ](storage/README.md ) | Non-session storage hub + backends + domain form | Product — stable surface |
| [`workspace/` ](workspace/README.md ) | Workspace entity | Product — stable surface |
2026-07-15 18:17:38 +08:00
| [`sdk/` ](sdk/README.md ) | Project SDK tooling | Product — stable surface |
2026-07-24 01:40:25 +08:00
| [`acp/` ](acp/README.md ) | Automation-only Agent Client Protocol server | Product — stable surface |
| [`ui/` ](ui/README.md ) | Human/client integrations: TUI and JSON-RPC, approval/interaction seams, ask-user tool | Product — stable surface |
| [`examples/` ](examples/README.md ) | Demo bundles (agent-spine + TUI/CLI/ACP/JSON-RPC bins) leaves load | Support — example infra |
2026-07-19 13:11:50 +08:00
| [`support/` ](support/README.md ) | Support infrastructure (testkits, invariants, replay, Loader smokes) | Support — lower compatibility expectations |
2026-07-17 18:35:48 +08:00
| [`util/` ](util/README.md ) | Low-level zero-dependency utilities shared across groups (`Branded<B>` , Harness home/path helpers, timeout, retention) | Support — small, stable, harness-dep-free |
2026-06-20 23:25:33 +08:00
2026-07-11 23:12:45 +08:00
Groups distinguish product API from support infrastructure. New packages join an existing group; a new group updates its README and this table.
refactor(examples): extract reusable logic into tested packages
Logic that lived under examples/ was outside the per-file 100% coverage
gate (examples/ are not workspaces) and, in the stdio-UI case, duplicated
across two examples. Move it into packages/ so it is gated and de-duped.
- packages/ui-stdio (new): unify the two diverged stdio-chat.ts copies into
one @deepseek-ai/dsh-ui-stdio plugin (welcome/agent Config). A test-only
I/O seam (createStdioChat(ctx, config, runtime)) keeps process streams out
of the serializable config and makes every render/EOF/disposal branch
unit-testable. Per-file 100%. echo/coding cordis.yml now load the package;
both src/stdio-chat.ts deleted.
- packages/llm-replay (new): move examples/acp-agent/src/llm-replay.ts (+ its
spec) here so its derive/parse/replay branches fall under the coverage gate.
cordis.snapshot.yml + README rewired to the package name; added apply/env
/assertNever/abort tests to reach per-file 100%.
- examples/{echo,coding}-agent: keyless Loader-path e2e smokes that boot the
real cordis.yml (no key) — the guard a hand-mounted unit test cannot be for
the unwrapExports/export-shape class (postmortem 0001). examples/AGENTS.md
codifies the keyless+with-key smoke convention (keyless-by-nature exception
for echo-agent).
- AGENTS.md: a scoped, removal-triggered pre-release stance (foundation over
blast radius). packages/README.md: new rows + a FIXME to later regroup ALL
packages into a hierarchy. Wiring: tsconfig paths/refs, publint, knip,
module-graph.
Verified: typecheck, lint, test:coverage (887 tests, 100%), build, hygiene,
doc-sync, test:snapshot (10), test:e2e (6 keyless pass, with-key self-skip).
2026-06-19 12:42:28 +08:00
docs(AGENTS): rewrite the root standing orders to the 1,500-word budget
Applies the documentation standard to its biggest offender. Every rule
survives as one to three lines plus a link to its durable home; the
stories, duplicate statements, and re-narrations go:
- Situational clusters evict to new homes: docs/testing.md (tiers,
with-key policy, real-over-mock, world-verification, real-entry-path
guards), docs/defensive-patterns.md (the bug-class rules), and
docs/cookbook/responding-to-pr-review-on-a-stack.md (the stacked-PR
review procedure).
- Doc-authoring rules consolidate into docs/AGENTS.md § Writing rules
(current-state-never-history, md-wrap, ts-block compilation, @mode,
catalog same-change, pair same-change).
- packages/README.md drops to the group table + the extension-vs-bundle
dependency rule; the hand ASCII graph yields to the generated
module-graph.md; group READMEs are the canonical per-package map.
- packages/AGENTS.md keeps only its packages-specific rules (export
shape, ctx.get, real-Loader coverage); examples/AGENTS.md repoints
its with-key-policy link; rfc/README.md loses a narrated-history
aside; dsh-code-review / dsh-find-simplifications / verify-md-wrap
references follow the moved content.
- Budget manifest ratchets: AGENTS.md 8200 -> 1500 (now 1,495 words),
packages/README.md 1900 -> 600, packages/AGENTS.md 600 -> 450; the
two new eviction docs join the budget set (testing 800, defensive
550); docs/AGENTS.md raises 1000 -> 1250 for the absorbed writing
rules (the one justified increase). The doc-tiers RFC's deferred list
prunes the two items this change ships.
2026-07-04 14:22:47 +08:00
## Dependencies
Document the codebase thoroughly and tighten type safety
Docs: per-folder README.md for packages/ (family overview + one per
package: service, events, API, extension points, TODOs), examples/,
and examples/echo-agent/; folder-level AGENTS.md (+ CLAUDE.md
symlinks) for packages/ and vendor/; module-level doc comments in
every packages/*/src file; richer JSDoc on all exported API
(event side effects, disposal contracts, error behavior). Root
AGENTS.md gains a "Type Safety and Documentation" policy section:
the codebase aims to be very type-safe and well documented; type
gymnastics are acceptable in core packages when they improve
plugin-author DX; verbose docs are fine as long as they stay strictly
in sync with the code.
Type safety: removed the upstream-inherited "noImplicitAny": false
from tsconfig.base.json — packages/* now compile under full strict
mode; vendor/loader and vendor/include set it locally (vendor/cordis
already did). Eliminated every `: any` / `as any` from packages and
examples (catch clauses use unknown + a CodedError narrowing type;
event data access uses discriminated-union narrowing).
Typed tool schemas: new @deepseek-ai/dsh-tools schema DSL —
SchemaSpec with per-property `required: true` booleans, type-level
InferArgs<S>, a runtime SchemaSpec → JSON Schema converter, and
defineTool() so first-party tools get typed execute(args) with zero
casts (raw JSON Schema still accepted for MCP interop; chosen over
schemastery because it targets JSON Schema generation directly).
echo-tool and all test tools migrated; +7 tests.
2026-06-11 12:39:27 +08:00
2026-07-09 13:01:14 +08:00
The dependency graph is generated: [docs/module-graph.md ](../docs/module-graph.md ) (`pnpm run gen-module-graph` , freshness-gated in CI).
Document the codebase thoroughly and tighten type safety
Docs: per-folder README.md for packages/ (family overview + one per
package: service, events, API, extension points, TODOs), examples/,
and examples/echo-agent/; folder-level AGENTS.md (+ CLAUDE.md
symlinks) for packages/ and vendor/; module-level doc comments in
every packages/*/src file; richer JSDoc on all exported API
(event side effects, disposal contracts, error behavior). Root
AGENTS.md gains a "Type Safety and Documentation" policy section:
the codebase aims to be very type-safe and well documented; type
gymnastics are acceptable in core packages when they improve
plugin-author DX; verbose docs are fine as long as they stay strictly
in sync with the code.
Type safety: removed the upstream-inherited "noImplicitAny": false
from tsconfig.base.json — packages/* now compile under full strict
mode; vendor/loader and vendor/include set it locally (vendor/cordis
already did). Eliminated every `: any` / `as any` from packages and
examples (catch clauses use unknown + a CodedError narrowing type;
event data access uses discriminated-union narrowing).
Typed tool schemas: new @deepseek-ai/dsh-tools schema DSL —
SchemaSpec with per-property `required: true` booleans, type-level
InferArgs<S>, a runtime SchemaSpec → JSON Schema converter, and
defineTool() so first-party tools get typed execute(args) with zero
casts (raw JSON Schema still accepted for MCP interop; chosen over
schemastery because it targets JSON Schema generation directly).
echo-tool and all test tools migrated; +7 tests.
2026-06-11 12:39:27 +08:00
2026-07-21 22:59:41 +08:00
**Extension plugins depend on interfaces, never the concrete loop.** `dsh-agent-loop` is swappable; UI, hook, and tool plugins use `dsh-agent` . Composition bundles, including `dsh-agent-spine-demo` , may depend on spine plugins. Capabilities split into interface / implementation / consumer packages; see [capability seams ](../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md ).
Document the codebase thoroughly and tighten type safety
Docs: per-folder README.md for packages/ (family overview + one per
package: service, events, API, extension points, TODOs), examples/,
and examples/echo-agent/; folder-level AGENTS.md (+ CLAUDE.md
symlinks) for packages/ and vendor/; module-level doc comments in
every packages/*/src file; richer JSDoc on all exported API
(event side effects, disposal contracts, error behavior). Root
AGENTS.md gains a "Type Safety and Documentation" policy section:
the codebase aims to be very type-safe and well documented; type
gymnastics are acceptable in core packages when they improve
plugin-author DX; verbose docs are fine as long as they stay strictly
in sync with the code.
Type safety: removed the upstream-inherited "noImplicitAny": false
from tsconfig.base.json — packages/* now compile under full strict
mode; vendor/loader and vendor/include set it locally (vendor/cordis
already did). Eliminated every `: any` / `as any` from packages and
examples (catch clauses use unknown + a CodedError narrowing type;
event data access uses discriminated-union narrowing).
Typed tool schemas: new @deepseek-ai/dsh-tools schema DSL —
SchemaSpec with per-property `required: true` booleans, type-level
InferArgs<S>, a runtime SchemaSpec → JSON Schema converter, and
defineTool() so first-party tools get typed execute(args) with zero
casts (raw JSON Schema still accepted for MCP interop; chosen over
schemastery because it targets JSON Schema generation directly).
echo-tool and all test tools migrated; +7 tests.
2026-06-11 12:39:27 +08:00
2026-07-14 14:01:35 +08:00
Package READMEs cover purpose, APIs, extension points, and [Model Experience ](../docs/cookbook/adding-a-package.md#4-write-the-package-readme ) unless on the model-agnostic [omission allowlist ](../scripts/verify-package-readme-model-experience.ts ). They also carry `## Known Limitations and Deferred Work` or use its [allowlist ](../scripts/verify-package-readme-limitations.ts ).