Back to directory

dsh-swarm

Curated pickMaintenance: Active

joekytc/dsh-swarm

Run multi-agent task pipelines on DSH like a team — plan, execute, review, and deliver code through a visual kanban with provable completion.

View on GitHub
$ dsh plugin add dsh-swarm

Install

dsh has no central install command — add this plugin’s entry (documented in its README below) to your profile or patch config, then restart.

How installs work

5

stars

0

forks

TypeScript

Language

MIT

License

2026-08-20

Created

2026-09-21

Last push

README

dsh-swarm

简体中文 · English


Say one requirement, reply one confirmation — six specialist agents take it from planning to verified delivery. No commands to memorize.

dsh-swarm is a DSH plugin that turns one requirement into a strict, evidence-verified delivery pipeline. An orchestrator (V) decomposes an approved spec into a strictly ordered phase chain (p → (pt?) → w2 → d → dt → w3 → summary); six single-purpose roles (V / P / W / D / PT / DT) run each phase with isolated, permission-gated tool faces; every handoff is machine-verified against an evidence contract; failures recover through idempotent retry and human-gated reviews; and a live Workflow kanban tab streams all state to the browser via SSE. Design inspired by the Hermes Agent kanban.

TypeScript License npm


Swarm mode turns your main session into a team lead: you state the requirement, it clarifies, plans, confirms, delegates and follows through — entirely in natural language, no commands to remember.

  • No commands to memorize — just state your requirement; no /plan: or /openspec: prefixes needed.
  • Automatic intent recognition — development requests → clarify/plan and build a chain; lessons & retrospectives → persist to memory; group notifications → deliver to WeCom; Q&A / chit-chat → answered directly. Intent is judged by the model, not by a code-level classifier — the confirmation gate below is what stops a misjudged chain.
  • Free delivery/sms <intent> (e.g. "post current progress to the group"): facts are grounded via kanban lookup, then the body is composed per intent and delivered; -s or wording like "private chat" targets the DM. A bare /sms re-sends the latest completed-chain report and /sms blocked [chainId] the block notice — those two bodies are rendered by system code from kanban facts, never rewritten by the lead. Group and private-chat targets auto-resolve to the single saved target (0 or 2+ targets error out; clean up in dsh-im settings, or pin imDelivery.targetId / imDelivery.dmTargetId, which skips the count check — though with imDelivery.botId empty the pinned target must still belong to the auto-discovered bot, or it errors out).
  • Confirmation gate against accidental chains — after the checklist is saved, the lead is instructed to build a chain only once you reply with an explicit affirmative (确认 / 开干 / 开跑 / 开始 / go, etc.). The gate is judged by the model, not enforced by a code-level check; vague replies, topic switches, or edit-only feedback count as not confirmed.
  • The lead is read-only — the main session cannot write/edit repo sources, nor run git mutations (push/commit/reset…); a bare git checkout/git switch of an existing branch is allowed. Writing code is done by the executor (D) in an isolated workspace by design.
  • Progress is always actually queried — ask "how is it going?" anytime and the lead reports from real kanban lookups, never fabricated.

Why it's designed this way

Coordinating several agents on one task typically fails in three ways:

  • Role drift — the "planner" starts writing code, the "executor" reviews its own work, and nobody owns the outcome.
  • Unverifiable handoffs — an agent claims "done" with no reproducible evidence, and the next agent builds on sand.
  • Silent deadlocks — an agent stops without finishing and the pipeline hangs, or bad code is merged before anyone reviewed it.

dsh-swarm encodes a contract against all three: one responsibility per role, enforced by the permission matrix, tool faces and task-body instructions; every handoff must carry structured evidence or the phase will not close; every stall or review failure lands in a visible, recoverable state — with you (the human) as the final trust anchor. It is built correctness-first: deterministic state machines, append-only event sourcing, idempotent schedulers, and a red-team test suite that replays the event log and rejects any illegal transition (mechanics in Advanced).

Two modes

Mode How you use it Notes
Swarm mode (recommended) Just say the requirement in natural language No commands to memorize, intent auto-recognized, runs on confirmation
Command mode (compatible) /plan: <requirement> → clarify → /openspec: confirm Kept for compatibility, functionally equivalent; may be removed in the future — new users should use swarm mode

Quickstart

1. Install

