claude-harness/dsh/README.md

7.4 KiB
Raw Blame History

dsh — DeepSeek Harness adapter

Spike of the claude-harness port for DeepSeek Harness (DSH 0.2.1-rc.3). The Claude Code installation in ~/.claude stays untouched; this directory is a separate Cordis bundle plus a thin install helper.

What works in the spike:

  • guard-main / require-plan — the tested bash/Python hooks run through ctx.tools.guard; the agent gets BLOCKED with the same messages as in Claude Code;
  • superpowers bootstrap — using-superpowers is injected once per session from agent/pre-step and re-injected after compaction;
  • roles — the model loads them with the role skill (~/.dsh/roles, then ~/.claude/roles, then repo roles/); /role dev|admin|analyst|qa remains the user-facing command and injects the same text, without Claude's auto-memory step;
  • SDD — the sdd skill executes a plan through asynchronous subagent dispatches (report files, task review, fix loop, ledger), with controller modes for one plan and for several parallel plans; the optional overlay enables model routes and depth 2.
  • OpenSpec — воркфлоу идут проектными скиллами .agents/skills/openspec-* (ставит openspec init --tools agents); глобальной копии нет, слэш-команд нет. Установка в проект: bash dsh/install.sh --openspec.

Not yet: briefing, harness-check, role-hint, harness-doctor, auto-memory, caveman. See PORT.md for the design, mapping table, and risks.

Quick start

# Static check
bash dsh/install.sh --check

# Superpowers source: get it once per machine. install.sh never downloads
# anything and no longer depends on ~/.claude.
git clone --depth 1 https://github.com/obra/superpowers ~/.dsh/superpowers
# ...or point at any checkout of the superpowers repo / its skills directory:
bash dsh/install.sh --skills --superpowers-from /path/to/superpowers
# ...or export DSH_SUPERPOWERS_SOURCE=/path/to/superpowers

# Global instructions, superpowers skills, local role skill, and roles
# (run from a terminal; these write outside the session workspace)
bash dsh/install.sh --global
bash dsh/install.sh --skills
bash dsh/install.sh --roles

# В корне проекта, где уже есть openspec/: добавить agents-скиллы
bash <harness>/dsh/install.sh --openspec

# Install the bundle in DSH:
#   Plugins -> install a bundle from dsh/bundle
#   or ask the agent to call plugin_manager install_bundle with that target.

--skills resolves superpowers in this order: --superpowers-from → $DSH_SUPERPOWERS_SOURCE → ~/.dsh/superpowers → the Claude Code plugin cache (legacy, warns). A clean HOME with no source and no installed copy fails with the clone command above instead of pretending success; the local role and sdd skills are copied either way.

Do not hand-edit $DSH_HOME/profiles/desktop/package.json or cordis.patch.yml: the Desktop profile is Electron-managed and the plugin manager owns those writes.

Verify

  1. In a new session, ask what skills do you have? — the superpowers catalog should be visible.
  2. In a repository on main, ask the agent to create a file — expect BLOCKED [guard-main].
  3. Create a worktree on a feature branch, ask for an edit under src/ — expect BLOCKED [require-plan] until .bounded or a plan for the branch exists.
  4. The model should load a role with skill({name:"role"}); /role dev is the user-facing command with the same file. Expect the five-line role summary.
  5. Prompt Let's make a react todo list — brainstorming must trigger before any code.
  6. In a project with .agents/skills, ask what skills do you have? — the six openspec-* skills must be listed.

The injected bootstrap starts with a marker:

<!-- DSH-HARNESS-BOOTSTRAP:<16-hex-hash> -->

After compaction the marker disappears from session.surface.nodes and the next step injects a fresh copy.

Tests

bash dsh/tests/run.sh

Pure Node; no DSH process is required. The guard tests create a throwaway git repository and exercise the real hooks/guard-main.sh and hooks/require-plan.sh through the adapter.

Layout

dsh/
  bundle/
    package.json          DSH bundle manifest (dsh.bundle.patch)
    cordis.patch.yml      inserts the dsh-harness row
    index.js              ctx.tools.guard + agent/pre-step + /role
    command-role.js       /role command glue
    lib/guards.js         DSH tool call -> claude-harness hook JSON
    lib/bootstrap.js      superpowers skill resolution, marker, dedupe
    lib/role.js           role layers and text (pure)
    dsh-tools.md          superpowers tool mapping
    hooks -> ../../hooks  local install: tested hooks are reused, not copied
    locale/{en,ru}.json
    icon.svg
  tests/
  install.sh
  skills/{role,sdd}/SKILL.md  model-invocable skills installed into ~/.dsh
  subagent-models.yml     opt-in overlay: model routes + maxDepth 2
  mcp.codegraph.yml       optional CodeGraph MCP overlay
  PORT.md                 design, mapping, risks, next phases
В корне проекта (не в dsh/):
  .agents/skills/openspec-*  скиллы OpenSpec, генерирует CLI

Configuration

The row is configurable from the profile patch; defaults target this repository layout:

- id: dsh-harness
  config:
    guards: true
    bootstrap: true
    roleCommand: true
    bootstrapSubagents: false
    hooksDir: ''             # empty -> bundle/hooks -> ../../hooks
    rolesDir: ''             # empty -> ~/.dsh/roles, legacy ~/.claude/roles, repo roles/
    projectRolesDir: ''      # empty -> <cwd>/.claude/roles
    roleNames: [dev, admin, analyst, qa]
    bootstrapSkillPath: ''   # empty -> ~/.dsh/skills, then legacy Claude Code paths
    toolMappingPath: ''      # empty -> bundle/dsh-tools.md
    bootstrapMaxBytes: 65536

Known limits

  • The guard adapter uses the repository's bash/Python hooks; if python3 is missing, the hooks fail open by design.
  • bundle/hooks is a symlink for local-directory installation. A published bundle needs a real copy of hooks/ (already listed in package.json files).
  • using-superpowers is read from ~/.dsh/skills after --skills. The install-time source is --superpowers-from, DSH_SUPERPOWERS_SOURCE, or ~/.dsh/superpowers; Claude Code locations are a legacy migration fallback and log one warning per process when used, so a partial Claude Code rollback does not break the bootstrap. Set bootstrapSkillPath or DSH_SUPERPOWERS_SKILL for another layout.
  • Roles resolve ~/.dsh/roles first; ~/.claude/roles and the repository roles/ are fallbacks. After --roles the runtime never needs ~/.claude.
  • Role loading is model-driven through the role skill; there is no automatic agent/pre-step injection. If the model skips the skill, use the /role command or ask it to load the role explicitly.
  • Model names in roles and superpowers (sonnet, haiku, opus) are not DSH models. The sdd skill uses two live routes from the opt-in dsh/subagent-models.yml overlay; without it every dispatch runs on the session model.
  • SDD on DSH is asynchronous, not a copy of Claude's Task. See the sdd skill and openspec/changes/dsh-sdd/.
  • OpenSpec-скиллы проект получает сам (openspec init --tools agents или --openspec); обвязка ставит их только в проект, не в ~/.dsh.