prizmkit 1.1.23 → 1.1.24

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "frameworkVersion": "1.1.23",
3
- "bundledAt": "2026-04-11T14:45:05.180Z",
4
- "bundledFrom": "fbba566"
2
+ "frameworkVersion": "1.1.24",
3
+ "bundledAt": "2026-04-12T01:13:39.954Z",
4
+ "bundledFrom": "626fbf5"
5
5
  }
@@ -6,9 +6,14 @@
6
6
  # structured progress from progress.json (written by
7
7
  # parse-stream-progress.py) and fall back to tail-based monitoring.
8
8
  #
9
+ # When stale_kill_threshold is set (>0), the heartbeat monitor will
10
+ # automatically kill the AI CLI process if it shows no progress for
11
+ # the specified duration. This prevents sessions from hanging forever
12
+ # when the AI CLI process doesn't exit after completing its work.
13
+ #
9
14
  # Usage:
10
15
  # source "$SCRIPT_DIR/lib/heartbeat.sh"
11
- # start_heartbeat "$cli_pid" "$session_log" "$progress_json" "$interval"
16
+ # start_heartbeat "$cli_pid" "$session_log" "$progress_json" "$interval" ["$stale_kill_threshold"]
12
17
  # # ... wait for CLI to finish ...
13
18
  # stop_heartbeat "$_HEARTBEAT_PID"
14
19
  #
@@ -20,19 +25,23 @@
20
25
  # Sets _HEARTBEAT_PID to the background process PID.
21
26
  #
22
27
  # Arguments:
