Native seams for a static fullstack-expert Cordis plugin

August 16, 2026 · View on GitHub

Scope: a static plugin/package mounted by a profile or agent preset (not a dynamic runtime plugin). The installed artifacts are @deepseek-ai/* version 0.1.0-rc.6 and Cordis 4.0.1; package manifests point at the official repository and package directories. Local citations below are authoritative for the installed runtime; GitHub links identify the corresponding upstream source.

1. Package shape and build/export conventions

  • First-party packages are ESM packages with type: "module", main: "lib/index.js", and declarations in lib/types/index.d.ts. Public exports use conditional types/default targets; source is commonly exposed only as ./src/* plus ./package.json. Example: @deepseek-ai/dsh-agent/package.json:13-30; instructions package: @deepseek-ai/dsh-agent-instructions/package.json:13-32.
  • Upstream package authoring rules are in /tmp/deepseek-harness-official at commit 47f943859bef60e4160492346772ded9b24f765a, especially packages/AGENTS.md:5-6,20-25: service packages export a default service class, while function plugins export named name/inject/Config/apply (no default export); source/build wiring follows srclib/types with tsconfig, workspace references, and aggregate requirements.
  • The canonical bundle package adds a patch export and bundle manifest: @deepseek-ai/dsh-base/package.json:13-39 exports ././invariant/./cordis.patch.yml/./src/*/./package.json, publishes built lib/*, declarations, and the patch, and declares dsh.bundle.patch: "./cordis.patch.yml". Ordinary tool packages are narrower: @deepseek-ai/dsh-tool-bash/package.json:13-32 exports built root/invariant/source glob/package JSON.
  • Published files lists built JS and declaration outputs, not the whole source tree (dsh-agent/package.json:32-36). Ordinary core packages may omit scripts; client/API packages commonly expose bundle: tsdown and watch: tsdown --watch (for example @deepseek-ai/dsh-client-ui-sidebar/package.json:67-76 and @deepseek-ai/dsh-api-gateway/package.json:71-74). Do not assume every package has a build script; the launcher only states that production requires built artifacts and repository-root pnpm run build (dsh/README.md:45-47).
  • A static plugin should ship its built lib artifacts and declarations and expose only deliberate public subpaths. The agent loop is intentionally stricter: its README says the root exports only the plugin/service/config contract and exposes no ./src/* escape hatch (@deepseek-ai/dsh-agent-loop/README.md:54-56). Some packages additionally expose typed faces such as ./types (agent/tools manifests) or ./presentation; client-capable packages export ./client and declare dsh.client metadata (dsh-client-ui-sidebar/package.json:16-41).
  • Cordis composition rows name the package root and configuration; a package root exports the Cordis plugin contract (name, optional inject, Config, apply) rather than model-specific internals. This is explicit for filesystem and bash tools: @deepseek-ai/dsh-tool-fs/README.md:60-62, @deepseek-ai/dsh-tool-bash/README.md:7-11.
  • Production uses built package/frontend artifacts; the launcher README requires pnpm run build, while pnpm dsh ... is the source-execution path (@deepseek-ai/dsh/README.md:45-47).

2. Agent prompt sections and scoped composition

  • SystemPrompt (ctx.systemPrompt) is the native seam: register PromptSection { name, order, text, complete? } with ctx.systemPrompt.section(...); register dynamic context, variables, and tool-schema providers through the corresponding methods. Registrations are scope-layered and disposed with the calling fiber (@deepseek-ai/dsh-system-prompt/README.md:16-25, 31-45).
  • Sections concatenate by ascending order; -100 is harness identity, 0 deployment persona, and tool guidance normally occupies 100–199 (dsh-system-prompt/README.md:33-36). A fullstack persona should normally be an ordinary ordered section, not a complete section, because one effective complete section suppresses the rest and multiple complete sections reject assembly (dsh-system-prompt/README.md:20,25,29).
  • Agent-local behavior belongs in agent.ctx: registrations shadow global sections/tools/variables and are unwound with that agent (@deepseek-ai/dsh-agent/README.md:15,99-111). For a static preset plugin, register against the preset standing scope; for per-agent specialization, use the agent setup context.
  • system-prompt/assemble is the authoritative cooperative waterfall. A listener may replace the assembly, but must preserve active Code Mode/structured-output protocol (dsh-system-prompt/README.md:27-29). A fullstack plugin should prefer additive sections and avoid replacing the entire assembly.
  • Concrete registrations: dsh-tool-fs/lib/index.js:323-333 adds tool:read at order 100 before registering read; dsh-tool-bash/lib/index.js:254-259 adds tool:bash at order 105 before registering bash. The app boot helper offers another global example: addHarnessSourceSection registers harness:source (dsh-app-boot/README.md:23-24). Agent-context integration can instead inject sourced user messages at agent/pre-step (packages/context/agent-instructions/src/index.ts:322-347 in the official checkout).

3. Skills provider and runtime registration

  • @deepseek-ai/dsh-skill owns ctx.skills. The official registry contract is /tmp/deepseek-harness-official/packages/skill/skill/README.md:5-24,42-64: external sources register synchronously through ctx.skills.registerProvider(create) with { signal, invalidate }, provider names are unique within the calling scope layer, and consumers use snapshot, list, and get; ctx.skills.register(runtimeSkill) is the embedded-skill path and skills/change is the invalidation event. The installed rc.6 README describes the same API (dsh-skill/README.md:5-19,48-56).
  • Embedded/static skills use ctx.skills.register(skill), which supplies runtime provider/invocation defaults and returns a Cordis disposer. Runtime registrations are first-wins within their layer; project providers can override runtime skills by rank (dsh-skill/README.md:58-64).
  • The registry does not register the model-facing skill tool or prompt catalog; @deepseek-ai/dsh-tool-skill is the consumer that does that (dsh-skill/README.md:62-68). Thus a fullstack plugin that publishes skills should depend on the registry, while tool exposure remains a separate composition row.
  • The shipped filesystem provider discovers <name>/SKILL.md bundles or flat <name>.md, with kebab-case names and frontmatter fields such as name, description, whenToUse, and invocation flags (official /tmp/deepseek-harness-official/packages/skill/skill-filesystem/README.md:5-11,29-51; installed dsh-skill-filesystem/README.md:41,55). Its concrete provider requires inject: ['skills'], supports configured roots/watchers, and registers the provider in installed lib/index.js:664-699 (export at :880); the standard preset mounts it with tool-skill (@deepseek-ai/dsh/config/agent-presets/standard/agent.cordis.yml:76-87).
  • The model-facing loader remains separate: dsh-tool-skill/lib/index.js:116-145 registers the skill tool and its catalog behavior, while its agent/pre-step listener is in the following implementation region. A provider alone does not expose a model tool.

4. Tool registration and model exposure

  • ToolRuntime is ctx.tools. Register a trusted definition with ctx.tools.register(...); definitions require a canonical output declaration and are disposed with the fiber. Agent-context registration is agent-local and shadows same-named global tools (@deepseek-ai/dsh-tools/README.md:18-27).
  • Tool schemas enter prompt assembly automatically through ToolRuntime's SystemPrompt integration (dsh-tools/README.md:29-31). Tool guidance is separate: register a section explicitly, as dsh-tool-bash does with tool:bash order 105 (dsh-tool-bash/README.md:9-11).
  • The execution seam is ordered: tools/pre-execute allow/deny/ask, monotonic ctx.tools.guard, tools/execute around-dispatch, tools/post-execute, definition finalizeContent, then observe-only tools/result (dsh-tools/README.md:1-5,37-60). Use these for policy/telemetry rather than wrapping the loop.
  • A static plugin should use defineTool where practical for typed parameter/output schemas (dsh-tools/README.md:63-97). Tool bodies receive exec.signal; cancellation is cooperative and tool side effects are not rolled back (dsh-tools/README.md:33-35,116-125).

5. Agent and session events

  • @deepseek-ai/dsh-agent owns the live agent/* coordination vocabulary, independent of the concrete loop. ctx.agents provides registry access, initiator propagation, and agent-scoped contexts (dsh-agent/README.md:9-15,26-45). Exact event signatures/payloads belong to generated official subsystem docs, not README paraphrases: use /tmp/deepseek-harness-official/docs/subsystems/core.md#cordis-surface for agent/tool/core contracts and /tmp/deepseek-harness-official/docs/subsystems/session.md#cordis-surface plus persistence-catalog.md for session payloads.
  • Lifecycle notifications: agent/created runs after setup and registry publication; agent/session-start is the first supported non-vetoing startup injection point; agent/disposed means the exact agent left the registry (dsh-agent/README.md:47-53). Other useful hooks include agent/pre-step, agent/request-error, agent/turn-stopping, and inbox inserted/claimed/discarded notifications (dsh-agent/README.md:53-61).
  • Turn/step boundaries and token chunks are durable session events, not mirrored agent notifications. @deepseek-ai/dsh-session owns the append-only Session, ctx.sessions, and session/event/session/flush durability seams (dsh-session/README.md:5-17,31-43). Persistence plugins subscribe to session/event, flush on session/flush, and mirror session lifecycle if needed (dsh-session/README.md:89-93).
  • Plugins adding durable facts should declaration-merge SessionEventMap, append through Session, and await ctx.sessions.flush(session) when durability is required (dsh-session/README.md:69-73). Do not use live agent events as a substitute for reconstructable session facts.
  • The concrete loop (dsh-agent-loop) is intentionally not the extension seam: new behavior belongs in plugins and event listeners; the loop injects agents, sessions, llm, tools, and systemPrompt (dsh-agent-loop/README.md:5-15,28-34,74-83).

6. Filesystem, shell, and services

  • Filesystem capability is ctx.fs (@deepseek-ai/dsh-fs): resolve targets, canonical process paths/file URLs, containment, metadata, text/stream reads, bounded bytes, directory listing, atomic writes, and literal atomic edits. The provider contract is separate from policy and model-facing tools (dsh-fs/README.md:5-16,18-37,43-47).
  • @deepseek-ai/dsh-tool-fs owns model-facing read, read_image, write, and edit; it calls ctx.fs directly and uses fs/write-intent, fs/edit-intent, and fs/observed events for policy (dsh-tool-fs/README.md:1-17,43-58). A fullstack plugin needing repository inspection should consume ctx.fs, not native fs globals. The installed implementation is a concrete reference: dsh-tool-fs/lib/index.js:1182-1186 injects tools, fs, and systemPrompt, registers tools at :333, :604, :749, and :952, and conditionally injects attachments at :1210-1212; the installed rc.6 source does not include fsObservationPolicy in this inject list, so service keys must be checked against the installed version rather than copied from another revision.
  • Process execution is ctx.subprocess (@deepseek-ai/dsh-subprocess): executable resolution, explicit-argv managed spawn, terminal spawn, bounded stdio, tree termination, scrubbed environment, and disposal cleanup (dsh-subprocess/README.md:5-18). Commands are not shell-interpreted unless the caller explicitly invokes bash -c (dsh-subprocess/README.md:9-12).
  • Shell capability is ctx.shell; @deepseek-ai/dsh-shell defines the abstract executor (run, start, incremental output, sandboxMode, disposal) in README.md:5-30, while @deepseek-ai/dsh-bash-local implements it over ctx.subprocess (dsh-bash-local/README.md:5-7). Installed rc.6 naming: dsh-tool-bash/lib/index.js:110-116 injects ['tools', 'shell', 'systemPrompt', 'shellEnv']; do not normalize these to bash/bashEnv from a different revision. dsh-tool-bash/lib/index.js:254-259 registers tool:bash (order 105) and the bash tool. For a plugin's trusted host work, inject/use the service seam; do not call undeclared globals.
  • Hard dependencies should be declared with inject; optional services should be read with ctx.get(...) and handled when absent. This is also why filesystem tools keep policy optional and why tool-bash stays pending until its required services exist (dsh-tool-bash/README.md:5-9; dsh-tool-fs/README.md:14-17).

7. Static fullstack-expert preset shape

  • The shipped standard preset is the closest reference composition: @deepseek-ai/dsh/config/agent-presets/standard/agent.cordis.yml:20-33 owns persona, :76-87 mounts skills/tool-skill, :100-124 mounts plan-mode guidance, and later rows provide the model-facing tool set. A fullstack-expert preset should copy this composition into the user-owned preset root and change the persona/rows there, rather than edit the shipped install.
  • The preset runtime is a standing mount, not a per-session duplicate: the agent view resolves agent → preset → global, and mount() belongs in factory setup; child agents use composeFrom so they inherit the parent's exact generation (@deepseek-ai/dsh-agent-presets/README.md:5-8,29-51). Package names resolve from the host composition while relative paths resolve from the preset directory (:63-69).
  • Keep host-plane registries and capabilities (agents, sessions, filesystem/policy, shell/environment, model route) in the base/web host composition. A preset-owned service must be under a cordis:group with isolate; otherwise it publishes root/process-global and can collide across presets (dsh-agent-presets/README.md:115-125).

8. Profile bundles and cordis.patch.yml

  • A profile is $DSH_HOME/profiles/<name> with package.json (dependencies plus dsh.profile.bundles) and a user cordis.patch.yml. Composition order is: bundle patches in manifest order, profile patch, home-level patch, then CLI overlays (@deepseek-ai/dsh/README.md:30-41). The official loader seam is /tmp/deepseek-harness-official/packages/boot/app-boot/README.md:16-23,30-32,36-45: loadOptionalPatches, composeEntries, bundle declaration/resolution, the ordered bundle list, later profile/home overlays, live watchUserPatches, and module-resolution rules.
  • The shipped bundle package manifest is the exact shape: @deepseek-ai/dsh-base/package.json:13-39 includes dsh.bundle.patch: "./cordis.patch.yml". Bundle-only metadata is distinct from ordinary static plugins: only bundle packages need to export ./cordis.patch.yml and declare dsh.bundle.patch; an ordinary plugin row can be inserted by an existing profile/bundle patch without carrying a patch file.
  • A bundle package declares "dsh": { "bundle": { "patch": "./cordis.patch.yml" } }; loadProfile resolves listed bundles from the installation first, then profile node_modules, and composeEntries uses the same Include patch algorithm as boot (@deepseek-ai/dsh-app-boot/README.md:36-38).
  • cordis.patch.yml is a top-level YAML array of Include patch options. The shipped headless/web patches show the concrete row grammar and flags (@deepseek-ai/dsh-headless/cordis.patch.yml:7-35; @deepseek-ai/dsh-web-app/cordis.patch.yml:1-13,16-45,47-59,102-143): insert rows carry id/name/config, rows may be disabled, and !!js expressions can derive values after services exist. An id-targeted patch replaces the matched row's whole config (restate fields you retain), rather than deep-merging. Empty/comments-only is invalid; [] disables a layer (dsh-app-boot/README.md:16-19,43-45,60).
  • watchUserPatches keeps profile/home patches live and recomposes transactionally; a failed parse/read/candidate leaves the last good tree running and emits hmr/config-update-failed (dsh-app-boot/README.md:19,45).
  • The shipped base patch is the canonical composition example: @deepseek-ai/dsh-base/cordis.patch.yml:1-13 inserts its rows over an empty root; native service/tool rows occupy the later ranges :15-43, :163-248, and :281-425. The web patch documents the agent-plane split and ownership (@deepseek-ai/dsh-web-app/cordis.patch.yml:276-330,367-425): host retains registries/persistence/sandbox/model route, while per-agent tool/prompt rows move into presets. Its early rows also define the browser roster seam: dsh.client entries are scanned into window.__DSH_BOOT__ (dsh-web-app/cordis.patch.yml:1-12,45-50).
  • A web/client-capable plugin is a separate seam from adding a host row: it needs a host root export plus a built ./client export and dsh.client metadata; client packages commonly declare client dependencies and bundle/watch scripts (dsh-client-ui-sidebar/package.json:16-41,67-76; API gateway dsh-api-gateway/package.json:16-45,71-74).
  • For a static fullstack-expert plugin, the native integration is therefore: publish a package with built exports; add a bundle patch row (or insert the row in a profile patch); compose the prompt/tool/skill registrations in that plugin; and ensure required provider rows (dsh-fs, shell/subprocess, skills, tools, agent/session services) are present in a lower bundle layer. Do not edit shipped preset installs; a copied user preset is a whole snapshot, while cordis.patch.yml is the intended overlay mechanism (dsh-agent-presets/README.md:53-67,145-153).

Primary source index