prizmkit 1.0.151 → 1.0.153

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.0.151",
3
- "bundledAt": "2026-04-01T01:52:30.515Z",
4
- "bundledFrom": "21236ab"
2
+ "frameworkVersion": "1.0.153",
3
+ "bundledAt": "2026-04-02T01:37:22.899Z",
4
+ "bundledFrom": "6fee0f0"
5
5
  }
@@ -8,15 +8,26 @@ set -euo pipefail
8
8
  # re-executed from scratch by the pipeline.
9
9
  #
10
10
  # Usage:
11
- # ./reset-feature.sh <feature-id> [options] [feature-list.json]
11
+ # ./reset-feature.sh <feature-id|range> [options] [feature-list.json]
12
+ #
13
+ # Feature selection:
14
+ # F-007 Single feature
15
+ # F-008:F-013 Range of features (inclusive)
16
+ # --auto-skipped All features with auto_skipped status
17
+ # --failed All features with failed status
18
+ # --stalled All non-completed features (failed + auto_skipped)
12
19
  #
13
20
  # Options:
14
21
  # --clean Also delete session history and .prizmkit/specs/{slug}/ artifacts
15
- # --run After reset, immediately retry the feature (calls retry-feature.sh)
22
+ # --run After reset, immediately retry via pipeline (only with single feature)
16
23
  #
17
24
  # Examples:
18
25
  # ./reset-feature.sh F-007 # Reset status only
19
26
  # ./reset-feature.sh F-007 --clean # Reset + delete artifacts
27
+ # ./reset-feature.sh F-008:F-013 --clean # Reset range
28
+ # ./reset-feature.sh --auto-skipped # Reset all auto_skipped
29
+ # ./reset-feature.sh --failed --clean # Reset all failed + clean
30
+ # ./reset-feature.sh --stalled --clean # Reset all non-completed
20
31
  # ./reset-feature.sh F-007 --clean --run # Reset + delete + retry
21
32
  # ./reset-feature.sh F-007 --clean my-features.json # Custom feature list
22
33
  # ============================================================
@@ -43,26 +54,48 @@ log_success() { echo -e "${GREEN}[OK]${NC} $*"; }
43
54
  # ============================================================
44
55
 
45
56
  FEATURE_ID=""
57
+ FEATURE_RANGE=""
46
58
  FEATURE_LIST=""
47
59
  DO_CLEAN=false
48
60
  DO_RUN=false
61
+ FILTER_MODE=""
49
62
 
50
63
  for arg in "$@"; do
51
64
  case "$arg" in
52
- --clean) DO_CLEAN=true ;;
53
- --run) DO_RUN=true ;;
54
- -h|--help) ;;
55
- F-*) FEATURE_ID="$arg" ;;
56
- *) FEATURE_LIST="$arg" ;;
65
+ --clean) DO_CLEAN=true ;;
66
+ --run) DO_RUN=true ;;
67
+ --auto-skipped) FILTER_MODE="auto_skipped" ;;
68
+ --failed) FILTER_MODE="failed" ;;
69
+ --stalled) FILTER_MODE="stalled" ;;
70
+ -h|--help)
71
+ echo "Usage: $0 <feature-id|range> [--clean] [--run] [--auto-skipped|--failed|--stalled] [feature-list.json]"
72
+ echo ""
73
+ echo " feature-id Single feature (e.g. F-007)"
74
+ echo " F-008:F-013 Range of features (inclusive)"
75
+ echo " --auto-skipped Reset all auto_skipped features"
76
+ echo " --failed Reset all failed features"
77
+ echo " --stalled Reset all non-completed (failed + auto_skipped)"
78
+ echo " --clean Delete session history and .prizmkit artifacts"
79
+ echo " --run Retry immediately after reset (single feature only)"
80
+ echo " feature-list.json Path to feature list (default: feature-list.json)"
81
+ exit 0
82
+ ;;
83
+ F-*:F-*|f-*:f-*) FEATURE_RANGE="$arg" ;;
84
+ F-*|f-*) FEATURE_ID="$arg" ;;
85
+ *) FEATURE_LIST="$arg" ;;
57
86
  esac
58
87
  done
59
88
 
