Teardown Deepwork
End a deepwork session — graceful per-teammate shutdown, archive state, and restore settings. The CLI auto-cleans team dirs at session end; no explicit TeamDelete call is needed. Applies to both mid-flight abort and post-HALT cleanup; the phase field in the archived state distinguishes the two.
- Use Glob to find all active instances:
Glob: ${CLAUDE_PROJECT_DIR:-$(pwd -P)}/.claude/deepwork/*/state.json
-
If no files are found, report that no deepwork session is running and stop.
-
Read each state file to extract:
session_id,goal,phase,team_name. -
If exactly one instance exists, proceed to tear it down. If multiple instances exist, show a summary:
| Instance ID | Goal | Phase | Team |
|---|---|---|---|
| <id> | <goal> | <phase> | <team> |
Then use AskUserQuestion to ask the user which instance to tear down.
-
Once the target instance is selected, note its directory path:
${CLAUDE_PROJECT_DIR:-$(pwd -P)}/.claude/deepwork/<id>/. -
Read the state file to get team_name. Then call
TaskListto get current task status for the summary report. -
Send a shutdown request to each known teammate BY NAME. Teammate names come from
state.json.role_definitions[](therolefield of each entry, lowercased, e.g."falsifier","coverage","mechanism","reframer","critic"). For each name, send oneSendMessage:SendMessage(to: "<teammate_name>", summary: "ending deepwork", message: "The user has ended the deepwork session. Please stop any in-progress work.")If
<!-- team_name is session-derived and @deprecated; discovery still matches because setup derives the same name. SendMessage(to: "*") broadcast is removed in 2.1.178+; send one message per recipient. TeamDelete no longer exists; the CLI auto-cleans team dirs at session end. -->role_definitionsis empty or null (session was torn down before any teammates were spawned), skip messaging entirely and proceed to step 8.Note:
state.json.team_nameis read for the summary report (steps 3, 6) but is not used to route teardown — routing is by individual teammate name. -
Archive runtime state via the canonical writer, then clean up transient files:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/state-transition.sh" \
--state-file "${CLAUDE_PROJECT_DIR:-$(pwd -P)}/.claude/deepwork/<id>/state.json" archive_state
rm -f "${CLAUDE_PROJECT_DIR:-$(pwd -P)}/.claude/deepwork/<id>/pending-change.json"
rm -f "${CLAUDE_PROJECT_DIR:-$(pwd -P)}/.claude/deepwork/<id>/.idle-retry.*"
archive_state emits a state_archived event, renames state.json → state.archived.json, and renames events.jsonl → events.archived.jsonl. The rename (not delete) of state.json stops all active-session globs (${CLAUDE_PROJECT_DIR:-$(pwd -P)}/.claude/deepwork/*/state.json) from picking up this instance — so setup-deepwork.sh, session-context.sh, deepwork-status, deepwork-bar, deepwork-guardrail, and this skill all correctly skip it — while preserving the full structured record (bar verdicts, empirical_unknowns, user_feedback, guardrails, role_definitions, anchors) for programmatic query across past deepwork sessions. The archived filename is neutral because this skill runs on mid-flight abort, post-APPROVE cleanup, and post-HALT cleanup; the phase field inside the archived state distinguishes them.
Do NOT delete the artifacts — they capture the why behind the session (what was explored, what failed, what was rejected) and remain useful after teardown for historical analysis and future decisions:
log.md— narrative historyproposals/— all versions of the proposal (audit trail)prompt.md— original user promptfindings.*.md,coverage.*.md,mechanism.*.md,reframe.*.md,empirical_results.*.md,critique.*.md— teammate outputsgate-list-*.md,anchors.md— bar/scope artifactsincidents.jsonl— structured record of runtime failures (SubagentStop non-zero, PermissionDenied)
- Check if any other instances remain (informational only — the teardown script in step 10 performs the same check internally):
ls "${CLAUDE_PROJECT_DIR:-$(pwd -P)}/.claude/deepwork"/*/state.json 2>/dev/null
-
Restore settings via the centralized teardown script. Pass the instance ID so only this instance's hooks are removed (sibling-instance hooks are preserved). Falls back to
.deepwork-backupif jq fails. No-ops if other active instances remain:bash "${CLAUDE_PLUGIN_ROOT}/scripts/settings-teardown.sh" "${CLAUDE_PROJECT_DIR:-$PWD}" "${INSTANCE_ID}"INSTANCE_IDis the 8-hex identifier read from the archived state.json (.instance_idfield) in a prior step. The same script is invoked byhooks/approve-archive.shon APPROVE, so both teardown paths use identical restore semantics. -
Report to the user:
- Goal that was being worked on
- Phase at time of teardown (the phase field in archived state is preserved as-is —
donefor post-APPROVE plan-mode cleanup,haltfor post-HALT execute-mode cleanup, or whichever phase was live for mid-flight abort) - Task status summary from TaskList (completed / in_progress / pending)
- Confirm teardown; note that the full instance is preserved at
${CLAUDE_PROJECT_DIR:-$(pwd -P)}/.claude/deepwork/<id>/includingstate.archived.json(structured record),log.md,proposals/, and all teammate artifacts — queryable viajqacross past sessions