@drunkcoding/agents-and-skills 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,70 @@
1
+ ---
2
+ description: Inspect and clean up team-superpower team state — orphaned configs, task lists, tmux sessions left by a dead lead.
3
+ argument-hint: [slug] | --all
4
+ ---
5
+
6
+ Inspect and (with owner confirmation) remove orphaned team-superpower state from `~/.claude/teams/superpower-*/` and `~/.claude/tasks/superpower-*/`. Preserves project-side artefacts (`docs/superpowers/{specs,plans,reviews}`) — only platform-side state is removed.
7
+
8
+ Argument:
9
+
10
+ $ARGUMENTS
11
+
12
+ ## What "orphaned" means
13
+
14
+ A team is orphaned when:
15
+
16
+ - Its team config lives at `~/.claude/teams/superpower-<slug>/` but the lead process is dead, so no Claude Code session can talk to it.
17
+ - The agent-teams runtime can't reuse it because the lead-for-a-team is fixed for that team's lifetime (per [docs](https://code.claude.com/docs/en/agent-teams)).
18
+ - The canonical "ask the lead to clean up" path is unavailable because there is no lead.
19
+
20
+ This command is the manual fallback for that case. **If a live lead exists, do not use this command** — message the lead and ask it to "clean up the team" via the native primitive instead.
21
+
22
+ ## Procedure
23
+
24
+ Run the helper script `${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh` to do the work. It accepts a subcommand and treats every destructive operation as opt-in (`--force`).
25
+
26
+ ### Step 1 — Decide scope
27
+
28
+ - If `$ARGUMENTS` is empty: run `bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh scan` and show the output to the owner. Ask which slug to clean (or `--all`).
29
+ - If `$ARGUMENTS` is `--all`: enumerate every slug from the scan and process each in turn.
30
+ - Otherwise treat `$ARGUMENTS` as the slug.
31
+
32
+ ### Step 2 — Inspect
33
+
34
+ For the chosen slug, run `bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh scan <slug>`. Quote the output verbatim to the owner. Pay attention to the `liveness` line:
35
+
36
+ | `liveness` | What it means | What to do |
37
+ |---|---|---|
38
+ | `LIKELY ALIVE` | Heartbeat is < 10min old | **Stop.** Tell the owner the previous lead may still be running. Ask them to verify nothing is in flight before forcing cleanup. |
39
+ | `stale` or `unknown` | Heartbeat old or absent | Proceed to step 3. |
40
+
41
+ ### Step 3 — Dry-run
42
+
43
+ Run `bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh cleanup <slug>` (no `--force`). Exit code 1 with a "would remove" list is expected. Quote the list to the owner.
44
+
45
+ If exit code is 4, there is nothing to clean — report and exit.
46
+
47
+ ### Step 4 — Confirm and apply
48
+
49
+ Ask the owner to confirm the dry-run list. On confirmation, run `bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh cleanup <slug> --force`.
50
+
51
+ - Exit code 0: report success and show the appended `## Cleanup` block from the checkpoint.
52
+ - Exit code 3 (heartbeat refusal): the owner confirmed nothing is in flight, but the heartbeat is fresh. Re-run with `--force --ignore-heartbeat` only after the owner re-confirms in writing (in the chat) that the previous lead is dead.
53
+
54
+ ### Step 5 — Verify
55
+
56
+ Re-run `bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh scan <slug>` and confirm `team_config_state: absent` and `task_list_state: absent`.
57
+
58
+ ## What this command will NOT do
59
+
60
+ - It will not touch any project-side files except to append a `## Cleanup` block to the checkpoint markdown.
61
+ - It will not delete the design doc, plan, or review report — those are the durable record of the work and are kept regardless.
62
+ - It will not run when there is a live lead. The heartbeat refusal is the safety check.
63
+ - It will not iterate `--all` without per-slug owner confirmation when any slug shows `LIKELY ALIVE`.
64
+
65
+ ## When to use
66
+
67
+ - After `/resume` left a team config behind that no current session can talk to.
68
+ - After a crash or kill of the lead mid-feature.
69
+ - Before `/team-feature` if the preflight scan there reports orphaned state.
70
+ - Routinely after an in-flight feature is abandoned.
@@ -0,0 +1,111 @@
1
+ ---
2
+ description: Resume a team-superpower workflow from a committed checkpoint file in docs/superpowers/sessions/. Handles stale team state from a dead lead.
3
+ argument-hint: <checkpoint-filename>
4
+ ---
5
+
6
+ You are the **lead** resuming an in-flight team-superpower workflow. `/resume` does not restore in-process teammates, so you reconstruct the team from the committed checkpoint and clean up any orphaned platform-side state along the way.
7
+
8
+ Checkpoint argument:
9
+
10
+ $ARGUMENTS
11
+
12
+ ## Resume protocol (strict order)
13
+
14
+ ### Step 1 — Locate the checkpoint
15
+
16
+ If `$ARGUMENTS` is a bare filename, prefix `docs/superpowers/sessions/`. Read it. If it doesn't exist or fails to parse against the checkpoint format from `/team-feature`, halt and ask the owner to point you at the correct file.
17
+
18
+ Extract `<slug>` from the checkpoint filename (`YYYY-MM-DD-<slug>.md`) and from the `**Team:**` line if present (`superpower-<slug>`). They must match.
19
+
20
+ If the checkpoint has a `## Closing` block with `cleanup: complete`, halt: the feature already finished. Tell the owner.
21
+
22
+ ### Step 2 — Verify environment
23
+
24
+ Same prechecks as `/team-feature`:
25
+ - Superpowers plugin installed
26
+ - Claude Code ≥ 2.1.32
27
+ - `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`
28
+
29
+ Halt on any failure.
30
+
31
+ ### Step 3 — Preflight scan
32
+
33
+ Run:
34
+
35
+ ```bash
36
+ bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh scan <slug>
37
+ ```
38
+
39
+ Decide based on the output:
40
+
41
+ | Scan result | Interpretation | Action |
42
+ |---|---|---|
43
+ | All states `absent`, no heartbeat | Lead exited cleanly without auto-cleanup, or platform-side state was already wiped. | Proceed to Step 4 (fresh respawn). |
44
+ | Team config `present`, heartbeat older than 10 min (`liveness: stale`) | Previous lead is dead, platform state lingers. | Run `bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh cleanup <slug> --force`. The heartbeat check will allow it because it's stale. Then proceed to Step 4. |
45
+ | Team config `present`, heartbeat fresh (`liveness: LIKELY ALIVE`) | A lead may still be running. | **Halt.** Tell the owner you detected what looks like a live lead. Ask them to verify nothing is in flight before re-running. If the owner confirms the previous lead is dead, instruct them to run `/team-cleanup <slug>` (which will require `--ignore-heartbeat`) and then re-run this command. |
46
+ | Team config `absent` but task_list or tmux still present | Partial cleanup from a previous attempt. | Run `bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh cleanup <slug> --force`. Proceed. |
47
+
48
+ After any cleanup, re-run the scan and confirm `team_config_state: absent` before continuing.
49
+
50
+ ### Step 4 — Identify resume point
51
+
52
+ The next pending phase is the first unchecked box in the checkpoint's `## Phases` section. Open escalations in the checkpoint take precedence — resolve them before resuming.
53
+
54
+ Read all the artefacts the next phase depends on:
55
+ - If next phase is `worktree` or later: design doc (path is in the checkpoint).
56
+ - If next phase is `implementation` or later: plan + `plan_approved_at` timestamp.
57
+ - If next phase is `finish`: review report.
58
+
59
+ ### Step 5 — Reconstruct context
60
+
61
+ - `cd` into the worktree path recorded in the checkpoint. If it no longer exists, halt and escalate via the §7 template — the owner needs to restore or rebase the worktree before resume can continue.
62
+ - Recreate the team with the same name (`superpower-<slug>`).
63
+ - Touch `docs/superpowers/sessions/<slug>.heartbeat` and update it at every phase boundary (same protocol as `/team-feature`).
64
+
65
+ ### Step 6 — Respawn only the teammates needed
66
+
67
+ For the next phase, spawn the relevant role(s) using the agent definitions shipped with this plugin. Do **not** respawn teammates whose phase is complete unless that phase needs them again later (e.g. reviewer is reused in phase 6).
68
+
69
+ Hand each respawned teammate:
70
+ - the slug
71
+ - the relevant artefact paths
72
+ - a note that this is a resume; they should pick up at the next pending task
73
+
74
+ ### Step 7 — Re-import the shared task list
75
+
76
+ If resuming inside phase 4 (implementation):
77
+
78
+ 1. Read the plan.
79
+ 2. Recreate any `impl:` tasks that were pending or in-progress at checkpoint time. The `TaskCreated` hook enforces the prefix; the `TaskCompleted` hook requires `plan_approved_at` metadata — carry the timestamp forward from the checkpoint.
80
+ 3. Skip `impl:` tasks that the checkpoint records as `complete` and whose corresponding commits exist on the worktree branch (verify with `git log --oneline -- <task-files>`). If a checkpoint marks a task complete but the commits are missing, halt — that's tampered or corrupted state.
81
+
82
+ ### Step 8 — Append a resume log entry
83
+
84
+ Append to the checkpoint (atomic write — tmp + rename) and commit:
85
+
86
+ ```markdown
87
+ ## Resume log
88
+ - resumed at: <ISO datetime>
89
+ - next phase: <phase name>
90
+ - respawned: <comma-separated role list>
91
+ - preflight cleanup: <yes|no — what was cleaned>
92
+ ```
93
+
94
+ ### Step 9 — Resume the phase chain
95
+
96
+ Continue per the same rules as `/team-feature`:
97
+ - four allowed owner touchpoints, nothing else without §7 template
98
+ - checkpoint after every phase boundary, atomic writes
99
+ - heartbeat touched at every phase boundary
100
+ - automatic cleanup after `FINISH_DONE`
101
+
102
+ ## Hard rules
103
+
104
+ - **Never** restart a completed phase. If a phase is checked in the checkpoint and the corresponding artefact + commits exist, trust it.
105
+ - **Never** assume teammates are still alive. They are not. Always respawn from the role definitions.
106
+ - **Never** silently change a previously approved design or plan. If the resumed state contradicts them, halt and escalate.
107
+ - **Never** skip Step 3 preflight. Stale team configs cause runtime errors and silently re-use the wrong session IDs.
108
+ - **Never** force-cleanup state with a fresh heartbeat unless the owner has confirmed in writing the previous lead is dead.
109
+ - **Never** skip the resume-log commit. It is the audit trail that proves the resume happened.
110
+
111
+ If anything in the checkpoint looks tampered with or inconsistent (e.g. plan marked approved but no plan file exists, completed task with missing commits), halt and escalate to the owner with the §7 template. Do not paper over.
@@ -0,0 +1,190 @@
1
+ ---
2
+ description: Launch a Superpowers-compliant agent team to deliver a feature end-to-end with at most 4 owner touchpoints, with automatic team cleanup after the finish phase.
3
+ argument-hint: <one-line feature idea>
4
+ ---
5
+
6
+ You are the **lead** of an agent team implementing the Superpowers methodology across multiple parallel Claude Code sessions.
7
+
8
+ Owner's feature request:
9
+
10
+ $ARGUMENTS
11
+
12
+ ## Your job
13
+
14
+ You are a **conductor**, not an implementer. Spawn teammates and coordinate them through the canonical Superpowers skill chain. Do not run skills yourself — delegate every skill to the correct teammate. The team-superpower agent definitions (`designer`, `planner`, `implementer`, `reviewer`) shipped with this plugin tell each teammate exactly which Superpowers skill to run.
15
+
16
+ ## Required prechecks (run these first, in order)
17
+
18
+ 1. Confirm Superpowers plugin is installed: `claude plugin list | grep superpowers`. If missing, **halt** and instruct the owner: `/plugin install superpowers@claude-plugins-official`.
19
+ 2. Confirm Claude Code version is `2.1.32` or later: `claude --version`. If older, halt.
20
+ 3. Confirm `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` is set in the environment. If not, halt and instruct the owner to add it to `~/.claude/settings.json` under `env`.
21
+ 4. Generate a kebab-case `<slug>` from the owner's request. Use it in every artifact filename for the rest of the run. The team you create MUST be named exactly `superpower-<slug>` — every cleanup and resume primitive depends on that convention.
22
+ 5. Create directories if missing: `docs/superpowers/{sessions,specs,plans,reviews}`.
23
+ 6. Seed `docs/superpowers/ESCALATION.md` from `${CLAUDE_PLUGIN_ROOT}/assets/ESCALATION.md` if it does not already exist. Seed `docs/superpowers/README.md` from `${CLAUDE_PLUGIN_ROOT}/assets/SESSION_README.md` if missing. Commit any seeded files.
24
+
25
+ ## Preflight — detect stale or orphaned state
26
+
27
+ Before writing any checkpoint or spawning any teammate, run the helper:
28
+
29
+ ```bash
30
+ bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh scan
31
+ ```
32
+
33
+ Then run a targeted scan for this run's slug:
34
+
35
+ ```bash
36
+ bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh scan <slug>
37
+ ```
38
+
39
+ Interpret the output:
40
+
41
+ | Outcome | What to do |
42
+ |---|---|
43
+ | `No team-superpower teams found` and no checkpoint for `<slug>` | Clean slate. Proceed. |
44
+ | Team config exists for `<slug>` and `liveness: LIKELY ALIVE` | Halt. Tell the owner there's already an in-flight run for this slug (heartbeat fresh). Offer: wait for it to finish, or `/team-cleanup <slug>` after owner confirms the previous lead is dead. |
45
+ | Team config exists for `<slug>` and `liveness: stale` or `unknown` | Tell the owner: "Stale state from a previous run detected." Offer two paths: **(a) Resume** via `/team-feature-resume YYYY-MM-DD-<slug>.md`, or **(b) Cleanup and restart** via `/team-cleanup <slug>` then re-run `/team-feature`. Halt — do NOT auto-decide. |
46
+ | Other slugs have configs but not this one | Note in the checkpoint that other in-flight runs exist; proceed with this slug. |
47
+
48
+ Same-session check: if the current Claude Code session already manages an agent team (the runtime enforces "one team per session"), halt. The owner must finish or `/team-cleanup` the current team before launching a new feature.
49
+
50
+ ## Initial checkpoint and heartbeat
51
+
52
+ After preflight clears:
53
+
54
+ 1. Write the initial checkpoint `docs/superpowers/sessions/YYYY-MM-DD-<slug>.md` per the format in the **Checkpointing** section and commit it.
55
+ 2. `touch docs/superpowers/sessions/<slug>.heartbeat` and commit (or leave uncommitted — the file is intentionally ephemeral; either is fine). **Touch this heartbeat at every phase boundary** and any time you remain active for more than ~10 minutes inside a phase. The cleanup script uses its mtime to decide whether a future session is allowed to wipe state.
56
+ 3. Write checkpoint updates atomically: write to `<file>.tmp` then `mv -f <file>.tmp <file>`. Half-written checkpoints corrupt recovery.
57
+
58
+ ## Phase chain (strict order — no skipping, no inlining)
59
+
60
+ 1. **Brainstorming (designer).** Spawn the `designer` teammate. Hand it `<slug>` and the owner's request. Wait for `DESIGN_APPROVED <path>` in your mailbox. If the designer asks a clarifying question, answer from project context if unambiguous; otherwise batch with any open questions and use the §7 escalation template to the owner. Checkpoint: `phase: brainstorming, status: complete`. Touch heartbeat.
61
+ 2. **Worktree + plan (planner).** Spawn the `planner` teammate. Hand it `<slug>` and the design doc path. Wait for `WORKTREE_READY` then `PLAN_READY <path>`. Route the plan to the owner for approval (third owner touchpoint). On approval, stamp `plan_approved_at: <ISO datetime>` into the metadata of every `impl:` task you will create — the `TaskCompleted` hook checks for it. Checkpoint: `phase: plan, status: approved`. Touch heartbeat.
62
+ 3. **Implementation (implementers, 1–3 in parallel).** Read the approved plan. Create one shared-task-list entry per plan task with title `impl:<short-name>`, body = full task text including verification, and dependency + file-scope metadata from the plan. Spawn one `implementer` teammate. If the plan contains clearly parallel tasks with disjoint file scopes, spawn a second (and up to a third). Implementers self-claim. **You must verify no two active implementer tasks overlap in file scope** — if a conflict appears, serialize by holding the second task. Watch for `impl:` task completions; on critical issues from a later review, file new `impl:` tasks here too. Checkpoint after each task transition: `phase: implementation, tasks_complete: M/N`. Touch heartbeat at every transition.
63
+ 4. **Review (reviewer).** Once all `impl:` tasks complete, file a `review:` task and spawn the `reviewer` teammate. Wait for `REVIEW_PASSED <path>`. If critical issues come back instead, the reviewer report names the responsible implementer and task — file fresh `impl:` tasks and loop to phase 3. Checkpoint: `phase: review, status: pass | critical_issues_returned`. Touch heartbeat.
64
+ 5. **Finish (reviewer).** Same reviewer runs `finishing-a-development-branch`. The owner makes the merge / PR / keep / discard decision (fourth and last owner touchpoint). On `FINISH_DONE <decision> <ref>`, checkpoint: `phase: finish, status: <merged|pr_opened|kept|discarded>`. Touch heartbeat.
65
+
66
+ ## Automatic cleanup (runs after `FINISH_DONE`)
67
+
68
+ The instant phase 5 records `FINISH_DONE`, run cleanup **before idling**. Do this in order, halting and escalating to the owner if any step fails:
69
+
70
+ ### Step A — Verify safety preconditions
71
+
72
+ Confirm all of the following from the checkpoint and the task list:
73
+
74
+ - Every phase from `brainstorming` through `finish` is checked complete.
75
+ - The shared task list has zero `in_progress` tasks. Every `impl:` and `review:` task is `completed`.
76
+ - Phase 5 returned a recognised decision: `merged`, `pr_opened`, `kept`, or `discarded`.
77
+ - The expected git commits exist on the worktree branch. Run `git log --oneline -20` and confirm:
78
+ - A design doc commit under `docs/superpowers/specs/`
79
+ - A plan commit under `docs/superpowers/plans/`
80
+ - One or more implementation commits (TDD pairs of test + code on the same files; the test commit precedes the code commit per the `test-driven-development` skill)
81
+ - A review report commit under `docs/superpowers/reviews/`
82
+ - If the finish decision is `merged` or `pr_opened`, the corresponding merge / PR-prep commit
83
+
84
+ If any of these is missing, **halt cleanup**, escalate with the §7 template, and instruct the owner to inspect manually. **Do not run cleanup on a half-finished feature.**
85
+
86
+ ### Step B — Shut down teammates gracefully
87
+
88
+ For each live teammate (`designer`, `planner`, every `implementer`, `reviewer`):
89
+
90
+ 1. Send a shutdown request via the canonical agent-teams primitive ("Ask the X teammate to shut down").
91
+ 2. Wait for graceful exit.
92
+ 3. If a teammate rejects shutdown, surface the rejection reason to the owner via the §7 template and halt cleanup.
93
+
94
+ The agent-teams runtime refuses team cleanup while any teammate is alive — this step is non-optional.
95
+
96
+ ### Step C — Run the canonical team cleanup
97
+
98
+ Ask the team-teams runtime to clean up the team (the native lead primitive: phrase it as a natural-language "clean up the team" instruction to yourself). Verify by running:
99
+
100
+ ```bash
101
+ bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh scan <slug>
102
+ ```
103
+
104
+ Expected after the runtime cleanup:
105
+
106
+ - `team_config_state: absent`
107
+ - `task_list_state: absent`
108
+ - `tmux_state: absent` (or `tmux` not installed)
109
+
110
+ ### Step D — Manual sweep (only if Step C left residue)
111
+
112
+ If the scan after Step C still shows any `present` lines, run:
113
+
114
+ ```bash
115
+ bash ${CLAUDE_PLUGIN_ROOT}/scripts/team-state.sh cleanup <slug> --force
116
+ ```
117
+
118
+ The heartbeat refusal check applies. If it fires, you are still touching the heartbeat (or another lead is alive) — investigate before forcing. If the only reason is your own fresh heartbeat from this session, pass `--ignore-heartbeat` (you know the lead is you and you are about to exit).
119
+
120
+ ### Step E — Final checkpoint commit
121
+
122
+ Append a closing block to the checkpoint:
123
+
124
+ ```markdown
125
+ ## Closing
126
+ - finished at: <ISO datetime>
127
+ - decision: <merged|pr_opened|kept|discarded>
128
+ - cleanup: complete
129
+ ```
130
+
131
+ Remove the `<slug>.heartbeat` file. Commit the checkpoint. Confirm to the owner: "Team cleaned up. Feature complete."
132
+
133
+ ### Step F — If anything failed
134
+
135
+ Tell the owner exactly which step failed, include the script output verbatim, and instruct them to run `/team-cleanup <slug>` once they have confirmed nothing else is running. Do **not** retry cleanup loops automatically — the safety check is the heartbeat, and you cannot meaningfully refresh it from outside the lead process.
136
+
137
+ ## Owner touchpoints (the ONLY allowed pings to the owner)
138
+
139
+ 1. Brainstorming clarifying questions — batched per phase by you, never raw-passed.
140
+ 2. Design sign-off (the brainstorming skill's built-in step).
141
+ 3. Plan approval before phase 3 starts.
142
+ 4. Finish-branch decision in phase 6.
143
+
144
+ **Anything else requires the §7 escalation template** from `docs/superpowers/ESCALATION.md`. Refuse to ping the owner without it. Cleanup runs without owner involvement when Step A passes.
145
+
146
+ ## Checkpointing
147
+
148
+ After every phase boundary, write `docs/superpowers/sessions/YYYY-MM-DD-<slug>.md` atomically (tmp + rename) per this format and commit it. This is the only way the workflow survives a `/resume` failure:
149
+
150
+ ```markdown
151
+ # Session: <slug>
152
+ **Started:** <ISO datetime>
153
+ **Last update:** <ISO datetime>
154
+ **Team:** superpower-<slug>
155
+ **Worktree:** <path>
156
+
157
+ ## Phases
158
+ - [x] brainstorming → docs/superpowers/specs/YYYY-MM-DD-<slug>-design.md
159
+ - [x] worktree → <branch>
160
+ - [x] plan → docs/superpowers/plans/YYYY-MM-DD-<slug>-plan.md (approved <datetime>)
161
+ - [ ] implementation (M/N tasks complete)
162
+ - [ ] review
163
+ - [ ] finish
164
+
165
+ ## Teammates
166
+ - designer (agent-id: ...) — idle
167
+ - planner (agent-id: ...) — idle
168
+ - implementer-1 (agent-id: ...) — active on task impl:<name>
169
+ - reviewer (agent-id: ...) — idle
170
+
171
+ ## Open escalations
172
+ - (none) | <escalation-template entries>
173
+
174
+ ## Resume protocol
175
+ 1. Owner runs /team-feature-resume with this filename.
176
+ 2. Lead respawns teammates using same role definitions.
177
+ 3. Lead reads this checkpoint, identifies next pending task, resumes.
178
+ ```
179
+
180
+ ## Hard rules
181
+
182
+ - **Never** run a Superpowers skill yourself. Always delegate to the correct teammate.
183
+ - **Never** modify, replace, or skip a Superpowers skill. Consume them as-installed.
184
+ - **Never** let an implementer write code before the plan is approved. The `TaskCompleted` hook will reject completions without `plan_approved_at`; do not let the situation arise upstream.
185
+ - **Never** let an `impl:` task be marked complete without TDD and the two-stage review from `subagent-driven-development`. The hook is a backstop, not a primary control.
186
+ - **Never** ping the owner without the §7 template, except for the four allowed touchpoints listed above.
187
+ - **Never** skip the automatic cleanup block after `FINISH_DONE`. The hooks have no `TeamShutdown` event; the lead is the only thing that knows when to clean up. If cleanup is skipped, the next `/team-feature` for the same slug will trip the preflight and refuse to start.
188
+ - **Never** force cleanup while the heartbeat is fresh and you didn't write it. That's the signal that another lead is alive.
189
+
190
+ Begin with the prechecks, then preflight, then spawn `designer`.
@@ -0,0 +1,28 @@
1
+ {
2
+ "hooks": {
3
+ "TeammateIdle": [
4
+ {
5
+ "matcher": "*",
6
+ "hooks": [
7
+ { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/teammate-idle.sh" }
8
+ ]
9
+ }
10
+ ],
11
+ "TaskCreated": [
12
+ {
13
+ "matcher": "*",
14
+ "hooks": [
15
+ { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/task-created.sh" }
16
+ ]
17
+ }
18
+ ],
19
+ "TaskCompleted": [
20
+ {
21
+ "matcher": "*",
22
+ "hooks": [
23
+ { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/task-completed.sh" }
24
+ ]
25
+ }
26
+ ]
27
+ }
28
+ }
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env bash
2
+ # TaskCompleted hook — gate implementation completions on plan approval and
3
+ # validate any embedded escalation entries.
4
+ #
5
+ # Accepts a JSON payload on stdin with at minimum:
6
+ # - task.title: string
7
+ # - task.metadata.plan_approved_at: string (ISO datetime), required for impl: tasks
8
+ # - task.metadata.blocked_questions: array of strings (optional)
9
+ #
10
+ # Rules:
11
+ # - impl: task -> plan_approved_at MUST be present (exit 2 NO_PLAN_APPROVAL)
12
+ # - any blocked_questions entry -> must mention every escalation field
13
+ # (Phase, Context, Options, Recommendation, Need from you)
14
+ # otherwise exit 2 BAD_ESCALATION: missing field(s) <list>
15
+
16
+ set -euo pipefail
17
+
18
+ LOG_DIR="${CLAUDE_PROJECT_DIR:-$PWD}/.claude/hooks"
19
+ LOG_FILE="$LOG_DIR/log.jsonl"
20
+ mkdir -p "$LOG_DIR"
21
+
22
+ ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
23
+
24
+ payload="$(cat || true)"
25
+
26
+ if [ -z "$payload" ]; then
27
+ printf '{"ts":"%s","hook":"task-completed","skipped":"empty payload"}\n' "$ts" >> "$LOG_FILE"
28
+ exit 0
29
+ fi
30
+
31
+ if ! command -v jq >/dev/null 2>&1; then
32
+ printf '{"ts":"%s","hook":"task-completed","skipped":"jq not installed"}\n' "$ts" >> "$LOG_FILE"
33
+ exit 0
34
+ fi
35
+
36
+ title="$(printf '%s' "$payload" | jq -r '.task.title // .title // ""' 2>/dev/null || echo "")"
37
+ plan_approved_at="$(printf '%s' "$payload" | jq -r '.task.metadata.plan_approved_at // .metadata.plan_approved_at // ""' 2>/dev/null || echo "")"
38
+
39
+ printf '{"ts":"%s","hook":"task-completed","title":%s,"plan_approved_at":%s}\n' \
40
+ "$ts" \
41
+ "$(printf '%s' "$title" | jq -Rs .)" \
42
+ "$(printf '%s' "$plan_approved_at" | jq -Rs .)" \
43
+ >> "$LOG_FILE"
44
+
45
+ case "$title" in
46
+ impl:*)
47
+ if [ -z "$plan_approved_at" ]; then
48
+ echo "NO_PLAN_APPROVAL: impl: tasks require metadata.plan_approved_at before completion (title: $title)" >&2
49
+ exit 2
50
+ fi
51
+ ;;
52
+ esac
53
+
54
+ # Validate escalation entries if present.
55
+ required_fields=("Phase" "Context" "Options" "Recommendation" "Need from you")
56
+ missing_any=""
57
+ entries="$(printf '%s' "$payload" | jq -c '(.task.metadata.blocked_questions // .metadata.blocked_questions // [])[]?' 2>/dev/null || true)"
58
+
59
+ if [ -n "$entries" ]; then
60
+ while IFS= read -r entry; do
61
+ [ -z "$entry" ] && continue
62
+ raw="$(printf '%s' "$entry" | jq -r '.' 2>/dev/null || printf '%s' "$entry")"
63
+ missing=""
64
+ for field in "${required_fields[@]}"; do
65
+ if ! printf '%s' "$raw" | grep -qE "(^|[^A-Za-z])${field}[[:space:]]*:"; then
66
+ if [ -z "$missing" ]; then
67
+ missing="$field"
68
+ else
69
+ missing="$missing, $field"
70
+ fi
71
+ fi
72
+ done
73
+ if [ -n "$missing" ]; then
74
+ if [ -z "$missing_any" ]; then
75
+ missing_any="$missing"
76
+ else
77
+ missing_any="$missing_any | $missing"
78
+ fi
79
+ fi
80
+ done <<< "$entries"
81
+ fi
82
+
83
+ if [ -n "$missing_any" ]; then
84
+ echo "BAD_ESCALATION: missing field(s) $missing_any" >&2
85
+ exit 2
86
+ fi
87
+
88
+ exit 0
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env bash
2
+ # TaskCreated hook — enforce title prefix on shared task list entries.
3
+ #
4
+ # Accepts a JSON payload on stdin. Required field:
5
+ # - task.title: string
6
+ #
7
+ # Title MUST start with one of: impl:, review:, meta:, block:
8
+ # Otherwise exit 2 with stderr BAD_PREFIX so the team-team runtime refuses
9
+ # the task and surfaces the failure to the lead.
10
+
11
+ set -euo pipefail
12
+
13
+ LOG_DIR="${CLAUDE_PROJECT_DIR:-$PWD}/.claude/hooks"
14
+ LOG_FILE="$LOG_DIR/log.jsonl"
15
+ mkdir -p "$LOG_DIR"
16
+
17
+ ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
18
+
19
+ payload="$(cat || true)"
20
+
21
+ if [ -z "$payload" ]; then
22
+ printf '{"ts":"%s","hook":"task-created","skipped":"empty payload"}\n' "$ts" >> "$LOG_FILE"
23
+ exit 0
24
+ fi
25
+
26
+ if ! command -v jq >/dev/null 2>&1; then
27
+ printf '{"ts":"%s","hook":"task-created","skipped":"jq not installed"}\n' "$ts" >> "$LOG_FILE"
28
+ exit 0
29
+ fi
30
+
31
+ title="$(printf '%s' "$payload" | jq -r '.task.title // .title // ""' 2>/dev/null || echo "")"
32
+
33
+ printf '{"ts":"%s","hook":"task-created","title":%s}\n' "$ts" "$(printf '%s' "$title" | jq -Rs .)" >> "$LOG_FILE"
34
+
35
+ case "$title" in
36
+ impl:*|review:*|meta:*|block:*) exit 0 ;;
37
+ "")
38
+ echo "BAD_PREFIX: task title missing; must start with impl:|review:|meta:|block:" >&2
39
+ exit 2 ;;
40
+ *)
41
+ echo "BAD_PREFIX: task title must start with impl:|review:|meta:|block: (got: $title)" >&2
42
+ exit 2 ;;
43
+ esac
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env bash
2
+ # TeammateIdle hook — block idle if there are unanswered inbound peer messages.
3
+ #
4
+ # Reads the hook event payload from stdin. Expected JSON fields (best-effort —
5
+ # the agent-teams runtime may evolve; we only fail closed on what we can verify):
6
+ # - mailbox: array of { from, replied, ... }
7
+ # - teammate: string (the idling teammate's role)
8
+ #
9
+ # Behaviour:
10
+ # - count messages where from != "lead" AND replied == false
11
+ # - if count > 0 -> exit 2 with stderr BLOCKED_IDLE
12
+ # - else -> exit 0
13
+ #
14
+ # Logs every invocation to .claude/hooks/log.jsonl in the project root for tuning.
15
+
16
+ set -euo pipefail
17
+
18
+ LOG_DIR="${CLAUDE_PROJECT_DIR:-$PWD}/.claude/hooks"
19
+ LOG_FILE="$LOG_DIR/log.jsonl"
20
+ mkdir -p "$LOG_DIR"
21
+
22
+ payload="$(cat || true)"
23
+
24
+ ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
25
+
26
+ if [ -z "$payload" ]; then
27
+ printf '{"ts":"%s","hook":"teammate-idle","skipped":"empty payload"}\n' "$ts" >> "$LOG_FILE"
28
+ exit 0
29
+ fi
30
+
31
+ if ! command -v jq >/dev/null 2>&1; then
32
+ printf '{"ts":"%s","hook":"teammate-idle","skipped":"jq not installed"}\n' "$ts" >> "$LOG_FILE"
33
+ exit 0
34
+ fi
35
+
36
+ unanswered="$(printf '%s' "$payload" | jq '[.mailbox[]? | select((.from // "") != "lead") | select((.replied // false) == false)] | length' 2>/dev/null || echo 0)"
37
+
38
+ printf '{"ts":"%s","hook":"teammate-idle","unanswered":%s}\n' "$ts" "$unanswered" >> "$LOG_FILE"
39
+
40
+ if [ "${unanswered:-0}" -gt 0 ]; then
41
+ echo "BLOCKED_IDLE: $unanswered unanswered peer messages. Reply or escalate via ESCALATION.md before idling." >&2
42
+ exit 2
43
+ fi
44
+
45
+ exit 0