184 lines
8.0 KiB
Markdown
184 lines
8.0 KiB
Markdown
# 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](PORT.md) for the design, mapping table, and
|
||
risks.
|
||
|
||
## Quick start
|
||
|
||
```bash
|
||
# Static check (offline; reports the configured pin and the current source)
|
||
bash dsh/install.sh --check
|
||
|
||
# Superpowers source. The default is a pinned clone: --skills clones or
|
||
# updates ~/.dsh/superpowers at $DSH_SUPERPOWERS_REF (default v7.0.1, fetched
|
||
# from $DSH_SUPERPOWERS_REPO), then runs sync + verify and copies the adapted
|
||
# skills. Offline it reuses the clone only when it is already on the ref.
|
||
bash dsh/install.sh --skills
|
||
# ...or sync a checkout directly (no network, no pin enforcement):
|
||
bash dsh/install.sh --skills --superpowers-from /path/to/superpowers
|
||
# ...or export DSH_SUPERPOWERS_SOURCE=/path/to/superpowers
|
||
|
||
# Global instructions, local role skill, and roles
|
||
# (run from a terminal; these write outside the session workspace)
|
||
bash dsh/install.sh --global
|
||
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` → the pinned clone `~/.dsh/superpowers` at
|
||
`$DSH_SUPERPOWERS_REF` (default `v7.0.1`, cloned or updated from
|
||
`$DSH_SUPERPOWERS_REPO`; offline it is reused only when already on the ref) →
|
||
the Claude Code plugin cache (legacy, warns). Explicit sources are synced in
|
||
place with no network. Every sync runs `dsh/sync/sync-from-upstream.mjs` (DSH
|
||
adaptations) and `dsh/sync/verify-skills.mjs`; a tree that fails verification
|
||
or holds zero skills is never installed. Legacy sources are copied raw. A
|
||
clean HOME with no source and no clone fails with the clone command 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:
|
||
|
||
```text
|
||
<!-- 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
|
||
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
|
||
|
||
```text
|
||
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
|
||
```
|
||
|
||
```text
|
||
В корне проекта (не в dsh/):
|
||
.agents/skills/openspec-* скиллы OpenSpec, генерирует CLI
|
||
```
|
||
|
||
## Configuration
|
||
|
||
The row is configurable from the profile patch; defaults target this
|
||
repository layout:
|
||
|
||
```yaml
|
||
- 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
|
||
the pinned clone `~/.dsh/superpowers` (`DSH_SUPERPOWERS_REF`, default
|
||
`v7.0.1`); 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`.
|