60
- if [[ -z "$FEATURE_ID" ]]; then
61
- echo "Usage: $0 <feature-id> [--clean] [--run] [feature-list.json]"
89
+ if [[ -z "$FEATURE_ID" && -z "$FEATURE_RANGE" && -z "$FILTER_MODE" ]]; then
90
+ echo "Usage: $0 <feature-id|range> [--clean] [--run] [--auto-skipped|--failed|--stalled] [feature-list.json]"
62
91
  echo ""
63
- echo " feature-id Feature to reset (e.g. F-007)"
92
+ echo " feature-id Single feature (e.g. F-007)"
93
+ echo " F-008:F-013 Range of features (inclusive)"
94
+ echo " --auto-skipped Reset all auto_skipped features"
95
+ echo " --failed Reset all failed features"
96
+ echo " --stalled Reset all non-completed (failed + auto_skipped)"
64
97
  echo " --clean Delete session history and .prizmkit artifacts"
65
- echo " --run Retry the feature immediately after reset"
98
+ echo " --run Retry immediately after reset (single feature only)"
66
99
  echo " feature-list.json Path to feature list (default: feature-list.json)"
67
100
  exit 1
68
101
  fi
@@ -88,16 +121,90 @@ if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
88
121
  exit 1
89
122
  fi
90
123
 
