@drunkcoding/agents-and-skills 0.0.19 → 0.0.23
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.
- package/.claude-plugin/marketplace.json +5 -5
- package/package.json +1 -1
- package/plugins/auto-power/.claude-plugin/plugin.json +1 -1
- package/plugins/html-effectiveness/.claude-plugin/plugin.json +1 -1
- package/plugins/plugin-validator/.claude-plugin/plugin.json +1 -1
- package/plugins/team-superpower/.claude-plugin/plugin.json +1 -1
- package/plugins/team-superpower/README.md +186 -115
- package/plugins/team-superpower/agents/backend-developer.md +105 -73
- package/plugins/team-superpower/agents/feature-planner.md +66 -0
- package/plugins/team-superpower/agents/frontend-developer.md +108 -70
- package/plugins/team-superpower/agents/orchestrator.md +83 -0
- package/plugins/team-superpower/agents/qc-engineer.md +84 -0
- package/plugins/team-superpower/agents/security-engineer.md +79 -44
- package/plugins/team-superpower/agents/solution-architect.md +80 -0
- package/plugins/team-superpower/agents/team-leader.md +100 -0
- package/plugins/team-superpower/assets/CLAUDE.md.template +22 -18
- package/plugins/team-superpower/assets/ESCALATION.md +114 -66
- package/plugins/team-superpower/assets/SESSION_README.md +232 -159
- package/plugins/team-superpower/commands/team-feature.md +191 -645
- package/plugins/team-superpower/hooks/task-completed.sh +100 -182
- package/plugins/team-superpower/hooks/task-created.sh +55 -38
- package/plugins/team-superpower/hooks/teammate-idle.sh +118 -13
- package/plugins/team-superpower/scripts/team-state.sh +106 -37
- package/plugins/tech-graph/.claude-plugin/plugin.json +1 -1
- package/plugins/team-superpower/agents/designer.md +0 -65
- package/plugins/team-superpower/agents/planner.md +0 -242
- package/plugins/team-superpower/agents/qa-engineer.md +0 -103
- package/plugins/team-superpower/agents/reviewer.md +0 -175
- package/plugins/team-superpower/agents/software-architect.md +0 -60
- package/plugins/team-superpower/commands/team-feature-resume.md +0 -185
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# TeammateIdle hook —
|
|
2
|
+
# TeammateIdle hook — v5 role-aware routing.
|
|
3
3
|
#
|
|
4
|
-
# Reads the hook event payload from stdin. Expected JSON fields
|
|
5
|
-
#
|
|
6
|
-
# -
|
|
7
|
-
#
|
|
4
|
+
# Reads the hook event payload from stdin. Expected JSON fields:
|
|
5
|
+
# - mailbox: array of { from, kind, replied, ... } — recent SendMessage history
|
|
6
|
+
# - teammate: string (the idling teammate's role; one of
|
|
7
|
+
# orchestrator | team-leader | solution-architect | feature-planner |
|
|
8
|
+
# security-engineer | backend-developer | frontend-developer | qc-engineer)
|
|
8
9
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
# -
|
|
12
|
-
#
|
|
10
|
+
# v5 behaviour: routing depends on role.
|
|
11
|
+
#
|
|
12
|
+
# backend-developer / frontend-developer:
|
|
13
|
+
# - block if any unanswered message FROM team-leader (implementer owes a reply)
|
|
14
|
+
# - block if a self-sent ESCALATE has no reply within heartbeat (advisory log)
|
|
15
|
+
# - otherwise advisory: wave dispatch may still be in flight; ok to idle
|
|
16
|
+
#
|
|
17
|
+
# team-leader:
|
|
18
|
+
# - block if SPAWN_REQUEST or RESTART_REQUEST has no SPAWN_DONE / RESTART_DONE
|
|
19
|
+
# reply from lead/orchestrator within heartbeat (must keep coordinating)
|
|
20
|
+
# - block if any unanswered ESCALATE from an implementer (must route)
|
|
21
|
+
# - otherwise advisory tick
|
|
22
|
+
#
|
|
23
|
+
# qc-engineer:
|
|
24
|
+
# - block if QC_REWORK_NEEDED has no reply (lead must acknowledge before shutdown)
|
|
25
|
+
# - otherwise advisory tick
|
|
26
|
+
#
|
|
27
|
+
# solution-architect / feature-planner / security-engineer (phase A roles):
|
|
28
|
+
# - block if owner sign-off touchpoint message has no reply yet
|
|
29
|
+
# - otherwise advisory tick (shutdown is owner-driven via lead)
|
|
30
|
+
#
|
|
31
|
+
# orchestrator (lead):
|
|
32
|
+
# - block if any unanswered SPAWN_REQUEST / RESTART_REQUEST inbound from
|
|
33
|
+
# team-leader (lead is the single spawner)
|
|
34
|
+
# - otherwise advisory tick (lead drives owner touchpoints separately)
|
|
13
35
|
#
|
|
14
36
|
# Logs every invocation to .claude/hooks/log.jsonl in the project root for tuning.
|
|
15
37
|
|
|
@@ -33,12 +55,95 @@ if ! command -v jq >/dev/null 2>&1; then
|
|
|
33
55
|
exit 0
|
|
34
56
|
fi
|
|
35
57
|
|
|
36
|
-
|
|
58
|
+
teammate="$(printf '%s' "$payload" | jq -r '.teammate // ""' 2>/dev/null || echo "")"
|
|
59
|
+
|
|
60
|
+
# Helper: count unanswered inbound messages where .from matches a pattern.
|
|
61
|
+
count_unanswered_from() {
|
|
62
|
+
local from_pattern="$1"
|
|
63
|
+
printf '%s' "$payload" \
|
|
64
|
+
| jq --arg p "$from_pattern" \
|
|
65
|
+
'[.mailbox[]?
|
|
66
|
+
| select(((.from // "") | test($p)))
|
|
67
|
+
| select((.replied // false) == false)
|
|
68
|
+
] | length' \
|
|
69
|
+
2>/dev/null \
|
|
70
|
+
|| echo 0
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# Helper: count self-sent outbound messages of a given kind with no reply yet.
|
|
74
|
+
count_outbound_unanswered_kind() {
|
|
75
|
+
local kind_pattern="$1"
|
|
76
|
+
printf '%s' "$payload" \
|
|
77
|
+
| jq --arg k "$kind_pattern" \
|
|
78
|
+
'[.mailbox[]?
|
|
79
|
+
| select(((.direction // "in") == "out"))
|
|
80
|
+
| select(((.kind // "") | test($k)))
|
|
81
|
+
| select((.replied // false) == false)
|
|
82
|
+
] | length' \
|
|
83
|
+
2>/dev/null \
|
|
84
|
+
|| echo 0
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
warn=""
|
|
37
88
|
|
|
38
|
-
|
|
89
|
+
case "$teammate" in
|
|
90
|
+
backend-developer|frontend-developer)
|
|
91
|
+
unanswered_from_leader="$(count_unanswered_from '^team-leader$')"
|
|
92
|
+
if [ "${unanswered_from_leader:-0}" -gt 0 ]; then
|
|
93
|
+
warn="BLOCKED_IDLE_implementer_owes_team-leader_reply"
|
|
94
|
+
fi
|
|
95
|
+
;;
|
|
96
|
+
team-leader)
|
|
97
|
+
spawn_pending="$(count_outbound_unanswered_kind 'SPAWN_REQUEST|RESTART_REQUEST')"
|
|
98
|
+
escalate_pending="$(count_unanswered_from '^(backend-developer|frontend-developer)$')"
|
|
99
|
+
if [ "${spawn_pending:-0}" -gt 0 ]; then
|
|
100
|
+
warn="BLOCKED_IDLE_team-leader_awaiting_lead_on_spawn_or_restart"
|
|
101
|
+
elif [ "${escalate_pending:-0}" -gt 0 ]; then
|
|
102
|
+
warn="BLOCKED_IDLE_team-leader_owes_implementer_escalate_reply"
|
|
103
|
+
fi
|
|
104
|
+
;;
|
|
105
|
+
qc-engineer)
|
|
106
|
+
qc_pending="$(count_outbound_unanswered_kind 'QC_REWORK_NEEDED')"
|
|
107
|
+
if [ "${qc_pending:-0}" -gt 0 ]; then
|
|
108
|
+
warn="BLOCKED_IDLE_qc-engineer_awaiting_lead_ack"
|
|
109
|
+
fi
|
|
110
|
+
;;
|
|
111
|
+
solution-architect|feature-planner|security-engineer)
|
|
112
|
+
handover_pending="$(count_outbound_unanswered_kind 'HANDOVER_READY|SEC_PASSED|SEC_BLOCKED')"
|
|
113
|
+
if [ "${handover_pending:-0}" -gt 0 ]; then
|
|
114
|
+
warn="BLOCKED_IDLE_phaseA_awaiting_owner_signoff"
|
|
115
|
+
fi
|
|
116
|
+
;;
|
|
117
|
+
orchestrator)
|
|
118
|
+
lead_inbound_pending="$(count_unanswered_from '^team-leader$')"
|
|
119
|
+
if [ "${lead_inbound_pending:-0}" -gt 0 ]; then
|
|
120
|
+
warn="BLOCKED_IDLE_orchestrator_unhandled_team-leader_request"
|
|
121
|
+
fi
|
|
122
|
+
;;
|
|
123
|
+
"")
|
|
124
|
+
# Unknown role: fall back to legacy v4 behaviour (any unanswered non-lead inbound).
|
|
125
|
+
legacy_unanswered="$(printf '%s' "$payload" | jq '[.mailbox[]? | select((.from // "") != "lead") | select((.replied // false) == false)] | length' 2>/dev/null || echo 0)"
|
|
126
|
+
if [ "${legacy_unanswered:-0}" -gt 0 ]; then
|
|
127
|
+
warn="BLOCKED_IDLE_legacy_unanswered_inbound"
|
|
128
|
+
fi
|
|
129
|
+
;;
|
|
130
|
+
*)
|
|
131
|
+
# Unknown but non-empty role — log advisory only, do not block.
|
|
132
|
+
:
|
|
133
|
+
;;
|
|
134
|
+
esac
|
|
39
135
|
|
|
40
|
-
if [ "$
|
|
41
|
-
printf '{"ts":"%s","hook":"teammate-idle","
|
|
136
|
+
if [ -n "$warn" ]; then
|
|
137
|
+
printf '{"ts":"%s","hook":"teammate-idle","teammate":%s,"warn":%s}\n' \
|
|
138
|
+
"$ts" \
|
|
139
|
+
"$(printf '%s' "$teammate" | jq -Rs .)" \
|
|
140
|
+
"$(printf '%s' "$warn" | jq -Rs .)" \
|
|
141
|
+
>> "$LOG_FILE"
|
|
142
|
+
else
|
|
143
|
+
printf '{"ts":"%s","hook":"teammate-idle","teammate":%s,"ok":true}\n' \
|
|
144
|
+
"$ts" \
|
|
145
|
+
"$(printf '%s' "$teammate" | jq -Rs .)" \
|
|
146
|
+
>> "$LOG_FILE"
|
|
42
147
|
fi
|
|
43
148
|
|
|
44
149
|
exit 0
|
|
@@ -1,25 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# team-state.sh — inspect and clean up team-superpower team state.
|
|
2
|
+
# team-state.sh — inspect and clean up team-superpower v5 team state.
|
|
3
3
|
#
|
|
4
4
|
# Subcommands:
|
|
5
5
|
# scan List every known superpower-* team on this machine.
|
|
6
6
|
# scan <slug> Inspect a single slug; print state for the lead/owner.
|
|
7
|
+
# members <slug> Read team config.json and list current members + roles.
|
|
7
8
|
# cleanup <slug> Dry-run cleanup; print what would be removed (exit 1).
|
|
8
|
-
# cleanup <slug> --force Remove team config, task list,
|
|
9
|
+
# cleanup <slug> --force Remove team config, task list, .team-superpower/ artefacts.
|
|
9
10
|
#
|
|
10
11
|
# Flags (cleanup only):
|
|
11
12
|
# --force Apply the cleanup (otherwise dry-run).
|
|
12
13
|
# --ignore-heartbeat Skip the "lead may still be alive" refusal.
|
|
13
14
|
# Required when the heartbeat file is < 10 min old.
|
|
14
15
|
#
|
|
16
|
+
# v5 changes (delta from v4):
|
|
17
|
+
# - Removed: tmux session handling (Agent Teams runs in-process, not in tmux).
|
|
18
|
+
# - Added: `members` subcommand reads ~/.claude/teams/superpower-<slug>/config.json
|
|
19
|
+
# and lists current teammates + roles (single-team lifecycle visibility).
|
|
20
|
+
# - Added: cleanup now removes .team-superpower/ work artefacts (spawn-briefs,
|
|
21
|
+
# static-check logs, handover artefacts the lead created).
|
|
22
|
+
# - Added: scan shows cycle_restart_count from docs/superpowers/sessions/<slug>.cycle
|
|
23
|
+
# if present (for v5's restart-on-stuck telemetry).
|
|
24
|
+
#
|
|
15
25
|
# What this script preserves (always):
|
|
16
|
-
# - docs/superpowers/{specs,plans,reviews}
|
|
17
|
-
# - the project-side checkpoint markdown
|
|
26
|
+
# - docs/superpowers/{specs,plans,reviews,handovers} durable artefacts
|
|
27
|
+
# - the project-side checkpoint markdown kept; appended with a Cleanup record
|
|
18
28
|
#
|
|
19
29
|
# What it removes (with --force):
|
|
20
|
-
# - ~/.claude/teams/superpower-<slug>/
|
|
21
|
-
# - ~/.claude/tasks/superpower-<slug>/
|
|
22
|
-
# -
|
|
30
|
+
# - ~/.claude/teams/superpower-<slug>/ team config
|
|
31
|
+
# - ~/.claude/tasks/superpower-<slug>/ shared task list
|
|
32
|
+
# - .team-superpower/spawn-briefs/ wave brief files
|
|
33
|
+
# - .team-superpower/static-check-*.log per-task static-check logs
|
|
23
34
|
#
|
|
24
35
|
# Idempotent: re-running is safe.
|
|
25
36
|
#
|
|
@@ -37,6 +48,7 @@ TEAMS_DIR="$CLAUDE_HOME/teams"
|
|
|
37
48
|
TASKS_DIR="$CLAUDE_HOME/tasks"
|
|
38
49
|
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$PWD}"
|
|
39
50
|
SESSIONS_DIR="$PROJECT_DIR/docs/superpowers/sessions"
|
|
51
|
+
ARTEFACTS_DIR="$PROJECT_DIR/.team-superpower"
|
|
40
52
|
HEARTBEAT_TTL_SECONDS=600 # 10 min
|
|
41
53
|
|
|
42
54
|
print_usage() {
|
|
@@ -44,13 +56,17 @@ print_usage() {
|
|
|
44
56
|
}
|
|
45
57
|
|
|
46
58
|
team_name_for_slug() { printf 'superpower-%s' "$1"; }
|
|
47
|
-
tmux_name_for_slug() { printf 'claude-superpower-%s' "$1"; }
|
|
48
59
|
|
|
49
60
|
heartbeat_file_for_slug() {
|
|
50
61
|
local slug="$1"
|
|
51
62
|
printf '%s/%s.heartbeat' "$SESSIONS_DIR" "$slug"
|
|
52
63
|
}
|
|
53
64
|
|
|
65
|
+
cycle_file_for_slug() {
|
|
66
|
+
local slug="$1"
|
|
67
|
+
printf '%s/%s.cycle' "$SESSIONS_DIR" "$slug"
|
|
68
|
+
}
|
|
69
|
+
|
|
54
70
|
checkpoint_for_slug() {
|
|
55
71
|
local slug="$1"
|
|
56
72
|
if [ ! -d "$SESSIONS_DIR" ]; then return; fi
|
|
@@ -87,9 +103,7 @@ cmd_scan() {
|
|
|
87
103
|
echo "team-superpower teams on this machine:"
|
|
88
104
|
while IFS= read -r s; do
|
|
89
105
|
[ -z "$s" ] && continue
|
|
90
|
-
local
|
|
91
|
-
team="$(team_name_for_slug "$s")"
|
|
92
|
-
team_dir="$TEAMS_DIR/$team"
|
|
106
|
+
local hb age
|
|
93
107
|
hb="$(heartbeat_file_for_slug "$s")"
|
|
94
108
|
age="$(heartbeat_age_seconds "$hb")"
|
|
95
109
|
if [ "$age" -lt 0 ]; then
|
|
@@ -101,39 +115,73 @@ cmd_scan() {
|
|
|
101
115
|
return 0
|
|
102
116
|
fi
|
|
103
117
|
|
|
104
|
-
local team team_dir task_dir hb age ckpt
|
|
118
|
+
local team team_dir task_dir hb age ckpt cycle_file restart_count
|
|
105
119
|
team="$(team_name_for_slug "$slug")"
|
|
106
120
|
team_dir="$TEAMS_DIR/$team"
|
|
107
121
|
task_dir="$TASKS_DIR/$team"
|
|
108
122
|
hb="$(heartbeat_file_for_slug "$slug")"
|
|
109
123
|
age="$(heartbeat_age_seconds "$hb")"
|
|
110
124
|
ckpt="$(checkpoint_for_slug "$slug")"
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
printf '
|
|
118
|
-
|
|
119
|
-
printf '
|
|
125
|
+
cycle_file="$(cycle_file_for_slug "$slug")"
|
|
126
|
+
restart_count=0
|
|
127
|
+
if [ -f "$cycle_file" ]; then
|
|
128
|
+
restart_count="$(head -n1 "$cycle_file" | tr -d '[:space:]')"
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
printf 'slug: %s\n' "$slug"
|
|
132
|
+
printf 'team_name: %s\n' "$team"
|
|
133
|
+
printf 'team_config: %s\n' "$team_dir"
|
|
134
|
+
if [ -d "$team_dir" ]; then printf 'team_config_state: present\n'; else printf 'team_config_state: absent\n'; fi
|
|
135
|
+
printf 'task_list: %s\n' "$task_dir"
|
|
136
|
+
if [ -d "$task_dir" ]; then printf 'task_list_state: present\n'; else printf 'task_list_state: absent\n'; fi
|
|
137
|
+
printf 'checkpoint: %s\n' "${ckpt:-<none>}"
|
|
138
|
+
printf 'cycle_restart_count: %s\n' "${restart_count:-0}"
|
|
120
139
|
if [ "$age" -lt 0 ]; then
|
|
121
|
-
printf 'heartbeat:
|
|
122
|
-
printf 'liveness:
|
|
140
|
+
printf 'heartbeat: <none>\n'
|
|
141
|
+
printf 'liveness: unknown (no heartbeat — treat as stale)\n'
|
|
123
142
|
else
|
|
124
|
-
printf 'heartbeat:
|
|
143
|
+
printf 'heartbeat: %s (%ds ago)\n' "$hb" "$age"
|
|
125
144
|
if [ "$age" -lt "$HEARTBEAT_TTL_SECONDS" ]; then
|
|
126
|
-
printf 'liveness:
|
|
145
|
+
printf 'liveness: LIKELY ALIVE (heartbeat < %ds)\n' "$HEARTBEAT_TTL_SECONDS"
|
|
127
146
|
else
|
|
128
|
-
printf 'liveness:
|
|
147
|
+
printf 'liveness: stale\n'
|
|
129
148
|
fi
|
|
130
149
|
fi
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
150
|
+
if [ -d "$ARTEFACTS_DIR" ]; then
|
|
151
|
+
local brief_count log_count
|
|
152
|
+
brief_count="$(find "$ARTEFACTS_DIR/spawn-briefs" -maxdepth 1 -type f -name '*.md' 2>/dev/null | wc -l | tr -d ' ')"
|
|
153
|
+
log_count="$(find "$ARTEFACTS_DIR" -maxdepth 1 -type f -name 'static-check-*.log' 2>/dev/null | wc -l | tr -d ' ')"
|
|
154
|
+
printf 'spawn_briefs: %s file(s)\n' "${brief_count:-0}"
|
|
155
|
+
printf 'static_check_logs: %s file(s)\n' "${log_count:-0}"
|
|
134
156
|
else
|
|
135
|
-
printf '
|
|
157
|
+
printf 'artefacts_dir: absent\n'
|
|
158
|
+
fi
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
cmd_members() {
|
|
162
|
+
local slug="${1:-}"
|
|
163
|
+
if [ -z "$slug" ]; then
|
|
164
|
+
echo "usage: team-state.sh members <slug>" >&2
|
|
165
|
+
return 2
|
|
166
|
+
fi
|
|
167
|
+
local team team_dir config
|
|
168
|
+
team="$(team_name_for_slug "$slug")"
|
|
169
|
+
team_dir="$TEAMS_DIR/$team"
|
|
170
|
+
config="$team_dir/config.json"
|
|
171
|
+
if [ ! -f "$config" ]; then
|
|
172
|
+
echo "team config not found: $config" >&2
|
|
173
|
+
return 4
|
|
136
174
|
fi
|
|
175
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
176
|
+
echo "jq not installed; raw config follows:" >&2
|
|
177
|
+
cat "$config"
|
|
178
|
+
return 0
|
|
179
|
+
fi
|
|
180
|
+
printf 'team: %s\n' "$team"
|
|
181
|
+
printf 'config: %s\n' "$config"
|
|
182
|
+
printf 'members:\n'
|
|
183
|
+
jq -r '.members[]? | " - " + (.role // "<no-role>") + " (id: " + (.id // "<no-id>") + ", status: " + (.status // "unknown") + ")"' "$config" 2>/dev/null \
|
|
184
|
+
|| jq -r '. | tostring' "$config"
|
|
137
185
|
}
|
|
138
186
|
|
|
139
187
|
cmd_cleanup() {
|
|
@@ -153,21 +201,27 @@ cmd_cleanup() {
|
|
|
153
201
|
return 2
|
|
154
202
|
fi
|
|
155
203
|
|
|
156
|
-
local team team_dir task_dir hb age ckpt
|
|
204
|
+
local team team_dir task_dir hb age ckpt
|
|
157
205
|
team="$(team_name_for_slug "$slug")"
|
|
158
206
|
team_dir="$TEAMS_DIR/$team"
|
|
159
207
|
task_dir="$TASKS_DIR/$team"
|
|
160
208
|
hb="$(heartbeat_file_for_slug "$slug")"
|
|
161
209
|
age="$(heartbeat_age_seconds "$hb")"
|
|
162
210
|
ckpt="$(checkpoint_for_slug "$slug")"
|
|
163
|
-
tmux_name="$(tmux_name_for_slug "$slug")"
|
|
164
211
|
|
|
165
212
|
# Build the work list.
|
|
166
213
|
local items=()
|
|
167
214
|
[ -d "$team_dir" ] && items+=("team_config:$team_dir")
|
|
168
215
|
[ -d "$task_dir" ] && items+=("task_list:$task_dir")
|
|
169
|
-
if
|
|
170
|
-
|
|
216
|
+
if [ -d "$ARTEFACTS_DIR/spawn-briefs" ]; then
|
|
217
|
+
local n
|
|
218
|
+
n="$(find "$ARTEFACTS_DIR/spawn-briefs" -maxdepth 1 -type f -name '*.md' 2>/dev/null | wc -l | tr -d ' ')"
|
|
219
|
+
[ "${n:-0}" -gt 0 ] && items+=("spawn_briefs:$ARTEFACTS_DIR/spawn-briefs (${n} files)")
|
|
220
|
+
fi
|
|
221
|
+
if [ -d "$ARTEFACTS_DIR" ]; then
|
|
222
|
+
local n
|
|
223
|
+
n="$(find "$ARTEFACTS_DIR" -maxdepth 1 -type f -name 'static-check-*.log' 2>/dev/null | wc -l | tr -d ' ')"
|
|
224
|
+
[ "${n:-0}" -gt 0 ] && items+=("static_check_logs:$ARTEFACTS_DIR/static-check-*.log (${n} files)")
|
|
171
225
|
fi
|
|
172
226
|
|
|
173
227
|
if [ ${#items[@]} -eq 0 ]; then
|
|
@@ -202,10 +256,24 @@ cmd_cleanup() {
|
|
|
202
256
|
echo "removed: $task_dir"
|
|
203
257
|
removed=$((removed+1))
|
|
204
258
|
fi
|
|
205
|
-
if
|
|
206
|
-
|
|
259
|
+
if [ -d "$ARTEFACTS_DIR/spawn-briefs" ]; then
|
|
260
|
+
rm -rf -- "$ARTEFACTS_DIR/spawn-briefs"
|
|
261
|
+
echo "removed: $ARTEFACTS_DIR/spawn-briefs"
|
|
207
262
|
removed=$((removed+1))
|
|
208
263
|
fi
|
|
264
|
+
if [ -d "$ARTEFACTS_DIR" ]; then
|
|
265
|
+
local cleared
|
|
266
|
+
cleared="$(find "$ARTEFACTS_DIR" -maxdepth 1 -type f -name 'static-check-*.log' 2>/dev/null | wc -l | tr -d ' ')"
|
|
267
|
+
if [ "${cleared:-0}" -gt 0 ]; then
|
|
268
|
+
find "$ARTEFACTS_DIR" -maxdepth 1 -type f -name 'static-check-*.log' -delete 2>/dev/null || true
|
|
269
|
+
echo "removed: ${cleared} static-check log(s) under $ARTEFACTS_DIR"
|
|
270
|
+
removed=$((removed+1))
|
|
271
|
+
fi
|
|
272
|
+
# If .team-superpower/ is now empty, drop it too.
|
|
273
|
+
if [ -z "$(ls -A "$ARTEFACTS_DIR" 2>/dev/null)" ]; then
|
|
274
|
+
rmdir "$ARTEFACTS_DIR" 2>/dev/null || true
|
|
275
|
+
fi
|
|
276
|
+
fi
|
|
209
277
|
# Heartbeat is informational; remove it so future scans don't see a stale "alive" signal.
|
|
210
278
|
if [ -f "$hb" ]; then
|
|
211
279
|
rm -f -- "$hb"
|
|
@@ -219,7 +287,7 @@ cmd_cleanup() {
|
|
|
219
287
|
{
|
|
220
288
|
printf '\n## Cleanup\n'
|
|
221
289
|
printf -- '- cleaned at: %s\n' "$ts"
|
|
222
|
-
printf -- '- removed: %d resource(s) (team_config, task_list,
|
|
290
|
+
printf -- '- removed: %d resource(s) (team_config, task_list, spawn_briefs, static_check_logs as applicable)\n' "$removed"
|
|
223
291
|
printf -- '- status: cleaned\n'
|
|
224
292
|
} >> "$ckpt"
|
|
225
293
|
echo "appended cleanup record to: $ckpt"
|
|
@@ -235,6 +303,7 @@ main() {
|
|
|
235
303
|
shift || true
|
|
236
304
|
case "$sub" in
|
|
237
305
|
scan) cmd_scan "$@" ;;
|
|
306
|
+
members) cmd_members "$@" ;;
|
|
238
307
|
cleanup) cmd_cleanup "$@" ;;
|
|
239
308
|
-h|--help|help|"") print_usage; [ -z "$sub" ] && return 2 || return 0 ;;
|
|
240
309
|
*) echo "unknown subcommand: $sub" >&2; print_usage; return 2 ;;
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: designer
|
|
3
|
-
description: Runs the Superpowers `brainstorming` skill end-to-end to produce an owner-approved design document. Owns phase 1 of the team-superpower workflow. Cannot write code, plans, or any artifact outside `docs/superpowers/specs/`.
|
|
4
|
-
tools: Read, Write, Glob, Grep
|
|
5
|
-
model: opus
|
|
6
|
-
effort: high
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Designer — Phase 1 (Brainstorming)
|
|
10
|
-
|
|
11
|
-
## First-turn directive (v3)
|
|
12
|
-
|
|
13
|
-
At the start of your first turn, run `/effort high` to set your reasoning effort. In your first heartbeat/checkpoint message back to the lead, include the self-report fields:
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
effort_set: high
|
|
17
|
-
model_actual: <the model you are running on per /model output>
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
The lead captures these and verifies them against your pinned `model: opus`. If `model_actual` does not match the pinned alias (e.g. a usage-threshold fallback dropped you to Sonnet), the lead surfaces a single owner touchpoint asking whether to continue.
|
|
21
|
-
|
|
22
|
-
## Thinking discipline
|
|
23
|
-
|
|
24
|
-
Default thinking level: **high**. Before any non-trivial step (problem decomposition, acceptance criteria, sub-project boundaries, design alternatives, spec self-review), take extended thinking time before acting. The team relies on your output being correct, not fast. Routine prose tightening and reformatting may be quick; everything load-bearing is high.
|
|
25
|
-
|
|
26
|
-
You are the **designer** teammate on a team-superpower agent team. The lead spawned you to run **one** Superpowers skill: `brainstorming`. Your output is a committed design document that the owner has signed off on. Nothing more.
|
|
27
|
-
|
|
28
|
-
## AGENTS.md (read-only, v4 §7)
|
|
29
|
-
|
|
30
|
-
At start of your first turn, read `docs/superpowers/AGENTS.md` if it exists. Apply documented patterns and pitfalls when shaping the design (e.g. if a pattern requires `ICurrentUserContext` injection, design any new feature around that abstraction). You may NEVER write to `docs/superpowers/AGENTS.md` — only the reviewer suggests, only the owner promotes.
|
|
31
|
-
|
|
32
|
-
## Hard rules
|
|
33
|
-
|
|
34
|
-
1. Run the unmodified Superpowers `brainstorming` skill at `~/.claude/plugins/cache/claude-plugins-official/superpowers/5.1.0/skills/brainstorming/SKILL.md`. Follow it verbatim. Do not invent steps, skip the visual-companion offer, or collapse the clarifying-question loop. Read the SKILL.md before you do anything else.
|
|
35
|
-
2. **Never** write code, plans, worktree commands, or anything outside `docs/superpowers/specs/`.
|
|
36
|
-
3. Save the design doc to `docs/superpowers/specs/YYYY-MM-DD-<slug>-design.md` and commit it. The brainstorming skill already prescribes this; do not deviate from its filename pattern. The `<slug>` is given to you by the lead in your spawn prompt.
|
|
37
|
-
4. Before sending a clarifying question to the owner, **post it to the lead via mailbox first**. The lead may answer from project context or escalate. Never DM the owner directly.
|
|
38
|
-
5. Every escalation you do raise MUST use the template in `docs/superpowers/ESCALATION.md`. No exceptions, even for one-line questions.
|
|
39
|
-
6. When the owner signs off on the design, post `DESIGN_APPROVED <path>` to the lead's mailbox where `<path>` is the absolute path of the design doc. Then idle.
|
|
40
|
-
|
|
41
|
-
## Output
|
|
42
|
-
|
|
43
|
-
A committed design document at `docs/superpowers/specs/YYYY-MM-DD-<slug>-design.md`, owner-approved per the brainstorming skill's sign-off step. Signals completion by posting `DESIGN_APPROVED <path>` to the lead's mailbox.
|
|
44
|
-
|
|
45
|
-
## What you must NOT do
|
|
46
|
-
|
|
47
|
-
- Decide implementation strategy. The plan is the planner's job.
|
|
48
|
-
- Pick a stack, framework, or library beyond what the brainstorming skill explicitly asks you to discuss with the owner.
|
|
49
|
-
- Touch the worktree. There is no worktree yet — it is created in phase 2.
|
|
50
|
-
- Skip the owner sign-off step inside the brainstorming skill. Phase 2 cannot start without an approved design.
|
|
51
|
-
|
|
52
|
-
## When you idle
|
|
53
|
-
|
|
54
|
-
- If you have unanswered inbound peer messages (`from != "lead"`, `replied == false`), the `TeammateIdle` hook will block your idle with `BLOCKED_IDLE`. Either reply or escalate per the template before going idle.
|
|
55
|
-
- After `DESIGN_APPROVED` is posted, idle. The lead will not call you again for this feature.
|
|
56
|
-
|
|
57
|
-
## Clarification routing
|
|
58
|
-
|
|
59
|
-
Use the 4-class decision table in `assets/ESCALATION.md` to classify every clarification you face. Your per-role buckets:
|
|
60
|
-
|
|
61
|
-
- **I decide alone (tactical):** doc structure, prose tightness, example phrasing, internal section ordering, choice of mermaid-vs-table format. Log each as one line in the session checkpoint `## Assumptions` block.
|
|
62
|
-
- **I consult planner (cross-role):** whether an acceptance criterion is measurable enough for the plan to size a test; whether a goal can be split into independent design units.
|
|
63
|
-
- **I escalate to owner (owner-only):** scope, success criteria, external policy, anything the design doc does not already pin and that changes what "done" looks like.
|
|
64
|
-
|
|
65
|
-
Every escalation MUST include the `Peer attempts:` field per `assets/ESCALATION.md`. If you classify as `tactical`, do NOT escalate — log to `## Assumptions` instead.
|