본문으로 건너뛰기
E

dsh-shared-handoff

eve1329/dsh-shared-handoff

공유 handoff 키트를 dsh로 포팅했습니다. handoff/task-id-bootstrap 스킬과 호스트 자동화로 기준 상태 주입, 턴별 Auto Log 스냅샷, task=<id> 라우팅, 이어서 실행할 때 재주입, clear-required 경고가 있는 압축 가드, 읽기 전용 하위 에이전트 처리를 제공합니다. Codex/Claude/pi 버전과 같은 .agents/state/에 기록해 한 저장소 내 에이전트 인계를 지원합니다.

설치

dsh plugin --profile web add github:eve1329/dsh-shared-handoff

README

shared-handoff-dsh

English | 中文

A DeepSeek Harness (dsh) skill plugin that ports the shared-handoff-kit's handoff workflow: it packages the handoff and task-id-bootstrap skills with zero dependencies and no build step, adapted for macOS, Linux, and Windows (including Windows 10 vs Windows 11 Python environment differences).

Skills

SkillWhat it doesRequires
handoffEvidence-driven session handoff: export/resume, interoperable across Codex, Claude, and dshNothing (pure instructions)
task-id-bootstrapRepo-local task state under .agents/state/tasks/<task-id>/, binding the current dsh session (DSH_SESSION_JSONL) to the taskPython 3.9+

Install

dsh plugin --profile web add shared-handoff-dsh

After restarting dsh web, both skills join the skill catalog and the model loads them through the skill tool.

For DSH session format v4, use 0.3.3 or later. This release fixes the format v4 message requires a producer-owned source kind failure during task-state injection and keeps injected context out of task-routing input.

Usage

Once installed there is no command to remember — the skills are triggered conversationally and the model loads the right SKILL.md itself.

task-id-bootstrap: open a task

Just say in a dsh chat (adjacent Chinese/English punctuation both work):

新开task-id=init-kmp,然后开个 init-kmp 分支

The model runs the bundled bootstrap script; success is proven by three lines:

Task state: .../.agents/state/tasks/init-kmp
Current task: init-kmp
Session binding: /Users/you/.dsh/sessions/.../session.jsonl.zstd

Progress then lives in .agents/state/tasks/init-kmp/process.md; say 继续,task-id=init-kmp later to resume. A directory without a session binding is only a partial result — the model must report it as such.

If Python (3.9+) is missing on first use, the model reports the gap and shows the install command for your platform, installing only after your explicit consent — never silently.

handoff: export / resume a session

When a thread gets long and you want a fresh one, say:

帮我做个 handoff

You get a paste-ready next-thread prompt (workspace / branch / done / verification status / next step). In the fresh session, open with:

继续上次 handoff

The model rebuilds context from state files instead of chat history. Phrases like 交接, 新开线程继续, 继续上次, and resume trigger it too.

The two skills cooperate

When a task-id is active in the same repo, handoff treats .agents/state/tasks/<task-id>/process.md as the canonical state instead of inventing a parallel one.

Cross-agent handoff

The state layout is identical to the Codex and Claude editions: a handoff exported from dsh can be resumed in Codex or Claude and vice versa (all three share the same session-tasks.json).

Automation (hook equivalents)

The three behaviors the original kit implemented through Codex/Claude hooks run automatically on the dsh host side via the harness event system — installed, they just work:

Original hookdsh equivalentBehavior
SessionStartfirst agent/pre-step (step 1)The active task's process.md / process.auto.md is injected as a baseline user message — say "继续" in a fresh session and the state is already there; the baseline ends with a reminder to run the handoff skill after completing a milestone, keeping the semantic state fresh
UserPromptSubmit (task routing)agent/pre-step message scanA task=<id> marker in the incoming user message re-binds the session and switches current-task (creating the task dir), then injects a switch notice for the new task
Continuationagent/pre-step message scanA short continuation prompt (继续 / 接着 / resume / 交接 …) re-injects the persisted state mid-session, labeled as a re-injection
Stopsession/event turn/endprocess.auto.md is refreshed after every turn (capturing the turn's last model output) and mirrored into an existing process.recent.md; the same turn also appends one summary line to the ## Auto Log section of process.md (newest last, capped at maxLogEntries, hand-written sections untouched)
PreCompact / PostCompactcompaction/start / compaction/summarySnapshots are written before and after compaction plus a context_guard.json marker; completed compactions increment auto_compact_count, and at compactThreshold (default 3) clear_required flips on and the next injected baseline carries a controlled-clear notice (hand off, start a fresh session)

Task resolution matches the original: the session's transcript binding in session-tasks.json first (dsh sessions align by their transcript path under $DSH_HOME/sessions), then the current-task pointer. Every write lands in the same .agents/state/ the Codex/Claude editions use.

Interop with the Codex and pi editions: context_guard.json is written read–merge–write with the Codex field contract (auto_compact_count, clear_required, threshold, last_*), and keys owned by other runtimes (pi_compact_count, last_pi_session_id, …) pass through untouched. The clear threshold check sums the pi and dsh counters together, so one repo alternated between runtimes still guards correctly.

To disable a piece, override the row in your profile patch:

- id: shared-handoff
  name: 'shared-handoff-dsh'
  config:
    injectBaseline: false   # no session-start injection
    autoSnapshot: false     # no per-turn snapshots
    autoLog: false          # no per-turn Auto Log lines in process.md
    compactionGuard: false  # no compaction guard
    handoffReminder: false  # no proactive-handoff reminder in the baseline
    maxLogChars: 300        # per-entry truncation for Auto Log lines
    maxLogEntries: 100      # Auto Log section length cap
    compactThreshold: 3     # compactions before a controlled clear is advised

process.auto.md and context_guard.json are host-owned metadata — the SKILL.md tells the model never to hand-write them; process.md stays model-maintained except for the host-appended ## Auto Log section at its end.

Design notes

  • archify-dsh pattern: cordis.patch.yml mounts an isolated @deepseek-ai/dsh-skill-filesystem instance (includeDefaultRoots: false
    • a unique providerName + bundledSkillDir pointing at the packaged skills/), leaving the stock filesystem provider untouched.
  • Host half (hook equivalents): zero external dependencies (Node builtins only) — listens to agent/pre-step and session/event for injection/snapshots/guard, see Automation above; listeners swallow their own errors, so a snapshot failure can never break the agent loop.
  • Subagents are read-only (single-writer rule): delegated children and forks (origin: "subagent" / positive delegationDepth) receive the baseline injection but never write state — no snapshots, no Auto Log entries, no bindings, no compaction-guard updates, and no task=<id> routing (a delegated prompt mentioning a task marker cannot hijack the repo's active task). Parallel children would otherwise clobber each other's snapshots and interleave the Auto Log; the parent session is the single writer, and children's findings flow back through their reports.
  • Session binding: dsh injects DSH_SESSION_JSONL (the current session transcript path) into the managed bash/PowerShell environment; the bootstrap script binds it via --transcript-path with zero script changes, writing into the same session-tasks.json the Codex/Claude editions use.
  • Cross-platform: the SKILL.md ships both bash and PowerShell command forms plus a Windows 10/11 Python detection matrix (py launcher, Store alias stub, winget availability); the lock module uses fcntl on POSIX and msvcrt on Windows, identical to the original.
  • Missing Python: never installed silently — report the gap, show the platform-specific command, install only after explicit consent; the handoff skill and the host-half automation work regardless (they need no Python).

Known limitations

  • Only the two platform-neutral skills were ported; claude-handoff (Claude Code specific) and the Codex/Claude hook runtimes stay with the original kit.
  • The auto snapshot records the turn's last model output verbatim (facts, not summaries) — semantic progress still lives in the model-maintained process.md; the ## Auto Log section gives it a per-turn, timestamped trail without replacing that curation.
  • Local path installs (dsh plugin add <path>) resolve as a link; publishing to npm is the sturdier sharing route.

License

MIT (inherited from shared-handoff-kit).

관련 플러그인