91
- # Get feature info from feature list
92
- FEATURE_INFO=$(python3 -c "
124
+ # ============================================================
125
+ # Resolve feature IDs to process
126
+ # ============================================================
127
+
128
+ FEATURE_IDS=()
129
+
130
+ if [[ -n "$FILTER_MODE" ]]; then
131
+ # Filter by status from state/features/*/status.json
132
+ while IFS= read -r fid; do
133
+ [[ -n "$fid" ]] && FEATURE_IDS+=("$fid")
134
+ done < <(python3 -c "
135
+ import json, os, sys
136
+ state_dir = '$STATE_DIR'
137
+ filter_mode = '$FILTER_MODE'
138
+ features_dir = os.path.join(state_dir, 'features')
139
+ if not os.path.isdir(features_dir):
140
+ sys.exit(0)
141
+ for fid in sorted(os.listdir(features_dir)):
142
+ status_file = os.path.join(features_dir, fid, 'status.json')
143
+ if not os.path.isfile(status_file):
144
+ continue
145
+ with open(status_file) as f:
146
+ status = json.load(f).get('status', '')
147
+ if filter_mode == 'auto_skipped' and status == 'auto_skipped':
148
+ print(fid)
149
+ elif filter_mode == 'failed' and status == 'failed':
150
+ print(fid)
151
+ elif filter_mode == 'stalled' and status in ('failed', 'auto_skipped'):
152
+ print(fid)
153
+ " 2>/dev/null)
154
+
155
+ if [[ ${#FEATURE_IDS[@]} -eq 0 ]]; then
156
+ log_info "No features found with status: $FILTER_MODE"
157
+ exit 0
158
+ fi
159
+ log_info "Found ${#FEATURE_IDS[@]} feature(s) matching --$FILTER_MODE: ${FEATURE_IDS[*]}"
160
+
161
+ elif [[ -n "$FEATURE_RANGE" ]]; then
162
+ # Parse range F-NNN:F-MMM
163
+ RANGE_START="${FEATURE_RANGE%%:*}"
164
+ RANGE_END="${FEATURE_RANGE##*:}"
165
+ START_NUM=$(echo "$RANGE_START" | sed 's/[Ff]-//' | sed 's/^0*//')
166
+ END_NUM=$(echo "$RANGE_END" | sed 's/[Ff]-//' | sed 's/^0*//')
167
+
168
+ if [[ -z "$START_NUM" || -z "$END_NUM" || "$START_NUM" -gt "$END_NUM" ]]; then
169
+ log_error "Invalid range: $FEATURE_RANGE (start must be <= end)"
170
+ exit 1
171
+ fi
172
+
173
+ for ((i=START_NUM; i<=END_NUM; i++)); do
174
+ FEATURE_IDS+=("F-$(printf '%03d' "$i")")
175
+ done
176
+ log_info "Range $FEATURE_RANGE → ${FEATURE_IDS[*]}"
177
+
178
+ else
179
+ FEATURE_IDS=("$FEATURE_ID")
180
+ fi
181
+
182
+ # --run only works with single feature
183
+ if [[ "$DO_RUN" == true && ${#FEATURE_IDS[@]} -gt 1 ]]; then
184
+ log_warn "--run is only supported for single feature reset. Use './run.sh run' to resume pipeline after batch reset."
185
+ DO_RUN=false
186
+ fi
187
+
188
+ # ============================================================
189
+ # Process each feature
190
+ # ============================================================
191
+
192
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
193
+ RESET_COUNT=0
194
+ FAIL_COUNT=0
195
+
196
+ for CUR_FEATURE_ID in "${FEATURE_IDS[@]}"; do
197
+
198
+ # Get feature info from feature list
199
+ FEATURE_INFO=$(python3 -c "
93
200
  import json, sys, re
94
201
  with open('$FEATURE_LIST') as f:
95
202
  data = json.load(f)
96
203
  for feat in data.get('features', []):
97
- if feat.get('id') == '$FEATURE_ID':
204
+ if feat.get('id') == '$CUR_FEATURE_ID':
98
205
  title = feat.get('title', '')
99
206
  # Compute slug
100
- numeric = '$FEATURE_ID'.replace('F-', '').replace('f-', '').zfill(3)
207
+ numeric = '$CUR_FEATURE_ID'.replace('F-', '').replace('f-', '').zfill(3)
101
208
  slug = title.lower()
102
209
  slug = re.sub(r'[^a-z0-9\s-]', '', slug)
103
210
  slug = re.sub(r'[\s]+', '-', slug.strip())
@@ -107,103 +214,100 @@ for feat in data.get('features', []):
107
214
  sys.exit(0)
108
215
  sys.exit(1)
109
216
  " 2>/dev/null) || {
110
- log_error "Feature $FEATURE_ID not found in $FEATURE_LIST"
111
- exit 1
112
- }
113
-
114
- FEATURE_TITLE=$(echo "$FEATURE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['title'])")
115
- FEATURE_SLUG=$(echo "$FEATURE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['slug'])")
116
- FEATURE_STATUS=$(echo "$FEATURE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")
117
-
118
- # ============================================================
119
- # Show current state
120
- # ============================================================
217
+ log_warn "Feature $CUR_FEATURE_ID not found in $FEATURE_LIST — skipping"
218
+ FAIL_COUNT=$((FAIL_COUNT + 1))
219
+ continue
220
+ }
121
221
 
122
- echo ""
123
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
124
- echo -e "${BOLD} Reset: $FEATURE_ID — $FEATURE_TITLE${NC}"
125
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
222
+ FEATURE_TITLE=$(echo "$FEATURE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['title'])")
223
+ FEATURE_SLUG=$(echo "$FEATURE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['slug'])")
126
224
 
127
- # Read current status.json
128
- STATUS_FILE="$STATE_DIR/features/$FEATURE_ID/status.json"
129
- if [[ -f "$STATUS_FILE" ]]; then
130
- CURRENT_STATUS=$(python3 -c "import json; d=json.load(open('$STATUS_FILE')); print(d.get('status','?'))")
131
- CURRENT_RETRY=$(python3 -c "import json; d=json.load(open('$STATUS_FILE')); print(d.get('retry_count',0))")
132
- SESSION_COUNT=$(python3 -c "import json; d=json.load(open('$STATUS_FILE')); print(len(d.get('sessions',[])))")
133
- log_info "Current status: $CURRENT_STATUS (retry $CURRENT_RETRY, $SESSION_COUNT sessions)"
134
- else
135
- log_info "No status file found (never executed)"
136
- fi
225
+ # ── Show current state ──
226
+ echo ""
227
+ echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
228
+ echo -e "${BOLD} Reset: $CUR_FEATURE_ID $FEATURE_TITLE${NC}"
229
+ echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
137
230
 
138
- # Count artifacts
139
- SPECS_DIR="$(cd "$SCRIPT_DIR/.." 2>/dev/null && pwd)/.prizmkit/specs/$FEATURE_SLUG"
140
- SPECS_COUNT=0
141
- if [[ -d "$SPECS_DIR" ]]; then
142
- SPECS_COUNT=$(find "$SPECS_DIR" -type f 2>/dev/null | wc -l | tr -d ' ')
143
- log_info "PrizmKit artifacts: $SPECS_COUNT files in .prizmkit/specs/$FEATURE_SLUG/"
144
- fi
231
+ STATUS_FILE="$STATE_DIR/features/$CUR_FEATURE_ID/status.json"
232
+ if [[ -f "$STATUS_FILE" ]]; then
233
+ CURRENT_STATUS=$(python3 -c "import json; d=json.load(open('$STATUS_FILE')); print(d.get('status','?'))")
234
+ CURRENT_RETRY=$(python3 -c "import json; d=json.load(open('$STATUS_FILE')); print(d.get('retry_count',0))")
235
+ SESSION_COUNT=$(python3 -c "import json; d=json.load(open('$STATUS_FILE')); print(len(d.get('sessions',[])))")
236
+ log_info "Current status: $CURRENT_STATUS (retry $CURRENT_RETRY, $SESSION_COUNT sessions)"
237
+ else
238
+ log_info "No status file found (never executed)"
239
+ fi
145
240
 
146
- SESSIONS_DIR="$STATE_DIR/features/$FEATURE_ID/sessions"
147
- SESSIONS_COUNT=0
148
- if [[ -d "$SESSIONS_DIR" ]]; then
149
- SESSIONS_COUNT=$(find "$SESSIONS_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
150
- log_info "Session history: $SESSIONS_COUNT session(s)"
151
- fi
241
+ SPECS_DIR="$PROJECT_ROOT/.prizmkit/specs/$FEATURE_SLUG"
242
+ SPECS_COUNT=0
243
+ if [[ -d "$SPECS_DIR" ]]; then
244
+ SPECS_COUNT=$(find "$SPECS_DIR" -type f 2>/dev/null | wc -l | tr -d ' ')
245
+ log_info "PrizmKit artifacts: $SPECS_COUNT files in .prizmkit/specs/$FEATURE_SLUG/"
246
+ fi
152
247
 
153
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
248
+ SESSIONS_DIR="$STATE_DIR/features/$CUR_FEATURE_ID/sessions"
249
+ SESSIONS_COUNT=0
250
+ if [[ -d "$SESSIONS_DIR" ]]; then
251
+ SESSIONS_COUNT=$(find "$SESSIONS_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
252
+ log_info "Session history: $SESSIONS_COUNT session(s)"
253
+ fi
154
254
 
155
- # ============================================================
156
- # Execute reset
157
- # ============================================================
255
+ echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
158
256
 
159
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
257
+ # ── Execute reset ──
258
+ if [[ "$DO_CLEAN" == true ]]; then
259
+ log_info "Cleaning $CUR_FEATURE_ID (reset + delete artifacts)..."
260
+ RESULT=$(python3 "$SCRIPTS_DIR/update-feature-status.py" \
261
+ --feature-list "$FEATURE_LIST" \
262
+ --state-dir "$STATE_DIR" \
263
+ --feature-id "$CUR_FEATURE_ID" \
264
+ --feature-slug "$FEATURE_SLUG" \
265
+ --project-root "$PROJECT_ROOT" \
266
+ --action clean 2>&1)
267
+ else
268
+ log_info "Resetting $CUR_FEATURE_ID status..."
269
+ RESULT=$(python3 "$SCRIPTS_DIR/update-feature-status.py" \
270
+ --feature-list "$FEATURE_LIST" \
271
+ --state-dir "$STATE_DIR" \
272
+ --feature-id "$CUR_FEATURE_ID" \
273
+ --action reset 2>&1)
274
+ fi
160
275
 
161
- if [[ "$DO_CLEAN" == true ]]; then
162
- log_info "Cleaning $FEATURE_ID (reset + delete artifacts)..."
163
- RESULT=$(python3 "$SCRIPTS_DIR/update-feature-status.py" \
164
- --feature-list "$FEATURE_LIST" \
165
- --state-dir "$STATE_DIR" \
166
- --feature-id "$FEATURE_ID" \
167
- --feature-slug "$FEATURE_SLUG" \
168
- --project-root "$PROJECT_ROOT" \
169
- --action clean 2>&1)
170
- else
171
- log_info "Resetting $FEATURE_ID status..."
172
- RESULT=$(python3 "$SCRIPTS_DIR/update-feature-status.py" \
173
- --feature-list "$FEATURE_LIST" \
174
- --state-dir "$STATE_DIR" \
175
- --feature-id "$FEATURE_ID" \
176
- --action reset 2>&1)
177
- fi
276
+ # Check for errors
277
+ if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); sys.exit(0 if 'error' not in d else 1)" 2>/dev/null; then
278
+ RESET_COUNT=$((RESET_COUNT + 1))
279
+ if [[ "$DO_CLEAN" == true ]]; then
280
+ log_success "$CUR_FEATURE_ID cleaned: status → pending, $SESSIONS_COUNT session(s) deleted, $SPECS_COUNT artifact(s) deleted"
281
+ else
282
+ log_success "$CUR_FEATURE_ID reset: status → pending, retry count → 0"
283
+ fi
284
+ else
285
+ ERROR_MSG=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('error','unknown'))" 2>/dev/null || echo "$RESULT")
286
+ log_error "Reset $CUR_FEATURE_ID failed: $ERROR_MSG"
287
+ FAIL_COUNT=$((FAIL_COUNT + 1))
288
+ fi
178
289
 
179
- # Check for errors
180
- if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); sys.exit(0 if 'error' not in d else 1)" 2>/dev/null; then
181
- : # no error
182
- else
183
- ERROR_MSG=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('error','unknown'))" 2>/dev/null || echo "$RESULT")
184
- log_error "Reset failed: $ERROR_MSG"
185
- exit 1
186
- fi
290
+ done
187
291
 
188
292
  # ============================================================
189
293
  # Summary
190
294
  # ============================================================
191
295
 
192
296
  echo ""
193
- if [[ "$DO_CLEAN" == true ]]; then
194
- log_success "$FEATURE_ID cleaned: status → pending, $SESSIONS_COUNT session(s) deleted, $SPECS_COUNT artifact(s) deleted"
195
- else
196
- log_success "$FEATURE_ID reset: status → pending, retry count → 0"
197
- fi
297
+ echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
298
+ echo -e "${BOLD} Reset complete: $RESET_COUNT succeeded, $FAIL_COUNT failed${NC}"
299
+ echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
198
300
 
199
301
  echo ""
200
302
  echo -e "${BOLD}Next steps:${NC}"
201
- if [[ "$DO_RUN" == true ]]; then
202
- log_info "Auto-retrying $FEATURE_ID..."
303
+ if [[ "$DO_RUN" == true && ${#FEATURE_IDS[@]} -eq 1 ]]; then
304
+ log_info "Auto-retrying ${FEATURE_IDS[0]}..."
203
305
  echo ""
204
- exec "$SCRIPT_DIR/retry-feature.sh" "$FEATURE_ID" "$FEATURE_LIST"
306
+ exec "$SCRIPT_DIR/retry-feature.sh" "${FEATURE_IDS[0]}" "$FEATURE_LIST"
205
307
  else
206
- log_info " ./dev-pipeline/retry-feature.sh $FEATURE_ID # Retry once"
207
- log_info " ./dev-pipeline/run.sh run feature-list.json # Resume pipeline"
308
+ log_info " ./dev-pipeline/run.sh run feature-list.json # Resume pipeline from first pending"
309
+ if [[ ${#FEATURE_IDS[@]} -eq 1 ]]; then
310
+ log_info " ./dev-pipeline/retry-feature.sh ${FEATURE_IDS[0]} # Retry single feature"
311
+ fi
208
312
  fi
209
313
  echo ""
@@ -987,6 +987,15 @@ print(count)
987
987
  fi
988
988
  echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
989
989
 
990
+ # Commit dirty working tree before starting feature
991
+ local _dirty_files=""
992
+ _dirty_files=$(git -C "$_proj_root" status --porcelain 2>/dev/null || true)
993
+ if [[ -n "$_dirty_files" ]]; then
994
+ log_info "Dirty working tree detected — committing before $feature_id..."
995
+ git -C "$_proj_root" add -A 2>/dev/null || true
996
+ git -C "$_proj_root" commit --no-verify -m "ready for run $feature_id" 2>/dev/null || true
997
+ fi
998
+
990
999
  # Create per-feature dev branch
991
1000
  local _feature_branch="${DEV_BRANCH:-dev/${feature_id}-$(date +%Y%m%d%H%M)}"
992
1001
  if branch_create "$_proj_root" "$_feature_branch" "$_ORIGINAL_BRANCH"; then
@@ -41,7 +41,7 @@ You are running in headless mode with a FINITE context window. Exceeding it will
41
41
  4. **One task at a time** — In Phase 3 (implement), complete and test one task before starting the next.
42
42
  5. **Minimize tool output** — When running commands, use `| head -20` or `| tail -20` to limit output. Never dump entire test suites or logs.
43
43
  6. **No intermediate commits** — Do NOT run `git add`/`git commit` during Phase 1-3. All changes are committed once at the end in Phase 4 via `/prizmkit-committer`.
44
- 7. **Capture test output once** — When running the test suite, 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.
44
+ 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.
45
45
 
46
46
  ---
47
47
 
@@ -130,14 +130,11 @@ grep -q '^/binary-name$' .gitignore || echo '/binary-name' >> .gitignore
130
130
  ```
131
131
  Never commit compiled binaries, build output, or generated artifacts.
132
132
 
133
- **3a.** Detect the test command and record baseline:
134
- ```bash
135
- # Try in order, use first that exits 0
136
- node --test tests/**/*.test.js 2>&1 | tail -3 # Node built-in
137
- npm test 2>&1 | tail -3 # npm fallback
138
- ```
139
- Record the working command as `TEST_CMD`. Then record baseline failures (if any):
133
+ **3a.** Detect test commands and record baseline:
134
+
135
+ 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` (one or more commands). Then record baseline:
140
136
  ```bash
137
+ # Run each test command, capture output
141
138
  $TEST_CMD 2>&1 | tee /tmp/test-baseline.txt | tail -20
142
139
  ```
143
140
 
@@ -191,6 +188,43 @@ You MUST execute this phase. Do NOT skip it. Do NOT mark it as completed without
191
188
  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.
192
189
  {{END_IF_BROWSER_INTERACTION}}
193
190
 
191
+ ### Phase 3.8: Local Deploy Verification
192
+
193
+ You just implemented this feature — you know the project's tech stack and build tools.
194
+
195
+ 1. **Build**: Run the project's build/compile commands. If a required tool is missing, install it first.
196
+ 2. **Fix**: If build fails with code errors (type errors, missing imports, config issues), fix them (max 2 rounds), then re-verify.
197
+ 3. **Assess and record** — append to context-snapshot.md:
198
+ - **ALL builds pass** → `## Deploy Verification: PASS` — proceed to commit
199
+ - **Some builds fail with fixable errors** → fix and re-verify (already handled in step 2)
200
+ - **Cannot build locally** (missing system-level deps you cannot install) → Generate `DEPLOY.md` with:
201
+ ```
202
+ # Local Development Setup
203
+
204
+ ## Prerequisites
205
+ - [tool]: [install instruction]
206
+
207
+ ## Build Steps
208
+ 1. [exact command]
209
+
210
+ ## Run / Dev Mode
211
+ [exact command to start the app locally]
212
+
213
+ ## Verify
214
+ [how to confirm the app is running correctly]
215
+ ```
216
+ Record: `## Deploy Verification: PARTIAL — see DEPLOY.md for missing prerequisites`
217
+
218
+ Deploy verification does NOT block the commit, but you MUST attempt it.
219
+
220
+ **Step 4 — Smoke test** (only if build passed and project can be started):
221
+ 1. Start the project locally (e.g., `make dev`, `npm start`, `go run .`, etc.)
222
+ 2. Verify basic functionality: hit key endpoints, check health routes, confirm the UI loads
223
+ 3. Stop the server process you started — do NOT leave it running
224
+ 4. Record smoke test results in `## Deploy Verification` section
225
+
226
+ If the project cannot be started locally (e.g., requires external services, databases, credentials), skip the smoke test and note why.
227
+
194
228
  ### Phase 4: Architecture Sync & Commit (SINGLE COMMIT)
195
229
 
196
230
  **4a.** Run `/prizmkit-retrospective` — maintains `.prizm-docs/` (architecture index):
@@ -41,7 +41,7 @@ You are running in headless mode with a FINITE context window. Exceeding it will
41
41
  4. **One task at a time** — In Phase 4 (implement), complete and test one task before starting the next.
42
42
  5. **Minimize tool output** — When running commands, use `| head -20` or `| tail -20` to limit output. Never dump entire test suites or logs.
43
43
  6. **No intermediate commits** — Do NOT run `git add`/`git commit` during Phase 1-5. All changes are committed once at the end in Phase 6 via `/prizmkit-committer`.
44
- 7. **Capture test output once** — When running the test suite, 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.
44
+ 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.
45
45
 
46
46
  ---
47
47
 
@@ -82,6 +82,16 @@ If any agent times out:
82
82
  Check `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — if exists, skip Phase 1 and proceed to Phase {{RESUME_PHASE}}.
83
83
  {{END_IF_RESUME}}
84
84
 
85
+ ### Phase 0.5: Detect Test Commands
86
+
87
+ 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:
88
+ ```bash
89
+ $TEST_CMD 2>&1 | tee /tmp/test-baseline.txt | tail -20
90
+ ```
91
+ Save pre-existing failing tests as `BASELINE_FAILURES`.
92
+
93
+ > **⚠️ Test Output Rule**: Always capture test output to a temp file (`tee /tmp/test-out.txt`). Then grep the file instead of re-running the suite.
94
+
85
95
  ### Phase 1: Build Context Snapshot (you, the orchestrator)
86
96
 
87
97
  **Check for previous failure log:**
@@ -302,6 +312,43 @@ You MUST execute this phase. Do NOT skip it. Do NOT mark it as completed without
302
312
  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.
303
313
  {{END_IF_BROWSER_INTERACTION}}
304
314
 
315
+ ### Phase 5.8: Local Deploy Verification
316
+
317
+ You just implemented this feature — you know the project's tech stack and build tools.
318
+
319
+ 1. **Build**: Run the project's build/compile commands. If a required tool is missing, install it first.
320
+ 2. **Fix**: If build fails with code errors (type errors, missing imports, config issues), fix them (max 2 rounds), then re-verify.
321
+ 3. **Assess and record** — append to context-snapshot.md:
322
+ - **ALL builds pass** → `## Deploy Verification: PASS` — proceed to commit
323
+ - **Some builds fail with fixable errors** → fix and re-verify (already handled in step 2)
324
+ - **Cannot build locally** (missing system-level deps you cannot install) → Generate `DEPLOY.md` with:
325
+ ```
326
+ # Local Development Setup
327
+
328
+ ## Prerequisites
329
+ - [tool]: [install instruction]
330
+
331
+ ## Build Steps
332
+ 1. [exact command]
333
+
334
+ ## Run / Dev Mode
335
+ [exact command to start the app locally]
336
+
337
+ ## Verify
338
+ [how to confirm the app is running correctly]
339
+ ```
340
+ Record: `## Deploy Verification: PARTIAL — see DEPLOY.md for missing prerequisites`
341
+
342
+ Deploy verification does NOT block the commit, but you MUST attempt it.
343
+
344
+ **Step 4 — Smoke test** (only if build passed and project can be started):
345
+ 1. Start the project locally (e.g., `make dev`, `npm start`, `go run .`, etc.)
346
+ 2. Verify basic functionality: hit key endpoints, check health routes, confirm the UI loads
347
+ 3. Stop the server process you started — do NOT leave it running
348
+ 4. Record smoke test results in `## Deploy Verification` section
349
+
350
+ If the project cannot be started locally (e.g., requires external services, databases, credentials), skip the smoke test and note why.
351
+
305
352
  ### Phase 6: Architecture Sync & Commit (SINGLE COMMIT)
306
353
 
307
354
  **6a.** Run `/prizmkit-retrospective` — maintains `.prizm-docs/` (architecture index):
@@ -75,23 +75,18 @@ If any agent times out:
75
75
  - **CP-0**: Verify `.prizm-docs/root.prizm`, `.prizmkit/config.json` exist
76
76
  {{END_IF_INIT_NEEDED}}
77
77
  {{IF_INIT_DONE}}
78
- ### Phase 0: Record Test Baseline & Detect Test Command
78
+ ### Phase 0: Record Test Baseline & Detect Test Commands
79
79
 
80
- **Step 1 — Detect the correct test command** (run once, save as `TEST_CMD`):
81
- ```bash
82
- # Try in order, use the first one that exits 0
83
- node --test tests/**/*.test.js 2>&1 | tail -3 # Node built-in
84
- npm test 2>&1 | tail -3 # npm script fallback
85
- ```
86
- Record the working command as `TEST_CMD`. If both fail, record `TEST_CMD="npm test"` as default.
80
+ **Step 1 — Detect test commands**: 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`.
87
81
 
88
82
  **Step 2 — Record pre-existing failure baseline**:
89
83
  ```bash
84
+ # Run each test command, capture output
90
85
  $TEST_CMD 2>&1 | tee /tmp/test-baseline.txt | tail -20
91
86
  ```
92
87
  Save the list of **pre-existing failing tests** (if any) as `BASELINE_FAILURES`. These are known failures that existed before this session — Dev must NOT be blamed for them, but must list them in COMPLETION_SIGNAL.
93
88
 
94
- > **⚠️ Test Output Rule**: Always capture test output to a temp file (`tee /tmp/test-out.txt`). Then grep the file instead of re-running the suite. Never run `npm test` multiple times just to apply different grep filters to the output.
89
+ > **⚠️ Test Output Rule**: Always capture test output to a temp file (`tee /tmp/test-out.txt`). Then grep the file instead of re-running the suite.
95
90
  {{END_IF_INIT_DONE}}
96
91
 
97
92
  ### Step 1: Initialize
@@ -400,6 +395,42 @@ You MUST execute this phase. Do NOT skip it. Do NOT mark it as completed without
400
395
  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.
401
396
  {{END_IF_BROWSER_INTERACTION}}
402
397
 
398
+ ### Phase 5.8: Local Deploy Verification
399
+
400
+ You just implemented this feature — you know the project's tech stack and build tools.
401
+
402
+ 1. **Build**: Run the project's build/compile commands. If a required tool is missing, install it first.
403
+ 2. **Fix**: If build fails with code errors (type errors, missing imports, config issues), fix them (max 2 rounds), then re-verify.
404
+ 3. **Assess and record** — append to context-snapshot.md:
405
+ - **ALL builds pass** → `## Deploy Verification: PASS` — proceed to commit
406
+ - **Some builds fail with fixable errors** → fix and re-verify (already handled in step 2)
407
+ - **Cannot build locally** (missing system-level deps you cannot install) → Generate `DEPLOY.md` with:
408
+ ```
409
+ # Local Development Setup
410
+
411
+ ## Prerequisites
412
+ - [tool]: [install instruction]
413
+
414
+ ## Build Steps
415
+ 1. [exact command]
416
+
417
+ ## Run / Dev Mode
418
+ [exact command to start the app locally]
419
+
420
+ ## Verify
421
+ [how to confirm the app is running correctly]
422
+ ```
423
+ Record: `## Deploy Verification: PARTIAL — see DEPLOY.md for missing prerequisites`
424
+
425
+ Deploy verification does NOT block the commit, but you MUST attempt it.
426
+
427
+ **Step 4 — Smoke test** (only if build passed and project can be started):
428
+ 1. Start the project locally (e.g., `make dev`, `npm start`, `go run .`, etc.)
429
+ 2. Verify basic functionality: hit key endpoints, check health routes, confirm the UI loads
430
+ 3. Stop the server process you started — do NOT leave it running
431
+ 4. Record smoke test results in `## Deploy Verification` section
432
+
433
+ If the project cannot be started locally (e.g., requires external services, databases, credentials), skip the smoke test and note why.
403
434
 
404
435
  ### Phase 6: Retrospective & Commit (SINGLE COMMIT) — DO NOT SKIP
405
436
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.151",
2
+ "version": "1.0.153",
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.0.151",
3
+ "version": "1.0.153",
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": {