Prerequisites: a working DSH runtime (@deepseek-ai/*), Node.js ≥ 22.19 and npm. Optional: a wiki-vault HTTP service (KB features, see Configuration).

From npm (the published tarball ships the built lib/):

dsh plugin --profile web add @joekytc/dsh-swarm

From a source checkout (rebuild first so lib/ matches the sources):

npm install
npm run build        # tsc -p tsconfig.build.json + client bundle (lib/client.js)
dsh plugin --profile web add .

From GitHub source: dsh plugin --profile web add github:joekytc/dsh-swarm — the repository tracks the built lib/.

2. Switch your main-session preset

Switch the main session's agent preset to Swarm (蜂群模式) — it is installed at $DSH_HOME/.agent-presets/swarm once the plugin is installed.

3. Say → confirm → watch progress

Example conversation:

You: Add a role-management page to the admin project with CRUD and permission checkboxes

Lead: Let me confirm a few things first —
  · Which role fields do you need (name/description/status/…)?
  · Permission source: the existing menu tree, or custom?
  · Any acceptance requirements, e.g. "deleting a role must not affect linked users"?

You: Fields are name and description, permissions from the existing menu tree, acceptance via TDD

Lead: Checklist saved (six spec sections + repo facts). Reply "confirm" to launch —
      I'll spin up the p → (pt) → w2 → d → dt → w3 pipeline.

You: confirm

Lead: Chain created (ch_…), live progress on the kanban tab (Conversation → Trajectory → Kanban).
      First phase: Planning (P)…
  • Kanban: the third tab of the conversation center (Conversation → Trajectory → Kanban). Click a card for Overview / Trajectory / Handoff / Spec / Comments.
  • Completion: when a chain completes, the system audits the workspace and (for D chains) automatically merges the feature branch into the spec-declared target branch. An audit warning blocks the final wrap-up until you confirm ownership in the GUI — it does not gate the merge.
  • Progress: just ask "how is it going?" — the lead reports from real kanban lookups and relays blocking reasons faithfully.

What it does for you

Six roles, one job each — boundaries enforced by the permission matrix, trimmed tool faces and task-body instructions, so no role creep:

Role One-line responsibility What it never does
V Orchestrator Creates phase cards, drives the pipeline, gives guidance on stalls Never executes
P Planner Reads the spec + repo facts, writes the implementation plan Never writes code
PT Plan reviewer Read-only review of P's plan (on demand) Never changes anything
W Knowledge officer Syncs the KB in planning/completion phases Never touches code/git
D Executor The only role that writes code: implement → verify → commit → push feature branch Never merges into the target branch itself
DT Implementation reviewer Empirically verifies D's delivery (tests/build/typecheck/diff) Read-only against the repo

The pipeline (strictly serial within a chain, parallel across chains):

p ──> (pt?) ──> w2 ──> d ──> dt ──> w3 ──> summary
plan   plan rev.  KB    impl  impl rev.  KB    wrap-up
  • pt appears only when P decides a plan review is needed; d is always followed by an implementation review (dt).
  • Chain completion is decided by a mechanical rule (W3 done + D done with delivery evidence + no open tasks), not by an agent's self-assessment.

Configuration

All keys are optional; schema lives in src/config.ts. Most users only need the first three — keep the rest at their defaults.

Key Default Description
storageDir $DSH_HOME/storages/kanban Event log (events.jsonl), orchestration state, per-task workspaces, dispatcher.log. Value must use the unquoted !!js dshHomePath("storages/kanban") form — quoting degrades it into a literal string
wikiVault.baseUrl '' (empty) wiki-vault HTTP service for KB reads/writes — required for KB features; set to your own server
wikiVault.pagePrefix projects/ Namespace prefix for generated wiki pages
roles.models.<role> {} Per-role model: { provider, model, reasoningEffort?, fallbacks?[] }
roles.models.<role>.reasoningEffort high Default reasoning effort for all roles
roles.models.<role>.fallbacks [] Silent fallback candidates (audited via [model-fallback] comment)
dispatcher.staleTimeoutSeconds 14400 Heartbeat timeout; running task without heartbeat is reclaimed
dispatcher.maxRetries 3 Failure retries before circuit → blocked(gave_up)
dispatcher.heartbeatIntervalSeconds 300 Watchdog heartbeat period
dispatcher.maxProtocolViolations 2 Protocol-violation guardrail: once consecutive violations reach this many, the next one is final (gave_up)
dispatcher.maxReworksPerRole { pt: 3, dt: 3 } Max review rework rounds before review/gave-up + [review-final]
prefixRoutes.plan /plan: Command-mode phase-0 planning prefix
prefixRoutes.openspec /openspec: Command-mode approve-and-execute prefix
prefixRoutes.learning /learning Lessons / retrospective prefix
prefixRoutes.send /sms Free-delivery prefix (DM with -s)
memory.enabled true Memory recall index; false makes planning_memory_recall return a disabled notice
memory.maxIndexEntries 8 Max recalled memory entries (1–20)
ui.enabled true Declared switch; not consumed yet — the tab registers unconditionally
ui.contentMinWidth 715 Declared lower width bound (px); not consumed by the client yet — the tab follows the host conversation width
ui.contentMaxWidth 780 Declared upper width bound (px); not consumed by the client yet
ui.sseHeartbeatSeconds 20 SSE heartbeat interval
gates.enabled true TDD measurement gate; false → silent skip (no event)
gates.timeoutMs 600000 Per-command gate timeout (ms), SIGKILL at the deadline
gates.forbidden ['rm -rf /', 'git push'] Command-blacklist substrings (defence in depth)
evidenceReplay.enabled false L3 replay of model-written commands — not a sandbox, see Issue evidence check
evidenceReplay.timeoutMs 600000 Per-replay command timeout (ms)
evidenceReplay.allowPrefixes ['npx --no-install vitest', 'npm test', 'npm run build', 'npm run typecheck', 'tsc', 'eslint'] Allowlisted tool prefixes (word-boundary match)
imDelivery.enabled false WeCom delivery via dsh-im (W3 wrap-up / chain blocked / review gave-up)
imDelivery.botId '' Empty = auto-discover the only wecom bot
imDelivery.targetId '' Empty = auto-discover the only saved group target
imDelivery.dmTargetId '' DM target for /sms -s
imDelivery.fallbackBotId '' Bot used when preset-based matching finds nothing
reviewEngine.mode delegate delegate or managed — see Review engine (ocr)
reviewEngine.managed.provider '' Model-chain provider id used in managed mode
reviewEngine.managed.model '' Model-chain model id used in managed mode
wikiWritePresets ['swarm', 'kanban-w', 'ptc'] Presets allowed to call wiki_write (page paths are still whitelisted by namespace)

Review engine (ocr)

Implementation reviews (the in-chain DT phase and standalone reviews) are powered by open-code-review (ocr), with two modes switchable in the web config panel under 「Swarm 配置 → 评审引擎(ocr)」 (Swarm config → Review engine (ocr)):

Mode How it works Notes
Delegate (default) ocr only outputs the review scope and rules; DT reviews each file with its own model Zero API keys, works out of the box
Managed ocr runs the full review with your chosen provider/model and returns normalized findings in one shot For large change sets; delegate mode hints at switching past 50 files (a hint only, never auto-switched)

Install

  • When ocr is missing, the config panel shows a red banner — click 「安装 ocr」 (Install ocr) for a one-click global install (async, cancellable);
  • or run npm install -g @alibaba-group/open-code-review in a terminal, then verify with ocr --version.

Standalone review (no chain needed)

  1. Switch the session to 「交付评审官(DT)」 (Delivery Reviewer (DT)) at the top of the dsh web UI and just talk;
  2. State the review target: a local directory / branch range (from…to) / a single commit / uncommitted workspace diff / a public repo URL (auto-cloned into a temp dir, discarded afterwards);
  3. The report is first fully output to the conversation;
  4. Only after you confirm is it written to the KB at projects/<repo>/reviews/<topic>-<date>/ — remote KB mode only; with the default empty wikiVault.baseUrl (local mode) no wiki page is written.

Read-only in practice: bash/run_code writes and wiki writes outside the reviews namespace are blocked by the guard, while the fs write/edit tools are not blocked in a standalone DT session.

Configuration notes

  • Mode, provider and model are all chosen on the 「评审引擎(ocr)」 card; the provider/model dropdowns share the same catalog as the model chain;
  • After picking, click 「应用到 ocr」 (Apply to ocr) — the system writes the wiring into ocr's custom config (dsh-managed); the API key is resolved from the dsh model config and written into ocr, never shown in plain text in the panel; if resolution fails it degrades gracefully and points you to a manual ocr config provider in a terminal;
  • When managed is not ready, the ocr tool refuses the managed call and returns delegate guidance; the reviewer switches to delegate mode — nothing is blocked.

Official docs: Installation · Model configuration · Delegate mode


Trust & guardrails (user's view)

  • Read-only hard gate for the lead — in swarm mode, main-session writes to sources and git mutations are blocked by a system gate; if blocked, just let the lead explain — execution is done by the D role.
  • Confirmation gate — the lead only builds a chain after you reply with an explicit affirmative (enforced by the lead's instructions, not by a code-level check).
  • TDD hard gate — implementations must ship with tests (or an explained skip); reviews machine-verify "tests really ran, and were written first".
  • Human trust anchors — spec approval, unblock, audit confirmation and chain deletion are human-only; role agents cannot approve specs, and a chain is only created from your confirmed routing call (the main session routes as human).
  • Guardrails are constraints, not a sandbox — PT/DT write guards rely on path and command regexes (reviewers get no git credentials), and review evidence is existence-checked: fields must be present and well-formed, while replaying the commands to prove they ran happens only when evidenceReplay.enabled is turned on.
  • Full mechanics (permission matrix, delivery contract, review chain, rework, failure recovery) live under Advanced / Developers.

Advanced / Developers

Mechanics and implementation details below — regular users can skip.

Roles & the execution pipeline (full table)

Six roles are dispatched by the scheduler as one-shot agent sessions (deterministic session id kbn-<taskId>; a retry resumes that same session — resumeSessionId is always null in the current implementation — while a rework task starts its own kbn-<reworkId> session). Each role-agent session is bound to exactly one task (boundTaskId) and gets a trimmed tool face. V is the exception: a chain-scoped orchestrator session (kbn-v-<chainId>) with no boundTaskId.

Role Alias Responsibility Tool face (highlights)
V Orchestrator Drives the phase machine, creates one card per phase, posts [blocked-review] guidance on stalls. Never executes. kanban_create + task tools + spec view
P Planner Reads spec + repo facts (incl. read-only self-checks), writes an OpenSpec implementation plan, opts into PT via pt_decision.needed. Never executes. Task tools + spec view, read-only (writes only openspec/changes/)
PT Plan reviewer Read-only review of P's plan (requirements alignment, completeness, logic). Outputs verdict + issues. Task tools + spec view, read-only ToolGuard
W Knowledge officer W2/W3 KB sync (w:kb). Never touches code/git. Task tools + wiki_search/read/write (remote) / skill→llm-wiki (local) + prefetch_file/prefetch_external/prefetch_kb + read-only spec view
D Executor The only role that writes code: worktree → implement → verify → [AI-GEN] commit → push feature branch (merging into the spec-declared target branch is done by the system only after DT passes). Task tools + wiki read + bash/fs/run_code (full dev) + subagent (spawn/fork/list-agents) + goal
DT Implementation reviewer Empirically verifies D's work (test/build/typecheck/diff/git + open-code-review), writes review page to KB. Read-only against the repo. Task tools + wiki read/write (review namespace) + ocr_review + bash/fs/run_code, read-only ToolGuard

Guardrails in detail

Permission matrix

can(action, actor, task, { boundTaskId }) in src/domain/permissions.ts. "Bound" means the actor is the role agent session spawned for that exact task (boundTaskId === task.id and, for complete, also actor === task.assignee).

Action V P W D PT DT Human System
create-chain / create-task
claim
complete bound bound bound bound bound ✅ (GUI)
block bound bound bound bound bound
heartbeat bound bound bound bound bound
comment
unblock
archive
spec-approve
spec-edit
spec-attach
update-title
delete-chain
wiki-write ✅ (review ns)
wiki-read
prefetch
audit-confirm
create-rework-task
reopen-chain
waive-review

Key guarantees (two):

  • The main session cannot execute. Its kanban tool face is a read-only subset — kanban_show/kanban_chain/kanban_list/kanban_comment plus the human-recovery pair kanban_reopen_chain/kanban_waive_review — together with spec_card_view, kanban_route, the planning_* tools and sms_send; never kanban_create/kanban_complete/kanban_block. Chains/specs are created only via swarm-mode intents or /plan:+/openspec:; the GUI observes and mutates task state but never creates chains or tasks — "who decided to run what" stays explicit and auditable.
  • Session binding prevents cross-task escalation (a W agent bound to task A cannot complete/block task B even though both are W tasks); DT writes are confined to the projects/<repoSlug>/<chain>/review/ namespace by a ToolGuard on top of the matrix; and no role agent can approve specs, unblock, confirm audits, waive a review or reopen a chain — those are human trust anchors; system handles only mechanical bookkeeping.

Delivery contract (upstream owes downstream)

Each phase's handoff must carry the keys its downstream actually reads (src/domain/delivery-contract.ts). Missing delivery keys block the W/P card immediately and admit no human exemption; the D/PT/DT evidence gates instead reject complete with an error (the card stays running) and are human-exempt. The orchestrator never builds a downstream card on a blocked parent:

Card Required handoff keys
W2 / W3 (w:kb) kb_url + page_path — non-empty is not enough: with a configured wikiVault.baseUrl the kb_url must start with it (and must be exactly '' in local mode), while page_path must sit in the allowlisted namespaces (wiki/** locally)
P (p:openspec) artifacts_path + pt_decision (needed boolean required; when needed: true, reason is required)
D (d:execute) changed_files + (commit_hash or push) — hasDeliveryEvidence; branch (feature branch) is not a delivery key, but when the TDD gate actually runs the tests it checks the branch and bounces the card if it is absent or mismatched; tdd (test_files or skipped.reason, XOR)
PT / DT review_evidence (schema-valid) — validateReviewEvidence

TDD hard gate (evidence threshold)

D completes only with tddtest_files (with test_first) or skipped.reason (XOR, delivery-evidence.ts). DT's review_evidence must carry tdd; whenever tdd.test_files are declared the runner must be vitest (test.runner), and on a pass verdict test_first === true must hold (review-evidence.ts). This makes "tests actually ran, and were written first" a machine-checked property rather than a claim.

Gate skip alarm & declaration cross-check

A declaration that disagrees with the diff no longer passes the gate silently (three silent-skip modes remain, emitting no event: gates.enabled=false, a handoff without worktree_dir, and non-d:execute cards):

  • task/gate-skipped event — a declared tdd.skipped is allowed when the diff is pure docs/config, or when the diff cannot be computed (conservative alarm-skip); both leave the event as an audit trail. Otherwise the gate bounces the card back (same session, agent fixes and re-completes).
  • Declaration ↔ reality cross-check — declaring test_files with no test-file change in the diff (stale-test handoff), an empty test_files, an invalid path, or a branch mismatch all bounce instead of silently skipping.
  • After 3 cumulative bounces the task is blocked for human review (gave_up: gate bounced 3 times).
  • Gate runs now archive raw output to <storageDir>/gate-logs/<taskId>.log (path is referenced in the gate event detail).
  • review_evidence.lint must be a structured object (aligning with build/typecheck); null/scalars are rejected.

Issue evidence check (PR2, opt-in)

Reviewer-reported issues (DT cards only — PT issues are never evidence-checked) can carry evidence = { file, command, exit } (raw output archive, first line [exit code: N]). Verification is three-tier: missing evidence → flagged (not-provided; critical/high → could-not-replay + needs-human); archive paper-check (zero execution) → matches; on mismatch a replay re-runs the command — only if evidenceReplay.enabled is turned on, and only for allowlisted tool prefixes (word-boundary match; npm run restricted to fixed script names). Replays execute model-written commands and are NOT a sandbox; keep the switch off unless you accept that risk. Results are summarized in a review/evidence-check event; differs never auto-fails a review — it surfaces to human review.

Phase-0 planning checklist

Planning runs a read-only planning session (grill-meplanning_prefetchplanning_checklist_save, planning-driver.ts). The checklist carries a structured manifest (repo facts + file baseline, prefetch-manifest.ts); an invalid manifest blocks the save, and chain creation mounts the checklist as the file-prefetch + kb attachments on the spec card (prefix-router.ts).

Review quality chain

View on GitHub

DSH Plugins is an independent community directory of DeepSeek Harness plugins. Not affiliated with or endorsed by DeepSeek. Third-party plugins are not security-audited — review the source before installing.

New DeepSeek Harness plugins, weekly. No spam.