23
- # $1 - cli_pid PID of the AI CLI process to monitor
24
- # $2 - session_log Path to session.log
25
- # $3 - progress_json Path to progress.json (may not exist if stream-json disabled)
26
- # $4 - interval Heartbeat interval in seconds
28
+ # $1 - cli_pid PID of the AI CLI process to monitor
29
+ # $2 - session_log Path to session.log
30
+ # $3 - progress_json Path to progress.json (may not exist if stream-json disabled)
31
+ # $4 - interval Heartbeat interval in seconds
32
+ # $5 - stale_kill_threshold (optional) Seconds of no progress before auto-killing the process.
33
+ # 0 = disabled (default). Recommended: 900 (15 minutes).
27
34
  start_heartbeat() {
28
35
  local cli_pid="$1"
29
36
  local session_log="$2"
30
37
  local progress_json="$3"
31
38
  local heartbeat_interval="$4"
39
+ local stale_kill_threshold="${5:-0}"
32
40
 
33
41
  (
34
42
  local elapsed=0
35
43
  local prev_size=0
44
+ local stale_seconds=0
36
45
  while kill -0 "$cli_pid" 2>/dev/null; do
37
46
  sleep "$heartbeat_interval"
38
47
  elapsed=$((elapsed + heartbeat_interval))
@@ -48,6 +57,13 @@ start_heartbeat() {
48
57
  local growth=$((cur_size - prev_size))
49
58
  prev_size=$cur_size
50
59
 
60
+ # Track progress staleness (no log growth = stale)
61
+ if [[ $growth -eq 0 ]]; then
62
+ stale_seconds=$((stale_seconds + heartbeat_interval))
63
+ else
64
+ stale_seconds=0
65
+ fi
66
+
51
67
  local size_display
52
68
  if [[ $cur_size -gt 1048576 ]]; then
53
69
  size_display="$((cur_size / 1048576))MB"
@@ -67,6 +83,33 @@ start_heartbeat() {
67
83
  status_icon="${YELLOW}⏸${NC}"
68
84
  fi
69
85
 
86
+ # Stale-kill: auto-terminate process if no progress for too long
87
+ if [[ $stale_kill_threshold -gt 0 && $stale_seconds -ge $stale_kill_threshold ]]; then
88
+ local stale_mins=$((stale_seconds / 60))
89
+ echo -e " ${RED}[HEARTBEAT]${NC} ${mins}m${secs}s | log: ${size_display} | ${RED}STALE-KILL: no progress for ${stale_mins}m (threshold: ${stale_kill_threshold}s)${NC}"
90
+ echo -e " ${RED}[HEARTBEAT]${NC} Killing AI CLI process $cli_pid (stale session)..."
91
+ kill -TERM "$cli_pid" 2>/dev/null || true
92
+ # Give process 10s to exit gracefully, then force kill
93
+ sleep 10
94
+ if kill -0 "$cli_pid" 2>/dev/null; then
95
+ echo -e " ${RED}[HEARTBEAT]${NC} Process still alive after SIGTERM, sending SIGKILL..."
96
+ kill -9 "$cli_pid" 2>/dev/null || true
97
+ fi
98
+ # Write stale-kill marker so spawn_and_wait_session knows this wasn't a crash
99
+ local _marker_dir
100
+ _marker_dir="$(dirname "$session_log")"
101
+ echo "{\"killed_at\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\", \"reason\": \"stale_session\", \"stale_seconds\": $stale_seconds, \"threshold\": $stale_kill_threshold}" > "$_marker_dir/stale-kill.json" 2>/dev/null || true
102
+ break
103
+ fi
104
+
105
+ # Build staleness hint for display
106
+ local stale_hint=""
107
+ if [[ $stale_kill_threshold -gt 0 && $stale_seconds -gt 0 ]]; then
108
+ local stale_mins=$((stale_seconds / 60))
109
+ local threshold_mins=$((stale_kill_threshold / 60))
110
+ stale_hint=" | stale: ${stale_mins}m/${threshold_mins}m"
111
+ fi
112
+
70
113
  # Try structured progress from progress.json
71
114
  if [[ -f "$progress_json" ]]; then
72
115
  local phase tool msgs tools_total
@@ -86,7 +129,7 @@ try:
86
129
  except Exception:
87
130
  sys.exit(1)
88
131
  " "$progress_json" 2>/dev/null) && {
89
- echo -e " ${status_icon} ${BLUE}[HEARTBEAT]${NC} ${mins}m${secs}s | log: ${size_display} | ${phase}"
132
+ echo -e " ${status_icon} ${BLUE}[HEARTBEAT]${NC} ${mins}m${secs}s | log: ${size_display} | ${phase}${stale_hint}"
90
133
  continue
91
134
  }
92
135
  fi
@@ -97,7 +140,7 @@ except Exception:
97
140
  last_activity=$(tail -20 "$session_log" 2>/dev/null | grep -v '^$' | tail -1 | cut -c1-80 || echo "")
98
141
  fi
99
142
 
100
- echo -e " ${status_icon} ${BLUE}[HEARTBEAT]${NC} ${mins}m${secs}s elapsed | log: ${size_display} (+${growth}B) | ${last_activity}"
143
+ echo -e " ${status_icon} ${BLUE}[HEARTBEAT]${NC} ${mins}m${secs}s elapsed | log: ${size_display} (+${growth}B) | ${last_activity}${stale_hint}"
101
144
  done
102
145
  ) &
103
146
  _HEARTBEAT_PID=$!
@@ -21,6 +21,7 @@ set -euo pipefail
21
21
  # PRIZMKIT_PLATFORM Force platform: 'codebuddy' or 'claude' (auto-detected)
22
22
  # VERBOSE Set to 1 to enable --verbose on AI CLI
23
23
  # HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)
24
+ # STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)
24
25
  # HEARTBEAT_STALE_THRESHOLD Heartbeat stale threshold in seconds (default: 600)
25
26
  # LOG_CLEANUP_ENABLED Run periodic log cleanup (default: 1)
26
27
  # LOG_RETENTION_DAYS Delete logs older than N days (default: 14)
@@ -39,6 +40,7 @@ MAX_RETRIES=${MAX_RETRIES:-3}
39
40
  SESSION_TIMEOUT=${SESSION_TIMEOUT:-0}
40
41
  HEARTBEAT_STALE_THRESHOLD=${HEARTBEAT_STALE_THRESHOLD:-600}
41
42
  HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-30}
43
+ STALE_KILL_THRESHOLD=${STALE_KILL_THRESHOLD:-900}
42
44
  LOG_CLEANUP_ENABLED=${LOG_CLEANUP_ENABLED:-1}
43
45
  LOG_RETENTION_DAYS=${LOG_RETENTION_DAYS:-14}
44
46
  LOG_MAX_TOTAL_MB=${LOG_MAX_TOTAL_MB:-1024}
@@ -146,8 +148,8 @@ spawn_and_wait_session() {
146
148
  watcher_pid=$!
147
149
  fi
148
150
 
149
- # Heartbeat monitor
150
- start_heartbeat "$cli_pid" "$session_log" "$progress_json" "$HEARTBEAT_INTERVAL"
151
+ # Heartbeat monitor (with stale-kill protection)
152
+ start_heartbeat "$cli_pid" "$session_log" "$progress_json" "$HEARTBEAT_INTERVAL" "$STALE_KILL_THRESHOLD"
151
153
  local heartbeat_pid="${_HEARTBEAT_PID:-}"
152
154
 
153
155
  # Wait for AI CLI to finish
@@ -166,6 +168,14 @@ spawn_and_wait_session() {
166
168
 
167
169
  [[ $exit_code -eq 143 ]] && exit_code=124
168
170
 
171
+ # Check for stale-kill marker (heartbeat killed the process due to no progress)
172
+ local stale_kill_marker="$session_dir/logs/stale-kill.json"
173
+ local was_stale_killed=false
174
+ if [[ -f "$stale_kill_marker" ]]; then
175
+ was_stale_killed=true
176
+ log_warn "Session was stale-killed by heartbeat monitor (no progress for too long)"
177
+ fi
178
+
169
179
  # Session summary
170
180
  if [[ -f "$session_log" ]]; then
171
181
  local final_size=$(wc -c < "$session_log" 2>/dev/null | tr -d ' ')
@@ -183,6 +193,33 @@ spawn_and_wait_session() {
183
193
  if [[ $exit_code -eq 124 ]]; then
184
194
  log_warn "Session timed out after ${SESSION_TIMEOUT}s"
185
195
  session_status="timed_out"
196
+ elif [[ "$was_stale_killed" == true ]]; then
197
+ log_warn "Session stale-killed (no progress for ${STALE_KILL_THRESHOLD}s)"
198
+ local has_commits=""
199
+ if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
200
+ has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
201
+ fi
202
+ if [[ -n "$has_commits" ]]; then
203
+ log_info "Stale-killed session has commits — treating as success"
204
+ session_status="success"
205
+ else
206
+ local uncommitted=""
207
+ uncommitted=$(git -C "$project_root" status --porcelain 2>/dev/null | head -1 || true)
208
+ if [[ -n "$uncommitted" ]]; then
209
+ log_warn "Stale-killed session has uncommitted changes — auto-committing..."
210
+ git -C "$project_root" add -A 2>/dev/null || true
211
+ if git -C "$project_root" commit --no-verify -m "chore($bug_id): auto-commit session work (stale-killed)" 2>/dev/null; then
212
+ log_info "Auto-commit succeeded"
213
+ session_status="success"
214
+ else
215
+ log_warn "Auto-commit failed — no changes to commit"
216
+ session_status="crashed"
217
+ fi
218
+ else
219
+ log_warn "Stale-killed session produced no commits and no changes"
220
+ session_status="crashed"
221
+ fi
222
+ fi
186
223
  elif [[ $exit_code -ne 0 ]]; then
187
224
  log_warn "Session exited with code $exit_code"
188
225
  session_status="crashed"
@@ -1091,6 +1128,7 @@ show_help() {
1091
1128
  echo " AI_CLI AI CLI command name (auto-detected: cbc or claude)"
1092
1129
  echo " VERBOSE Set to 1 for verbose AI CLI output"
1093
1130
  echo " HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)"
1131
+ echo " STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)"
1094
1132
  echo " LOG_CLEANUP_ENABLED Run log cleanup before execution (default: 1)"
1095
1133
  echo " LOG_RETENTION_DAYS Delete logs older than N days (default: 14)"
1096
1134
  echo " LOG_MAX_TOTAL_MB Keep total logs under N MB (default: 1024)"
@@ -23,6 +23,7 @@ set -euo pipefail
23
23
  # MODEL AI model to use (e.g. claude-opus-4.6, claude-sonnet-4.6, claude-haiku-4.5)
24
24
  # VERBOSE Set to 1 to enable --verbose on AI CLI (shows subagent output)
25
25
  # HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)
26
+ # STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)
26
27
  # HEARTBEAT_STALE_THRESHOLD Heartbeat stale threshold in seconds (default: 600)
27
28
  # LOG_CLEANUP_ENABLED Run periodic log cleanup (default: 1)
28
29
  # LOG_RETENTION_DAYS Delete logs older than N days (default: 14)
@@ -42,6 +43,7 @@ MAX_RETRIES=${MAX_RETRIES:-3}
42
43
  SESSION_TIMEOUT=${SESSION_TIMEOUT:-0}
43
44
  HEARTBEAT_STALE_THRESHOLD=${HEARTBEAT_STALE_THRESHOLD:-600}
44
45
  HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-30}
46
+ STALE_KILL_THRESHOLD=${STALE_KILL_THRESHOLD:-900}
45
47
  LOG_CLEANUP_ENABLED=${LOG_CLEANUP_ENABLED:-1}
46
48
  LOG_RETENTION_DAYS=${LOG_RETENTION_DAYS:-14}
47
49
  LOG_MAX_TOTAL_MB=${LOG_MAX_TOTAL_MB:-1024}
@@ -157,7 +159,8 @@ spawn_and_wait_session() {
157
159
  fi
158
160
 
159
161
  # Heartbeat monitor (reads progress.json when available, falls back to tail)
160
- start_heartbeat "$cbc_pid" "$session_log" "$progress_json" "$HEARTBEAT_INTERVAL"
162
+ # Also monitors for stale sessions and auto-kills if no progress for STALE_KILL_THRESHOLD seconds
163
+ start_heartbeat "$cbc_pid" "$session_log" "$progress_json" "$HEARTBEAT_INTERVAL" "$STALE_KILL_THRESHOLD"
161
164
  local heartbeat_pid="${_HEARTBEAT_PID:-}"
162
165
 
163
166
  # Wait for AI CLI to finish
@@ -179,6 +182,14 @@ spawn_and_wait_session() {
179
182
  exit_code=124
180
183
  fi
181
184
 
185
+ # Check for stale-kill marker (heartbeat killed the process due to no progress)
186
+ local stale_kill_marker="$session_dir/logs/stale-kill.json"
187
+ local was_stale_killed=false
188
+ if [[ -f "$stale_kill_marker" ]]; then
189
+ was_stale_killed=true
190
+ log_warn "Session was stale-killed by heartbeat monitor (no progress for too long)"
191
+ fi
192
+
182
193
  # Show final session summary
183
194
  if [[ -f "$session_log" ]]; then
184
195
  local final_size=$(wc -c < "$session_log" 2>/dev/null | tr -d ' ')
@@ -198,6 +209,34 @@ spawn_and_wait_session() {
198
209
  if [[ $exit_code -eq 124 ]]; then
199
210
  log_warn "Session timed out after ${SESSION_TIMEOUT}s"
200
211
  session_status="timed_out"
212
+ elif [[ "$was_stale_killed" == true ]]; then
213
+ log_warn "Session stale-killed (no progress for ${STALE_KILL_THRESHOLD}s)"
214
+ # Treat stale-killed as potentially successful — check for commits
215
+ local has_commits=""
216
+ if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
217
+ has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
218
+ fi
219
+ if [[ -n "$has_commits" ]]; then
220
+ log_info "Stale-killed session has commits — treating as success"
221
+ session_status="success"
222
+ else
223
+ local uncommitted=""
224
+ uncommitted=$(git -C "$project_root" status --porcelain 2>/dev/null | head -1 || true)
225
+ if [[ -n "$uncommitted" ]]; then
226
+ log_warn "Stale-killed session has uncommitted changes — auto-committing..."
227
+ git -C "$project_root" add -A 2>/dev/null || true
228
+ if git -C "$project_root" commit --no-verify -m "chore($feature_id): auto-commit session work (stale-killed)" 2>/dev/null; then
229
+ log_info "Auto-commit succeeded"
230
+ session_status="success"
231
+ else
232
+ log_warn "Auto-commit failed — no changes to commit"
233
+ session_status="crashed"
234
+ fi
235
+ else
236
+ log_warn "Stale-killed session produced no commits and no changes"
237
+ session_status="crashed"
238
+ fi
239
+ fi
201
240
  elif [[ $exit_code -ne 0 ]]; then
202
241
  log_warn "Session exited with code $exit_code"
203
242
  session_status="crashed"
@@ -1318,6 +1357,7 @@ show_help() {
1318
1357
  echo " AI_CLI AI CLI command name (auto-detected: cbc or claude)"
1319
1358
  echo " MODEL AI model ID (e.g. claude-opus-4.6, claude-sonnet-4.6, claude-haiku-4.5)"
1320
1359
  echo " HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)"
1360
+ echo " STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)"
1321
1361
  echo " HEARTBEAT_STALE_THRESHOLD Heartbeat stale threshold in seconds (default: 600)"
1322
1362
  echo " LOG_CLEANUP_ENABLED Run log cleanup before execution (default: 1)"
1323
1363
  echo " LOG_RETENTION_DAYS Delete logs older than N days (default: 14)"
@@ -21,6 +21,7 @@ set -euo pipefail
21
21
  # PRIZMKIT_PLATFORM Force platform: 'codebuddy' or 'claude' (auto-detected)
22
22
  # VERBOSE Set to 1 to enable --verbose on AI CLI
23
23
  # HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)
24
+ # STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)
24
25
  # HEARTBEAT_STALE_THRESHOLD Heartbeat stale threshold in seconds (default: 600)
25
26
  # LOG_CLEANUP_ENABLED Run periodic log cleanup (default: 1)
26
27
  # LOG_RETENTION_DAYS Delete logs older than N days (default: 14)
@@ -40,6 +41,7 @@ MAX_RETRIES=${MAX_RETRIES:-3}
40
41
  SESSION_TIMEOUT=${SESSION_TIMEOUT:-0}
41
42
  HEARTBEAT_STALE_THRESHOLD=${HEARTBEAT_STALE_THRESHOLD:-600}
42
43
  HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-30}
44
+ STALE_KILL_THRESHOLD=${STALE_KILL_THRESHOLD:-900}
43
45
  LOG_CLEANUP_ENABLED=${LOG_CLEANUP_ENABLED:-1}
44
46
  LOG_RETENTION_DAYS=${LOG_RETENTION_DAYS:-14}
45
47
  LOG_MAX_TOTAL_MB=${LOG_MAX_TOTAL_MB:-1024}
@@ -148,8 +150,8 @@ spawn_and_wait_session() {
148
150
  watcher_pid=$!
149
151
  fi
150
152
 
151
- # Heartbeat monitor
152
- start_heartbeat "$cli_pid" "$session_log" "$progress_json" "$HEARTBEAT_INTERVAL"
153
+ # Heartbeat monitor (with stale-kill protection)
154
+ start_heartbeat "$cli_pid" "$session_log" "$progress_json" "$HEARTBEAT_INTERVAL" "$STALE_KILL_THRESHOLD"
153
155
  local heartbeat_pid="${_HEARTBEAT_PID:-}"
154
156
 
155
157
  # Wait for AI CLI to finish
@@ -168,6 +170,14 @@ spawn_and_wait_session() {
168
170
 
169
171
  [[ $exit_code -eq 143 ]] && exit_code=124
170
172
 
173
+ # Check for stale-kill marker (heartbeat killed the process due to no progress)
174
+ local stale_kill_marker="$session_dir/logs/stale-kill.json"
175
+ local was_stale_killed=false
176
+ if [[ -f "$stale_kill_marker" ]]; then
177
+ was_stale_killed=true
178
+ log_warn "Session was stale-killed by heartbeat monitor (no progress for too long)"
179
+ fi
180
+
171
181
  # Session summary
172
182
  if [[ -f "$session_log" ]]; then
173
183
  local final_size=$(wc -c < "$session_log" 2>/dev/null | tr -d ' ')
@@ -185,6 +195,33 @@ spawn_and_wait_session() {
185
195
  if [[ $exit_code -eq 124 ]]; then
186
196
  log_warn "Session timed out after ${SESSION_TIMEOUT}s"
187
197
  session_status="timed_out"
198
+ elif [[ "$was_stale_killed" == true ]]; then
199
+ log_warn "Session stale-killed (no progress for ${STALE_KILL_THRESHOLD}s)"
200
+ local has_commits=""
201
+ if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
202
+ has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
203
+ fi
204
+ if [[ -n "$has_commits" ]]; then
205
+ log_info "Stale-killed session has commits — treating as success"
206
+ session_status="success"
207
+ else
208
+ local uncommitted=""
209
+ uncommitted=$(git -C "$project_root" status --porcelain 2>/dev/null | head -1 || true)
210
+ if [[ -n "$uncommitted" ]]; then
211
+ log_warn "Stale-killed session has uncommitted changes — auto-committing..."
212
+ git -C "$project_root" add -A 2>/dev/null || true
213
+ if git -C "$project_root" commit --no-verify -m "chore($refactor_id): auto-commit session work (stale-killed)" 2>/dev/null; then
214
+ log_info "Auto-commit succeeded"
215
+ session_status="success"
216
+ else
217
+ log_warn "Auto-commit failed — no changes to commit"
218
+ session_status="crashed"
219
+ fi
220
+ else
221
+ log_warn "Stale-killed session produced no commits and no changes"
222
+ session_status="crashed"
223
+ fi
224
+ fi
188
225
  elif [[ $exit_code -ne 0 ]]; then
189
226
  log_warn "Session exited with code $exit_code"
190
227
  session_status="crashed"
@@ -1129,6 +1166,7 @@ show_help() {
1129
1166
  echo " VERBOSE Set to 1 for verbose AI CLI output"
1130
1167
  echo " STRICT_BEHAVIOR_CHECK Force full test suite after each refactor (default: 1)"
1131
1168
  echo " HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)"
1169
+ echo " STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)"
1132
1170
  echo " LOG_CLEANUP_ENABLED Run log cleanup before execution (default: 1)"
1133
1171
  echo " LOG_RETENTION_DAYS Delete logs older than N days (default: 14)"
1134
1172
  echo " LOG_MAX_TOTAL_MB Keep total logs under N MB (default: 1024)"
@@ -189,6 +189,49 @@ Round 5: 3 failures [test_b, test_d, test_e] ← plateau 3/3 → STOP
189
189
 
190
190
  You MUST execute this phase. Do NOT skip it. Do NOT mark it as completed without actually running playwright-cli.
191
191
 
192
+ **CRITICAL CONSTRAINT — playwright-cli ONLY, NO Playwright MCP**:
193
+ - You MUST use `playwright-cli` (the CLI tool) for ALL browser interactions in this phase
194
+ - **NEVER** use Playwright MCP server, Playwright MCP tools, or any MCP-based browser automation
195
+ - If you have Playwright MCP configured, IGNORE it entirely — use the CLI command `playwright-cli` exclusively
196
+ - All browser actions go through `playwright-cli <command>` in the Bash tool, not through any MCP tool call
197
+
198
+ **Step 0 — Playwright CLI Readiness Check (BLOCKING — must pass before any browser action)**:
199
+
200
+ 0a. Check if `playwright-cli` is installed:
201
+ ```bash
202
+ which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
203
+ ```
204
+ If output is `NOT_INSTALLED`, install it:
205
+ ```bash
206
+ npm install -g @playwright/cli@latest
207
+ ```
208
+ Then verify installation succeeded: `playwright-cli --version`. If installation fails, log `## Browser Verification: SKIPPED — playwright-cli installation failed` in context-snapshot.md and proceed to the next phase.
209
+
210
+ 0b. Learn playwright-cli usage (run once per session):
211
+ ```bash
212
+ playwright-cli --help
213
+ ```
214
+
215
+ 0c. Check if playwright-cli skill is installed for the current AI platform:
216
+ ```bash
217
+ CURRENT_PLATFORM=""
218
+ if which claude >/dev/null 2>&1; then
219
+ CURRENT_PLATFORM="claude"; SKILL_DIR="$HOME/.claude/skills"
220
+ elif which cbc >/dev/null 2>&1; then
221
+ CURRENT_PLATFORM="codebuddy"; SKILL_DIR="$HOME/.cbc/skills"
222
+ else
223
+ CURRENT_PLATFORM="unknown"
224
+ fi
225
+ if [ -d "$SKILL_DIR/playwright-cli" ] || ls "$SKILL_DIR"/playwright* 2>/dev/null | grep -q .; then
226
+ echo "SKILL_EXISTS"
227
+ else
228
+ echo "SKILL_MISSING"
229
+ fi
230
+ ```
231
+ If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform is NOT claude, copy installed skill from `$HOME/.claude/skills/playwright-cli` to `$SKILL_DIR/playwright-cli`.
232
+
233
+ 0d. Read the installed playwright-cli skill (SKILL.md) for workflow guidance. Use its recommended patterns to construct your verification flow.
234
+
192
235
  **Step 1 — Start Dev Server**:
193
236
 
194
237
  You know this project's tech stack. Detect and start the dev server yourself:
@@ -196,9 +239,7 @@ You know this project's tech stack. Detect and start the dev server yourself:
196
239
  1. Identify the dev server start command from project config (`package.json` scripts, `Makefile`, `docker-compose.yml`, etc.)
197
240
  2. **Detect the dev server port** — use the pre-detected port from pipeline if available, otherwise extract from project config. Do NOT hardcode or guess the port:
198
241
  ```bash
199
- # Use pipeline-injected port if available, otherwise extract from package.json
200
242
  DEV_PORT={{DEV_PORT}}
201
- # If DEV_PORT is still a placeholder, detect at runtime:
202
243
  if [ "$DEV_PORT" = "{{DEV_PORT}}" ]; then
203
244
  DEV_PORT=$(node -e "const s=require('./package.json').scripts.dev; const m=s.match(/-p\s+(\d+)/); console.log(m?m[1]:'')")
204
245
  if [ -z "$DEV_PORT" ]; then
@@ -225,14 +266,14 @@ You know this project's tech stack. Detect and start the dev server yourself:
225
266
 
226
267
  Use `playwright-cli snapshot` on the running app to discover actual element refs, then verify these goals:
227
268
  {{BROWSER_VERIFY_STEPS}}
228
- Decide the concrete playwright-cli actions (click, fill, assert, etc.) yourself based on the snapshot output and your knowledge of the implemented code. The goals above describe WHAT to verify — you determine HOW.
229
269
 
230
- Take a final screenshot for evidence.
270
+ Construct your verification workflow based on: (1) the playwright-cli skill documentation, (2) the `--help` output, (3) the current task's acceptance criteria. Decide the concrete playwright-cli actions yourself. Take a final screenshot: `playwright-cli screenshot`.
231
271
 
232
272
  **Step 3 — Cleanup (REQUIRED — you started it, you stop it)**:
233
273
 
234
- 1. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
235
- 2. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
274
+ 1. Close the playwright-cli browser: `playwright-cli close`
275
+ 2. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
276
+ 3. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
236
277
 
237
278
  **Step 4 — Reporting**:
238
279
 
@@ -241,10 +282,12 @@ Append results to `context-snapshot.md`:
241
282
  ## Browser Verification
242
283
  URL: http://localhost:$DEV_PORT
243
284
  Dev Server Command: <actual command used>
244
- Steps executed: [list]
285
+ playwright-cli version: <version>
286
+ Steps executed: [list of playwright-cli commands used]
245
287
  Screenshot: [path]
246
288
  Result: PASS / FAIL (reason)
247
289
  Server cleanup: confirmed
290
+ Browser cleanup: confirmed
248
291
  ```
249
292
 
250
293
  If verification fails, log the failure details but continue to commit. Failures do NOT block the commit, but you MUST attempt verification and MUST clean up the dev server.
@@ -287,6 +287,49 @@ If GATE:MISSING — send message to Reviewer (re-spawn if needed): "Write review
287
287
 
288
288
  You MUST execute this phase. Do NOT skip it. Do NOT mark it as completed without actually running playwright-cli.
289
289
 
290
+ **CRITICAL CONSTRAINT — playwright-cli ONLY, NO Playwright MCP**:
291
+ - You MUST use `playwright-cli` (the CLI tool) for ALL browser interactions in this phase
292
+ - **NEVER** use Playwright MCP server, Playwright MCP tools, or any MCP-based browser automation
293
+ - If you have Playwright MCP configured, IGNORE it entirely — use the CLI command `playwright-cli` exclusively
294
+ - All browser actions go through `playwright-cli <command>` in the Bash tool, not through any MCP tool call
295
+
296
+ **Step 0 — Playwright CLI Readiness Check (BLOCKING — must pass before any browser action)**:
297
+
298
+ 0a. Check if `playwright-cli` is installed:
299
+ ```bash
300
+ which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
301
+ ```
302
+ If output is `NOT_INSTALLED`, install it:
303
+ ```bash
304
+ npm install -g @playwright/cli@latest
305
+ ```
306
+ Then verify installation succeeded: `playwright-cli --version`. If installation fails, log `## Browser Verification: SKIPPED — playwright-cli installation failed` in context-snapshot.md and proceed to the next phase.
307
+
308
+ 0b. Learn playwright-cli usage (run once per session):
309
+ ```bash
310
+ playwright-cli --help
311
+ ```
312
+
313
+ 0c. Check if playwright-cli skill is installed for the current AI platform:
314
+ ```bash
315
+ CURRENT_PLATFORM=""
316
+ if which claude >/dev/null 2>&1; then
317
+ CURRENT_PLATFORM="claude"; SKILL_DIR="$HOME/.claude/skills"
318
+ elif which cbc >/dev/null 2>&1; then
319
+ CURRENT_PLATFORM="codebuddy"; SKILL_DIR="$HOME/.cbc/skills"
320
+ else
321
+ CURRENT_PLATFORM="unknown"
322
+ fi
323
+ if [ -d "$SKILL_DIR/playwright-cli" ] || ls "$SKILL_DIR"/playwright* 2>/dev/null | grep -q .; then
324
+ echo "SKILL_EXISTS"
325
+ else
326
+ echo "SKILL_MISSING"
327
+ fi
328
+ ```
329
+ If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform is NOT claude, copy installed skill from `$HOME/.claude/skills/playwright-cli` to `$SKILL_DIR/playwright-cli`.
330
+
331
+ 0d. Read the installed playwright-cli skill (SKILL.md) for workflow guidance. Use its recommended patterns to construct your verification flow.
332
+
290
333
  **Step 1 — Start Dev Server**:
291
334
 
292
335
  You know this project's tech stack. Detect and start the dev server yourself:
@@ -294,9 +337,7 @@ You know this project's tech stack. Detect and start the dev server yourself:
294
337
  1. Identify the dev server start command from project config (`package.json` scripts, `Makefile`, `docker-compose.yml`, etc.)
295
338
  2. **Detect the dev server port** — use the pre-detected port from pipeline if available, otherwise extract from project config. Do NOT hardcode or guess the port:
296
339
  ```bash
297
- # Use pipeline-injected port if available, otherwise extract from package.json
298
340
  DEV_PORT={{DEV_PORT}}
299
- # If DEV_PORT is still a placeholder, detect at runtime:
300
341
  if [ "$DEV_PORT" = "{{DEV_PORT}}" ]; then
301
342
  DEV_PORT=$(node -e "const s=require('./package.json').scripts.dev; const m=s.match(/-p\s+(\d+)/); console.log(m?m[1]:'')")
302
343
  if [ -z "$DEV_PORT" ]; then
@@ -323,14 +364,14 @@ You know this project's tech stack. Detect and start the dev server yourself:
323
364
 
324
365
  Use `playwright-cli snapshot` on the running app to discover actual element refs, then verify these goals:
325
366
  {{BROWSER_VERIFY_STEPS}}
326
- Decide the concrete playwright-cli actions (click, fill, assert, etc.) yourself based on the snapshot output and your knowledge of the implemented code. The goals above describe WHAT to verify — you determine HOW.
327
367
 
328
- Take a final screenshot for evidence.
368
+ Construct your verification workflow based on: (1) the playwright-cli skill documentation, (2) the `--help` output, (3) the current task's acceptance criteria. Decide the concrete playwright-cli actions yourself. Take a final screenshot: `playwright-cli screenshot`.
329
369
 
330
370
  **Step 3 — Cleanup (REQUIRED — you started it, you stop it)**:
331
371
 
332
- 1. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
333
- 2. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
372
+ 1. Close the playwright-cli browser: `playwright-cli close`
373
+ 2. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
374
+ 3. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
334
375
 
335
376
  **Step 4 — Reporting**:
336
377
 
@@ -339,10 +380,12 @@ Append results to `context-snapshot.md`:
339
380
  ## Browser Verification
340
381
  URL: http://localhost:$DEV_PORT
341
382
  Dev Server Command: <actual command used>
342
- Steps executed: [list]
383
+ playwright-cli version: <version>
384
+ Steps executed: [list of playwright-cli commands used]
343
385
  Screenshot: [path]
344
386
  Result: PASS / FAIL (reason)
345
387
  Server cleanup: confirmed
388
+ Browser cleanup: confirmed
346
389
  ```
347
390
 
348
391
  If verification fails, log the failure details but continue to commit. Failures do NOT block the commit, but you MUST attempt verification and MUST clean up the dev server.
@@ -359,6 +359,49 @@ If GATE:MISSING — send message to Reviewer (re-spawn if needed): "Write review
359
359
 
360
360
  You MUST execute this phase. Do NOT skip it. Do NOT mark it as completed without actually running playwright-cli.
361
361
 
362
+ **CRITICAL CONSTRAINT — playwright-cli ONLY, NO Playwright MCP**:
363
+ - You MUST use `playwright-cli` (the CLI tool) for ALL browser interactions in this phase
364
+ - **NEVER** use Playwright MCP server, Playwright MCP tools, or any MCP-based browser automation
365
+ - If you have Playwright MCP configured, IGNORE it entirely — use the CLI command `playwright-cli` exclusively
366
+ - All browser actions go through `playwright-cli <command>` in the Bash tool, not through any MCP tool call
367
+
368
+ **Step 0 — Playwright CLI Readiness Check (BLOCKING — must pass before any browser action)**:
369
+
370
+ 0a. Check if `playwright-cli` is installed:
371
+ ```bash
372
+ which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
373
+ ```
374
+ If output is `NOT_INSTALLED`, install it:
375
+ ```bash
376
+ npm install -g @playwright/cli@latest
377
+ ```
378
+ Then verify installation succeeded: `playwright-cli --version`. If installation fails, log `## Browser Verification: SKIPPED — playwright-cli installation failed` in context-snapshot.md and proceed to the next phase.
379
+
380
+ 0b. Learn playwright-cli usage (run once per session):
381
+ ```bash
382
+ playwright-cli --help
383
+ ```
384
+
385
+ 0c. Check if playwright-cli skill is installed for the current AI platform:
386
+ ```bash
387
+ CURRENT_PLATFORM=""
388
+ if which claude >/dev/null 2>&1; then
389
+ CURRENT_PLATFORM="claude"; SKILL_DIR="$HOME/.claude/skills"
390
+ elif which cbc >/dev/null 2>&1; then
391
+ CURRENT_PLATFORM="codebuddy"; SKILL_DIR="$HOME/.cbc/skills"
392
+ else
393
+ CURRENT_PLATFORM="unknown"
394
+ fi
395
+ if [ -d "$SKILL_DIR/playwright-cli" ] || ls "$SKILL_DIR"/playwright* 2>/dev/null | grep -q .; then
396
+ echo "SKILL_EXISTS"
397
+ else
398
+ echo "SKILL_MISSING"
399
+ fi
400
+ ```
401
+ If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform is NOT claude, copy installed skill from `$HOME/.claude/skills/playwright-cli` to `$SKILL_DIR/playwright-cli`.
402
+
403
+ 0d. Read the installed playwright-cli skill (SKILL.md) for workflow guidance. Use its recommended patterns to construct your verification flow.
404
+
362
405
  **Step 1 — Start Dev Server**:
363
406
 
364
407
  You know this project's tech stack. Detect and start the dev server yourself:
@@ -366,9 +409,7 @@ You know this project's tech stack. Detect and start the dev server yourself:
366
409
  1. Identify the dev server start command from project config (`package.json` scripts, `Makefile`, `docker-compose.yml`, etc.)
367
410
  2. **Detect the dev server port** — use the pre-detected port from pipeline if available, otherwise extract from project config. Do NOT hardcode or guess the port:
368
411
  ```bash
369
- # Use pipeline-injected port if available, otherwise extract from package.json
370
412
  DEV_PORT={{DEV_PORT}}
371
- # If DEV_PORT is still a placeholder, detect at runtime:
372
413
  if [ "$DEV_PORT" = "{{DEV_PORT}}" ]; then
373
414
  DEV_PORT=$(node -e "const s=require('./package.json').scripts.dev; const m=s.match(/-p\s+(\d+)/); console.log(m?m[1]:'')")
374
415
  if [ -z "$DEV_PORT" ]; then
@@ -395,14 +436,14 @@ You know this project's tech stack. Detect and start the dev server yourself:
395
436
 
396
437
  Use `playwright-cli snapshot` on the running app to discover actual element refs, then verify these goals:
397
438
  {{BROWSER_VERIFY_STEPS}}
398
- Decide the concrete playwright-cli actions (click, fill, assert, etc.) yourself based on the snapshot output and your knowledge of the implemented code. The goals above describe WHAT to verify — you determine HOW.
399
439
 
400
- Take a final screenshot for evidence.
440
+ Construct your verification workflow based on: (1) the playwright-cli skill documentation, (2) the `--help` output, (3) the current task's acceptance criteria. Decide the concrete playwright-cli actions yourself. Take a final screenshot: `playwright-cli screenshot`.
401
441
 
402
442
  **Step 3 — Cleanup (REQUIRED — you started it, you stop it)**:
403
443
 
404
- 1. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
405
- 2. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
444
+ 1. Close the playwright-cli browser: `playwright-cli close`
445
+ 2. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
446
+ 3. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
406
447
 
407
448
  **Step 4 — Reporting**:
408
449
 
@@ -411,10 +452,12 @@ Append results to `context-snapshot.md`:
411
452
  ## Browser Verification
412
453
  URL: http://localhost:$DEV_PORT
413
454
  Dev Server Command: <actual command used>
414
- Steps executed: [list]
455
+ playwright-cli version: <version>
456
+ Steps executed: [list of playwright-cli commands used]
415
457
  Screenshot: [path]
416
458
  Result: PASS / FAIL (reason)
417
459
  Server cleanup: confirmed
460
+ Browser cleanup: confirmed
418
461
  ```
419
462
 
420
463
  If verification fails, log the failure details but continue to commit. Failures do NOT block the commit, but you MUST attempt verification and MUST clean up the dev server.
@@ -11,3 +11,23 @@ You are running in **headless non-interactive mode** with a FINITE context windo
11
11
  5. **Minimize tool output** — Never load full command output into context. First capture to a temp file (`cmd 2>&1 | tee /tmp/out.txt | tail -20`), then scan the head/tail to identify relevant fields, and use targeted filtering (`grep`, `sed`, `awk`) to extract only the information needed for the current task. Only read the filtered result — never the raw full output.
12
12
  6. **No intermediate commits** — Do NOT run `git add`/`git commit` during implementation phases. All changes are committed once at the end via `/prizmkit-committer`.
13
13
  7. **Capture test output once** — When running test suites, always use `$TEST_CMD 2>&1 | tee /tmp/test-out.txt | tail -20`. Then grep `/tmp/test-out.txt` for details. Never re-run the suite just to apply a different filter.
14
+ 8. **Scaffold / generated file awareness (CRITICAL)** — When you run a scaffolding tool or package manager init command (`npm init`, `npx create-*`, `vite create`, `cargo init`, `go mod init`, `rails new`, `django-admin startproject`, `npx shadcn-ui init`, etc.), the output files are **generated boilerplate**. You MUST:
15
+ - Identify and mentally tag all files created by the tool as "scaffold files"
16
+ - Record the list of scaffold-generated files in context-snapshot.md under a `### Scaffold Files (do not re-read)` section
17
+ - **NEVER re-read scaffold files** after initial creation. Their content is standard boilerplate — you already know what they contain from the tool that generated them
18
+ - If you need to modify a scaffold file, make the edit directly without reading it first (you know the standard template content)
19
+ - This applies equally to `node_modules/`, `package-lock.json`, generated config files (`tsconfig.json`, `vite.config.ts`, `tailwind.config.js`, `.eslintrc`, etc.) produced by init commands
20
+ - When passing context to subagents, explicitly tell them which files are scaffold-generated so they skip reading them too
21
+ 9. **Package version verification (HARD CONSTRAINT — BLOCKING)** — Before writing ANY dependency version in `package.json`, `requirements.txt`, `Cargo.toml`, `go.mod`, `Gemfile`, `pyproject.toml`, or any other dependency manifest:
22
+ - You MUST verify the real version exists by querying the package registry first:
23
+ - npm/Node.js: `npm view <package> dist-tags.latest 2>/dev/null`
24
+ - Python/pip: `pip index versions <package> 2>/dev/null | head -1`
25
+ - Go: `go list -m -versions <module>@latest 2>/dev/null`
26
+ - Rust: `cargo search <crate> --limit 1 2>/dev/null`
27
+ - **NEVER guess or hallucinate version numbers**. If you cannot verify a version, use `"latest"` or `"*"` as a placeholder, or omit the version constraint entirely and let the package manager resolve it
28
+ - If the registry query fails (network issue, package not found), you MUST either:
29
+ (a) Use a known-safe version you have high confidence in, OR
30
+ (b) Skip that dependency and document it as a manual step, OR
31
+ (c) Use no version constraint (e.g., `"express": "*"`)
32
+ - **This is a BLOCKING gate**: do NOT run `npm install` / `pip install` / `cargo build` / `go mod tidy` until ALL versions in the manifest have been verified or use open constraints
33
+ - Batch version lookups: query multiple packages in parallel to save time (e.g., run multiple `npm view` commands concurrently)
@@ -2,6 +2,77 @@
2
2
 
3
3
  You MUST execute this phase. Do NOT skip it. Do NOT mark it as completed without actually running playwright-cli.
4
4
 
5
+ **CRITICAL CONSTRAINT — playwright-cli ONLY, NO Playwright MCP**:
6
+ - You MUST use `playwright-cli` (the CLI tool) for ALL browser interactions in this phase
7
+ - **NEVER** use Playwright MCP server, Playwright MCP tools, or any MCP-based browser automation
8
+ - If you have Playwright MCP configured, IGNORE it entirely — use the CLI command `playwright-cli` exclusively
9
+ - All browser actions go through `playwright-cli <command>` in the Bash tool, not through any MCP tool call
10
+
11
+ **Step 0 — Playwright CLI Readiness Check (BLOCKING — must pass before any browser action)**:
12
+
13
+ 0a. Check if `playwright-cli` is installed:
14
+ ```bash
15
+ which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
16
+ ```
17
+ If output is `NOT_INSTALLED`, install it:
18
+ ```bash
19
+ npm install -g @playwright/cli@latest
20
+ ```
21
+ Then verify installation succeeded:
22
+ ```bash
23
+ playwright-cli --version
24
+ ```
25
+ If installation fails, log the error in context-snapshot.md under `## Browser Verification: SKIPPED — playwright-cli installation failed` and proceed to the next phase. Do NOT attempt browser verification without playwright-cli.
26
+
27
+ 0b. Learn playwright-cli usage (run once per session to understand available commands):
28
+ ```bash
29
+ playwright-cli --help
30
+ ```
31
+ Use this output to determine the correct commands for your verification steps. Do NOT guess command syntax — refer to the help output.
32
+
33
+ 0c. Check if playwright-cli skill is installed for the current AI platform:
34
+ ```bash
35
+ # Detect AI CLI platform
36
+ CURRENT_PLATFORM=""
37
+ if which claude >/dev/null 2>&1; then
38
+ CURRENT_PLATFORM="claude"
39
+ SKILL_DIR="$HOME/.claude/skills"
40
+ elif which cbc >/dev/null 2>&1; then
41
+ CURRENT_PLATFORM="codebuddy"
42
+ SKILL_DIR="$HOME/.cbc/skills"
43
+ else
44
+ # Try to detect from environment or config
45
+ CURRENT_PLATFORM="unknown"
46
+ fi
47
+
48
+ # Check if playwright-cli skill exists
49
+ if [ -d "$SKILL_DIR/playwright-cli" ] || ls "$SKILL_DIR"/playwright* 2>/dev/null | grep -q .; then
50
+ echo "SKILL_EXISTS"
51
+ else
52
+ echo "SKILL_MISSING"
53
+ fi
54
+ ```
55
+ If `SKILL_MISSING`:
56
+ ```bash
57
+ # Install playwright-cli skills (defaults to claude platform)
58
+ playwright-cli install --skills
59
+ ```
60
+ If the current platform is NOT claude, move the installed skill files to the correct location:
61
+ ```bash
62
+ # Skills are installed to claude's default location — move to current platform's skill dir
63
+ if [ "$CURRENT_PLATFORM" != "claude" ] && [ "$CURRENT_PLATFORM" != "unknown" ]; then
64
+ CLAUDE_SKILL_DIR="$HOME/.claude/skills"
65
+ if [ -d "$CLAUDE_SKILL_DIR/playwright-cli" ]; then
66
+ mkdir -p "$SKILL_DIR"
67
+ cp -r "$CLAUDE_SKILL_DIR/playwright-cli" "$SKILL_DIR/"
68
+ echo "Moved playwright-cli skill from claude to $CURRENT_PLATFORM"
69
+ fi
70
+ fi
71
+ ```
72
+
73
+ 0d. Read the installed playwright-cli skill for workflow guidance:
74
+ After skill installation, read the skill's SKILL.md to understand recommended workflows and patterns. Use these patterns to construct your verification flow — do NOT invent your own patterns if the skill provides them.
75
+
5
76
  **Step 1 — Start Dev Server**:
6
77
 
7
78
  You know this project's tech stack. Detect and start the dev server yourself:
@@ -39,14 +110,20 @@ You know this project's tech stack. Detect and start the dev server yourself:
39
110
  Use `playwright-cli snapshot` on the running app to discover actual element refs, then verify these goals:
40
111
  {{BROWSER_VERIFY_STEPS}}
41
112
 
42
- Decide the concrete playwright-cli actions (click, fill, assert, etc.) yourself based on the snapshot output and your knowledge of the implemented code. The goals above describe WHAT to verify — you determine HOW.
113
+ Construct your verification workflow based on:
114
+ 1. The playwright-cli skill documentation (read in Step 0d)
115
+ 2. The `playwright-cli --help` output (captured in Step 0b)
116
+ 3. The current task's acceptance criteria and implemented features
117
+
118
+ Decide the concrete playwright-cli actions (click, fill, snapshot, screenshot, etc.) yourself based on the snapshot output and your knowledge of the implemented code. The goals above describe WHAT to verify — you determine HOW using playwright-cli commands.
43
119
 
44
- Take a final screenshot for evidence.
120
+ Take a final screenshot for evidence: `playwright-cli screenshot`
45
121
 
46
122
  **Step 3 — Cleanup (REQUIRED — you started it, you stop it)**:
47
123
 
48
- 1. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
49
- 2. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
124
+ 1. Close the playwright-cli browser: `playwright-cli close`
125
+ 2. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
126
+ 3. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
50
127
 
51
128
  **Step 4 — Reporting**:
52
129
 
@@ -55,10 +132,12 @@ Append results to `context-snapshot.md`:
55
132
  ## Browser Verification
56
133
  URL: http://localhost:$DEV_PORT
57
134
  Dev Server Command: <actual command used>
58
- Steps executed: [list]
135
+ playwright-cli version: <version>
136
+ Steps executed: [list of playwright-cli commands used]
59
137
  Screenshot: [path]
60
138
  Result: PASS / FAIL (reason)
61
139
  Server cleanup: confirmed
140
+ Browser cleanup: confirmed
62
141
  ```
63
142
 
64
143
  If verification fails, log the failure details but continue to commit. Failures do NOT block the commit, but you MUST attempt verification and MUST clean up the dev server.
@@ -2,6 +2,13 @@
2
2
 
3
3
  **Build artifacts rule** (passed to Dev): After any build/compile command (`go build`, `npm run build`, `tsc`, etc.), ensure the output binary or build directory is in `.gitignore`. Never commit compiled binaries, build output, or generated artifacts.
4
4
 
5
+ **Dependency version gate (BLOCKING — pass to Dev agent)**: Before running ANY package install command (`npm install`, `pip install`, `cargo build`, `go mod tidy`, `bundle install`, etc.):
6
+ 1. Every version number in the dependency manifest MUST be verified against the real registry (see Context Budget Rules §9)
7
+ 2. If a scaffold tool generated a `package.json` / `requirements.txt` / etc., verify the versions it wrote too — scaffold tools can emit outdated versions
8
+ 3. Do NOT proceed with install until all versions are confirmed real. Violation = wasted timeout cycles that can crash the session
9
+
10
+ **Scaffold file rule (pass to Dev agent)**: After running any init/scaffold command, record generated files in context-snapshot.md under `### Scaffold Files (do not re-read)`. Never re-read these files — their content is standard boilerplate (see Context Budget Rules §8). When spawning subagents, explicitly list scaffold files so they skip reading them.
11
+
5
12
  **Spawn Agent**:
6
13
  | Parameter | Value |
7
14
  |-----------|-------|
@@ -2,6 +2,13 @@
2
2
 
3
3
  **Build artifacts rule** (passed to Dev): After any build/compile command (`go build`, `npm run build`, `tsc`, etc.), ensure the output binary or build directory is in `.gitignore`. Never commit compiled binaries, build output, or generated artifacts.
4
4
 
5
+ **Dependency version gate (BLOCKING — pass to Dev agent)**: Before running ANY package install command (`npm install`, `pip install`, `cargo build`, `go mod tidy`, `bundle install`, etc.):
6
+ 1. Every version number in the dependency manifest MUST be verified against the real registry (see Context Budget Rules §9)
7
+ 2. If a scaffold tool generated a `package.json` / `requirements.txt` / etc., verify the versions it wrote too — scaffold tools can emit outdated versions
8
+ 3. Do NOT proceed with install until all versions are confirmed real. Violation = wasted timeout cycles that can crash the session
9
+
10
+ **Scaffold file rule (pass to Dev agent)**: After running any init/scaffold command, record generated files in context-snapshot.md under `### Scaffold Files (do not re-read)`. Never re-read these files — their content is standard boilerplate (see Context Budget Rules §8). When spawning subagents, explicitly list scaffold files so they skip reading them.
11
+
5
12
  Before spawning Dev, check plan.md Tasks section:
6
13
  ```bash
7
14
  grep -c '^\- \[ \]' .prizmkit/specs/{{FEATURE_SLUG}}/plan.md 2>/dev/null || true
@@ -7,6 +7,13 @@ grep -q '^/binary-name$' .gitignore || echo '/binary-name' >> .gitignore
7
7
  ```
8
8
  Never commit compiled binaries, build output, or generated artifacts.
9
9
 
10
+ **Dependency version gate (BLOCKING)**: Before running ANY package install command (`npm install`, `pip install`, `cargo build`, `go mod tidy`, `bundle install`, etc.):
11
+ 1. Every version number in your dependency manifest MUST be verified against the real registry (see Context Budget Rules §9)
12
+ 2. If you used a scaffold tool that generated a `package.json` / `requirements.txt` / etc., verify the versions it wrote too — scaffold tools can emit outdated versions
13
+ 3. Do NOT proceed with install until all versions are confirmed real. Violation = wasted timeout cycles
14
+
15
+ **Scaffold file rule**: After running any init/scaffold command, record generated files in context-snapshot.md under `### Scaffold Files (do not re-read)`. Never re-read these files — their content is standard boilerplate (see Context Budget Rules §8).
16
+
10
17
  **3a.** Detect test commands and record baseline:
11
18
 
12
19
  You know this project's tech stack. Identify ALL test commands that apply (e.g., `go test ./...`, `npm test`, `cargo test`, `pytest`, `make test`, etc.). Record them as `TEST_CMDS`. Then record baseline:
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.23",
2
+ "version": "1.1.24",
3
3
  "skills": {
4
4
  "prizm-kit": {
5
5
  "description": "Full-lifecycle dev toolkit. Covers spec-driven development, Prizm context docs, code quality, debugging, deployment, and knowledge management.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.1.23",
3
+ "version": "1.1.24",
4
4
  "description": "Create a new PrizmKit-powered project with clean initialization — no framework dev files, just what you need.",
5
5
  "type": "module",
6
6
  "bin": {