prizmkit 1.0.66 → 1.0.68

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.66",
3
- "bundledAt": "2026-03-19T12:01:20.770Z",
4
- "bundledFrom": "913a1b3"
2
+ "frameworkVersion": "1.0.68",
3
+ "bundledAt": "2026-03-20T07:41:55.236Z",
4
+ "bundledFrom": "d0d6a3c"
5
5
  }
@@ -30,9 +30,38 @@ export async function generateSettings(targetRoot, options = {}) {
30
30
  if (!existing.permissions.allow) existing.permissions.allow = [];
31
31
 
32
32
  const prizmkitPermissions = [
33
+ // Core tools
33
34
  'Bash(python3 *)',
34
35
  'Bash(git *)',
35
36
  'Bash(jq *)',
37
+ // Common dev commands
38
+ 'Bash(node *)',
39
+ 'Bash(npm *)',
40
+ 'Bash(npx *)',
41
+ // File operations
42
+ 'Bash(cat *)',
43
+ 'Bash(ls *)',
44
+ 'Bash(pwd)',
45
+ 'Bash(mkdir *)',
46
+ 'Bash(cp *)',
47
+ 'Bash(mv *)',
48
+ 'Bash(rm *)',
49
+ 'Bash(chmod *)',
50
+ 'Bash(touch *)',
51
+ // Search & text tools
52
+ 'Bash(find *)',
53
+ 'Bash(grep *)',
54
+ 'Bash(sed *)',
55
+ 'Bash(awk *)',
56
+ 'Bash(head *)',
57
+ 'Bash(tail *)',
58
+ 'Bash(wc *)',
59
+ 'Bash(sort *)',
60
+ 'Bash(echo *)',
61
+ // Script execution
62
+ 'Bash(./*)',
63
+ 'Bash(bash *)',
64
+ 'Bash(sh *)',
36
65
  ];
37
66
 
38
67
  if (options.pipeline) {
@@ -605,12 +605,12 @@ main() {
605
605
  # Track current session (atomic write via temp file)
606
606
  python3 -c "
607
607
  import json, sys, os
608
- from datetime import datetime
608
+ from datetime import datetime, timezone
609
609
  bug_id, session_id, state_dir = sys.argv[1], sys.argv[2], sys.argv[3]
610
610
  data = {
611
611
  'bug_id': bug_id,
612
612
  'session_id': session_id,
613
- 'started_at': datetime.now(datetime.UTC).strftime('%Y-%m-%dT%H:%M:%SZ')
613
+ 'started_at': datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
614
614
  }
615
615
  target = os.path.join(state_dir, 'current-session.json')
616
616
  tmp = target + '.tmp'
@@ -240,15 +240,89 @@ with open(p, 'w', encoding='utf-8') as f:
240
240
 
241
241
  log_info "Session result: $session_status"
242
242
 
243
+ # Write lightweight session summary for post-session inspection
244
+ local feature_slug
245
+ feature_slug=$(python3 -c "
246
+ import json, re, sys
247
+ flist, fid = sys.argv[1], sys.argv[2]
248
+ with open(flist) as f:
249
+ data = json.load(f)
250
+ for feat in data.get('features', []):
251
+ if feat.get('id') == fid:
252
+ fnum = feat['id'].replace('F-', '').replace('f-', '').zfill(3)
253
+ title = feat.get('title', '').lower()
254
+ title = re.sub(r'[^a-z0-9\s-]', '', title)
255
+ title = re.sub(r'[\s]+', '-', title.strip())
256
+ title = re.sub(r'-+', '-', title).strip('-')
257
+ print(f'{fnum}-{title}')
258
+ sys.exit(0)
259
+ sys.exit(1)
260
+ " "$feature_list" "$feature_id" 2>/dev/null) || {
261
+ log_warn "Could not resolve feature slug for $feature_id — session summary and artifact validation will be skipped"
262
+ feature_slug=""
263
+ }
264
+
265
+ if [[ -n "$feature_slug" ]]; then
266
+ local project_root_for_summary
267
+ project_root_for_summary="$(cd "$SCRIPT_DIR/.." && pwd)"
268
+ local summary_path="$project_root_for_summary/.prizmkit/specs/${feature_slug}/session-summary.json"
269
+ mkdir -p "$(dirname "$summary_path")"
270
+ local session_start_time
271
+ session_start_time=$(python3 -c "
272
+ import json, sys, os
273
+ p = os.path.join(sys.argv[1], 'current-session.json')
274
+ if os.path.isfile(p):
275
+ with open(p) as f: print(json.load(f).get('started_at', ''))
276
+ else: print('')
277
+ " "$STATE_DIR" 2>/dev/null) || session_start_time=""
278
+ local exec_tier
279
+ exec_tier=$(python3 -c "
280
+ import json, sys, os
281
+ p = sys.argv[1]
282
+ if os.path.isfile(p):
283
+ with open(p) as f: print(json.load(f).get('exec_tier', ''))
284
+ else: print('')
285
+ " "$session_dir/session-status.json" 2>/dev/null) || exec_tier=""
286
+ cat > "$summary_path" <<SUMMARY
287
+ {
288
+ "feature_id": "$feature_id",
289
+ "session_id": "$session_id",
290
+ "status": "$session_status",
291
+ "started_at": "$session_start_time",
292
+ "completed_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
293
+ "tier": "$exec_tier"
294
+ }
295
+ SUMMARY
296
+ fi
297
+
298
+ # Validate key artifacts exist after successful session
299
+ if [[ "$session_status" == "success" && -n "$feature_slug" ]]; then
300
+ local project_root_for_artifacts
301
+ project_root_for_artifacts="$(cd "$SCRIPT_DIR/.." && pwd)"
302
+ local context_snapshot="$project_root_for_artifacts/.prizmkit/specs/${feature_slug}/context-snapshot.md"
303
+ local plan_file="$project_root_for_artifacts/.prizmkit/specs/${feature_slug}/plan.md"
304
+
305
+ if [[ ! -f "$context_snapshot" ]]; then
306
+ log_warn "ARTIFACT_MISSING: context-snapshot.md not found at $context_snapshot"
307
+ fi
308
+ if [[ ! -f "$plan_file" ]]; then
309
+ log_warn "ARTIFACT_MISSING: plan.md not found at $plan_file"
310
+ fi
311
+ fi
312
+
243
313
  # Update feature status
244
- python3 "$SCRIPTS_DIR/update-feature-status.py" \
314
+ local update_output
315
+ update_output=$(python3 "$SCRIPTS_DIR/update-feature-status.py" \
245
316
  --feature-list "$feature_list" \
246
317
  --state-dir "$STATE_DIR" \
247
318
  --feature-id "$feature_id" \
248
319
  --session-status "$session_status" \
249
320
  --session-id "$session_id" \
250
321
  --max-retries "$max_retries" \
251
- --action update >/dev/null 2>&1 || true
322
+ --action update 2>&1) || {
323
+ log_error "Failed to update feature status: $update_output"
324
+ log_error "feature-list.json may be out of sync. Manual intervention needed."
325
+ }
252
326
 
253
327
  # Return status via global variable (avoids $() swallowing stdout)
254
328
  _SPAWN_RESULT="$session_status"
@@ -709,6 +783,16 @@ main() {
709
783
  exit 1
710
784
  fi
711
785
 
786
+ # Validate feature-list.json is at project root
787
+ local fl_dir
788
+ fl_dir="$(cd "$(dirname "$feature_list")" && pwd)"
789
+ local project_root
790
+ project_root="$(pwd)"
791
+ if [[ "$fl_dir" != "$project_root" ]]; then
792
+ log_warn "feature-list.json is not at project root ($project_root), found at $fl_dir"
793
+ log_warn "Pipeline expects feature-list.json at project root. Proceeding but results may be unstable."
794
+ fi
795
+
712
796
  check_dependencies
713
797
  run_log_cleanup
714
798
 
@@ -883,12 +967,12 @@ for f in data.get('stuck_features', []):
883
967
  # Update current session tracking (atomic write via temp file)
884
968
  python3 -c "
885
969
  import json, sys, os
886
- from datetime import datetime
970
+ from datetime import datetime, timezone
887
971
  feature_id, session_id, state_dir = sys.argv[1], sys.argv[2], sys.argv[3]
888
972
  data = {
889
973
  'feature_id': feature_id,
890
974
  'session_id': session_id,
891
- 'started_at': datetime.now(datetime.UTC).strftime('%Y-%m-%dT%H:%M:%SZ')
975
+ 'started_at': datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
892
976
  }
893
977
  target = os.path.join(state_dir, 'current-session.json')
894
978
  tmp = target + '.tmp'
@@ -300,6 +300,15 @@ def main():
300
300
  print(json.dumps(output, indent=2, ensure_ascii=False))
301
301
  sys.exit(1)
302
302
 
303
+ # Warn if feature-list.json is not at project root
304
+ feature_list_dir = os.path.dirname(os.path.abspath(args.feature_list))
305
+ indicators = ['.git', 'package.json', '.prizmkit']
306
+ is_at_root = any(os.path.exists(os.path.join(feature_list_dir, i)) for i in indicators)
307
+ if not is_at_root:
308
+ sys.stderr.write(
309
+ "Warning: feature-list.json may not be at project root: {}\n".format(feature_list_dir)
310
+ )
311
+
303
312
  # Validate schema
304
313
  schema_errors = validate_schema(data)
305
314
  if schema_errors:
@@ -99,14 +99,14 @@ Files changed/created: [list]
99
99
  Key decisions: [list]
100
100
  ```
101
101
 
102
- ### Phase 4: Self-Review
102
+ ### Phase 4: Code Review (mandatory)
103
103
 
104
104
  1. Re-read acceptance criteria from Section 1 of context-snapshot.md
105
- 2. Run the full test suite
106
- 3. Check error handling and edge cases
107
- 4. Fix any issues found
105
+ 2. Run `/prizmkit-code-review` verify all acceptance criteria, check code quality and correctness
106
+ 3. Run the full test suite
107
+ 4. If review uncovers issues, fix them (max 2 fix rounds)
108
108
 
109
- **CP-2**: All acceptance criteria met, tests pass.
109
+ **CP-2**: All acceptance criteria met, tests pass, code review passed.
110
110
 
111
111
  ### Phase 4.5: Memory Maintenance (mandatory before commit)
112
112
 
@@ -183,7 +183,8 @@ Re-check `git status --short` and ensure it is empty before exiting.
183
183
 
184
184
  ## Reminders
185
185
 
186
- - Tier 1: you do everything — no subagents, no TeamCreate
186
+ - Tier 1: you handle everything directly invoke skills yourself (no subagents needed for simple tasks)
187
+ - MANDATORY skills: `/prizmkit-code-review`, `/prizmkit-retrospective`, `/prizmkit-committer` — never skip these
187
188
  - Build context-snapshot.md FIRST; use it throughout instead of re-reading files
188
189
  - ALWAYS write session-status.json before exiting
189
190
  - `/prizmkit-committer` is mandatory — do NOT skip the commit phase, and do NOT replace it with manual git commit commands
@@ -101,7 +101,9 @@ Spawn Dev subagent (Agent tool, subagent_type="prizm-dev-team-dev", run_in_backg
101
101
  Prompt:
102
102
  > "Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
103
103
  >
104
- > 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — all project context, source files, and tests are embedded there. Do NOT re-read individual source files.
104
+ > **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST.
105
+ > This file contains ALL source code and context. Do NOT re-read individual source files.
106
+ > 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — all project context, source files, and tests are embedded there.
105
107
  > 2. Read `.prizmkit/specs/{{FEATURE_SLUG}}/plan.md` (including Tasks section).
106
108
  > 3. Implement task-by-task using TDD. Mark each task `[x]` in plan.md Tasks section immediately after completion.
107
109
  > 4. After ALL tasks complete, append an 'Implementation Log' section to `context-snapshot.md`:
@@ -119,7 +121,9 @@ Spawn Reviewer subagent (Agent tool, subagent_type="prizm-dev-team-reviewer", ru
119
121
  Prompt:
120
122
  > "Read {{REVIEWER_SUBAGENT_PATH}}. Review feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
121
123
  >
122
- > 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST:
124
+ > **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST.
125
+ > This file contains ALL source code and context. Do NOT re-read individual source files.
126
+ > 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
123
127
  > - Section 1: acceptance criteria to verify against
124
128
  > - Section 4: original source files (before changes)
125
129
  > - 'Implementation Log': what Dev changed
@@ -222,7 +222,9 @@ Append the following to the Dev agent prompt:
222
222
 
223
223
  Prompt:
224
224
  > "Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}) using TDD.
225
- > 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — all source files and context are there. Do NOT re-read individual source files.
225
+ > **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST.
226
+ > This file contains ALL source code and context. Do NOT re-read individual source files.
227
+ > 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — all source files and context are there.
226
228
  > 2. Read `plan.md` (including Tasks section) from `.prizmkit/specs/{{FEATURE_SLUG}}/`.
227
229
  > 3. Implement task-by-task. Mark each `[x]` in plan.md Tasks section **immediately** after completion (do NOT batch).
228
230
  > 4. Use `TEST_CMD=<TEST_CMD>` to run tests — do NOT explore alternative test commands.
@@ -262,7 +264,9 @@ Append the following to the Reviewer agent prompt:
262
264
 
263
265
  Prompt:
264
266
  > "Read {{REVIEWER_SUBAGENT_PATH}}. For feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}):
265
- > 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — Section 4 has original source files, 'Implementation Log' section lists exactly what Dev changed. Do NOT re-read source files that are NOT mentioned in the Implementation Log.
267
+ > **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST.
268
+ > This file contains ALL source code and context. Do NOT re-read individual source files.
269
+ > 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — Section 4 has original source files, 'Implementation Log' section lists exactly what Dev changed. Do NOT re-read source files that are NOT mentioned in the Implementation Log.
266
270
  > 2. Run prizmkit-code-review: spec compliance (against spec.md), code quality, correctness. Read ONLY files listed in Implementation Log.
267
271
  > 3. Write and execute integration tests covering all user stories from spec.md. Use `TEST_CMD=<TEST_CMD>` — do NOT try alternative test commands.
268
272
  > 4. Append 'Review Notes' to context-snapshot.md: issues (severity), test results, final verdict.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.66",
2
+ "version": "1.0.68",
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.",
@@ -311,7 +311,13 @@ Resume incremental planning? (Y/n)"
311
311
 
312
312
  ### Artifact Path Convention
313
313
 
314
- The primary output `feature-list.json` is always written to the **project root** — this is where `dev-pipeline-launcher` and all pipeline scripts expect it.
314
+ **CRITICAL PATH RULE**: `feature-list.json` MUST be written to the project root directory
315
+ (same level as `package.json` / `.git`).
316
+
317
+ Before writing, verify: `ls package.json .git 2>/dev/null` — if these exist in the current
318
+ directory, you are at the project root. NEVER write to `dev-pipeline/` or any subdirectory.
319
+
320
+ After writing, verify: `ls -la feature-list.json` from project root.
315
321
 
316
322
  ```
317
323
  <project-root>/
@@ -9,7 +9,16 @@ Launch the autonomous development pipeline from within an AI CLI conversation. T
9
9
 
10
10
  ### Execution Mode
11
11
 
12
- Always use daemon mode via `dev-pipeline/launch-daemon.sh` for start/stop/status/log actions. Foreground `run.sh` can be terminated by AI CLI session timeout, while daemon mode survives session closure this prevents half-finished features that leave the codebase in an inconsistent state.
12
+ **Default: Foreground mode** via `dev-pipeline/run.sh run` this provides visible output and direct error feedback. Use `launch-daemon.sh` only when the user explicitly requests background execution (e.g., "run in background", "detached mode", "后台运行").
13
+
14
+ Foreground `run.sh` is preferred because:
15
+ - Immediate visibility of errors and progress
16
+ - No orphaned processes if something goes wrong
17
+ - Session summary artifacts are written reliably
18
+
19
+ Use daemon mode (`launch-daemon.sh`) only when:
20
+ - User explicitly requests background/detached execution
21
+ - Pipeline must survive AI CLI session closure
13
22
 
14
23
  ### When to Use
15
24
 
@@ -98,31 +107,36 @@ Detect user intent from their message, then follow the corresponding workflow:
98
107
  ```
99
108
 
100
109
  4. **Ask execution mode**: Present the user with a choice before launching:
101
- - **(1) Background daemon (recommended)**: Pipeline runs fully detached via `launch-daemon.sh`. Survives session closure.
102
- - **(2) Foreground in session**: Pipeline runs in the current session via `run.sh run`. Visible output but will stop if session times out.
110
+ - **(1) Foreground in session (recommended)**: Pipeline runs in the current session via `run.sh run`. Visible output and direct error feedback.
111
+ - **(2) Background daemon**: Pipeline runs fully detached via `launch-daemon.sh`. Survives session closure. Use only when user explicitly requests background execution.
103
112
  - **(3) Manual — show commands**: Display the exact commands the user can run themselves. No execution.
104
113
 
105
- Default to option 1 if user says "just run it" or doesn't specify.
114
+ Default to option 1 if user says "just run it" or doesn't specify. Default to option 2 only if user explicitly says "background", "detached", or "后台".
106
115
 
107
- **If option 2 (foreground)**:
116
+ **If option 1 (foreground)**:
108
117
  ```bash
109
118
  dev-pipeline/run.sh run feature-list.json
110
119
  ```
111
- Note: This will block the session. Warn user about timeout risk.
112
120
 
113
- **If option 3 (manual)**: Print commands and stop. Do not execute anything.
114
- ```
115
- # To run in background (recommended):
121
+ **If option 2 (background)**:
122
+ ```bash
116
123
  dev-pipeline/launch-daemon.sh start feature-list.json
124
+ ```
125
+ Note: Pipeline runs fully detached. Survives session closure.
117
126
 
118
- # To run in foreground:
127
+ **If option 3 (manual)**: Print commands and stop. Do not execute anything.
128
+ ```
129
+ # To run in foreground (recommended):
119
130
  dev-pipeline/run.sh run feature-list.json
120
131
 
132
+ # To run in background (detached):
133
+ dev-pipeline/launch-daemon.sh start feature-list.json
134
+
121
135
  # To check status:
122
- dev-pipeline/launch-daemon.sh status
136
+ dev-pipeline/run.sh status feature-list.json
123
137
  ```
124
138
 
125
- 5. **Ask user to confirm**: "Ready to launch the pipeline? It will process N features in the background."
139
+ 5. **Ask user to confirm**: "Ready to launch the pipeline? It will process N features."
126
140
 
127
141
  6. **Launch**:
128
142
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.0.66",
3
+ "version": "1.0.68",
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": {
package/src/upgrade.js CHANGED
@@ -213,13 +213,25 @@ export async function runUpgrade(directory, options = {}) {
213
213
  }
214
214
 
215
215
  // 3. Resolve new skill list using old manifest's suite + platform (or defaults)
216
- const platform = oldManifest?.platform || 'claude';
216
+ const oldManifestPlatform = oldManifest?.platform || 'claude';
217
217
  const suite = oldManifest?.suite || 'full';
218
218
  const team = oldManifest?.options?.team ?? true;
219
219
  const pipeline = oldManifest?.options?.pipeline ?? true;
220
220
  const rulesPreset = oldManifest?.options?.rules || 'recommended';
221
221
  const aiCli = userConfig.ai_cli || oldManifest?.options?.aiCli || '';
222
222
 
223
+ // Filesystem-based platform detection (overrides manifest if dirs exist)
224
+ const hasClaude = await fs.pathExists(path.join(projectRoot, '.claude', 'commands'))
225
+ || await fs.pathExists(path.join(projectRoot, '.claude', 'agents'));
226
+ const hasCodeBuddy = await fs.pathExists(path.join(projectRoot, '.codebuddy', 'skills'))
227
+ || await fs.pathExists(path.join(projectRoot, '.codebuddy', 'agents'));
228
+
229
+ let platform;
230
+ if (hasClaude && hasCodeBuddy) platform = 'both';
231
+ else if (hasCodeBuddy) platform = 'codebuddy';
232
+ else if (hasClaude) platform = 'claude';
233
+ else platform = oldManifestPlatform; // fallback to manifest
234
+
223
235
  const newSkillList = await resolveSkillList(suite);
224
236
  const agentsDir = getAgentsDir();
225
237
  const newAgentFiles = (await fs.readdir(agentsDir)).filter(f => f.endsWith('.md'));
@@ -255,7 +267,7 @@ export async function runUpgrade(directory, options = {}) {
255
267
  const oldVersion = oldManifest?.version || 'unknown';
256
268
  console.log(chalk.bold(' Upgrade Summary:'));
257
269
  console.log(` Version: ${chalk.gray(oldVersion)} → ${chalk.cyan(pkg.version)}`);
258
- console.log(` Platform: ${platform}`);
270
+ console.log(` Platform: ${platform}${platform !== oldManifestPlatform ? chalk.yellow(` (detected from filesystem, manifest had: ${oldManifestPlatform})`) : ''}`);
259
271
  console.log(` Suite: ${suite}`);
260
272
  console.log('');
261
273