## Write a plugin A Harness function/namespace plugin exports `name`, `inject`, and `apply` — cordis's Loader reads those separately. **`export default` breaks this shape** ([why](./docs/postmortem/0001-acp-default-export-drops-inject.md)): the Loader keeps only the `apply` function and silently drops `inject` / `name`, so the plugin fails to load with `cannot get property … without inject`. Inside `apply(ctx)`, tools / LLM adapters / services register through `ctx.*`. The minimal echo tool from [`examples/echo-agent`](./examples/echo-agent): ```ts // echo-tool.ts import type { Context } from 'cordis' import { defineTool } from '@deepseek-ai/dsh-tools' export const name = 'echo-tool' export const inject = ['tools'] export function apply(ctx: Context) { ctx.tools.register(defineTool({ name: 'echo', description: 'Echo the given text back, uppercased.', parameters: { text: { type: 'string', required: true }, }, async execute(args) { // args is typed: { text: string } return [{ type: 'text', text: `ECHO: ${args.text.toUpperCase()}` }] }, })) } ``` `parameters` uses the [schemastery](./vendor/schemastery) JSON-Schema-shaped DSL — one field per property, with `required: true` for mandatory ones. A leaf `cordis.yml` is a flat `EntryOptions[]` the Loader iterates; this tool's entry looks like: ```yaml - id: echo-tool name: './echo-tool.ts' # your tool ``` Alongside it, a bootable config also needs an LLM adapter and a `stdio-agent` app entry whose `config.model` points at an id that adapter registers. The minimal runnable version — mock LLM + this echo tool + a `stdio-agent` entry wired to `mock-echo` — is [`examples/echo-agent`](./examples/echo-agent), launched via: ```sh pnpm run demo:echo ``` LLM-adapter and UI-plugin shapes: [`docs/cookbook/extension-cookbook.md`](./docs/cookbook/extension-cookbook.md). ## Packages All packages ship under the `@deepseek-ai/dsh-*` scope. Grouped by family: | Family | What lives here | |---|---| | **Core** (`packages/core/`) | `dsh-scope` · `dsh-session` · `dsh-tools` · `dsh-agent` · `dsh-agent-loop` · `dsh-system-prompt` | | **LLM** (`packages/llm/`) | `dsh-llm` (the seam) + `dsh-llm-deepseek` (hand-rolled) and `dsh-llm-pi-ai` (library-backed twin — same DeepSeek endpoint, different internals, kept for design verification) | | **Bash** (`packages/bash/`) | Shell execution: local + sandboxed backends, model-facing `bash` tool | | **Filesystem** (`packages/fs/`) | Filesystem service with a policy layer, `read` / `write` / `edit` tools | | **Web** (`packages/web/`) | Web search (Perplexity, Exa, DeepSeek) + fetch, model-facing tool | | **Sandbox** (`packages/sandbox/`) | Process-confinement seam (bwrap / Landlock / Seatbelt) — wraps a caller's argv under a per-call policy; execution itself lives in `ctx.bash` | | **Code runtime** (`packages/code-runtime/`) | JS worker runtime that Code Mode dispatches into | | **Sub-agents** (`packages/subagent/`) | `spawn`, `fork`, plus in-process / subprocess / ACP-backed backends | | **Workflows** (`packages/workflow/`) | Dynamic workflow orchestration (worker-thread execution) | | **Skills** (`packages/skill/`) | Skill-provider registry (`ctx.skills`) + a local-filesystem provider | | **Session persistence** (`packages/session-persistence/`) | Event-log persistence: JSONL and SQLite backends | | **Session query** (`packages/session-query/`) | `ctx.sessionQuery` — unified logical-corpus reads over live sessions + persistence | | **Compact** (`packages/compact/`) | Context compression / summarization | | **Context** (`packages/context/`) | Opt-in request-context enrichment (e.g. `dsh-time-context` — dynamic time-in-prompt) | | **Cordis toolset** (`packages/cordis/`) | Model-facing tools that inspect / mount / unmount cordis plugins at runtime | | **UI apps** (`packages/ui/`) | `dsh-stdio-agent` (REPL) · `dsh-acp-agent` (ACP server) · `dsh-app-boot` · approval + ask-user primitives | | **Hooks** (`packages/hooks/`) | Hook protocol + Claude Code / OpenAI Codex hook-config bridges | | **Guards** (`packages/guard/`) | Advisory loop-hygiene plugins (e.g. `repeat-tool-guard` for repeated-call escalation) | | **Timeouts** (`packages/timeout/`) | `timeout-policy` — a zero-config `tools/execute` wrapper enforcing per-tool `timeoutMs` | | **Todo** (`packages/todo/`) | The model-facing `todo_write` tool (whole-list task tracker) | | **Support** (`packages/support/`) | `invariants` — runtime diagnostic plugin mounted unconditionally by the shipped `dsh-agent-spine-demo` bundle; plus test/dev-only helpers (`llm-replay`, `acp-snapshot`, `subagent-mock`) | | **Example bundles** (`packages/examples/`) | Ready-to-run demo compositions the top-level `demo:*` scripts launch: `dsh-agent-spine-demo` (default spine + capabilities), `dsh-stdio-demo` (REPL), `dsh-acp-demo` (ACP server), `dsh-jsonrpc-demo` | | **Utils** (`packages/util/`) | Internal utility packages (`brand`, `timeout`) | For the full module dependency graph, see [`docs/module-graph.md`](./docs/module-graph.md). ## Deep dives To understand what makes DeepSeek Harness different, start here: - [Architecture](./docs/architecture.md) — the service taxonomy and the microkernel structure - [Agent lifecycle](./docs/agent-lifecycle.md) — how a turn flows through the loop, with sequence diagrams - [Cordis primer](./docs/cordis-primer.md) — a working introduction to the underlying plugin framework - [Tool execution pipeline](./docs/tool-execution-pipeline.md) — how a tool call passes through permission gates, hooks, and logging - [Capability seams](./docs/capability-seams.md) — the extension points each service exposes - [Code Mode](./docs/rfc/implemented/feature/2026-06-15-code-mode.md) — the model writes one JavaScript program per turn that chains many bash / tool calls, executed in a single runtime pass. **One model round-trip per multi-step operation**, not one per call. - [Dynamic Workflows](./docs/rfc/implemented/feature/2026-07-05-dynamic-workflows.md) — the model writes a plain-JS orchestrator that fans out sub-agents in parallel, joins their results, and returns to the parent — instead of a chain of sub-agent tool calls. - [Self-referential Cordis toolset](./docs/rfc/implemented/feature/2026-07-08-self-referential-cordis-toolset.md) — the SDK's own plumbing (`cordis_inspect`, `cordis_mount`, `cordis_unmount`) is exposed as tools, so the model can inspect its own runtime and load new plugins on the fly. Docs site: **[deepseek.com/harness-sdk/docs](https://deepseek.com/harness-sdk/docs)**. ## Community - **[GitHub Issues](https://github.com/deepseek-harness/deepseek-harness/issues)** — bug reports - **[GitHub Discussions](https://github.com/deepseek-harness/deepseek-harness/discussions)** — questions, ideas, RFCs Real-time chat on Discord. Release announcements on X / Twitter. ## License [BSD 3-Clause](./LICENSE) © DeepSeek