prizmkit 1.0.149 → 1.0.150

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.149",
3
- "bundledAt": "2026-03-31T17:50:05.806Z",
4
- "bundledFrom": "9c1abf7"
2
+ "frameworkVersion": "1.0.150",
3
+ "bundledAt": "2026-03-31T17:59:38.986Z",
4
+ "bundledFrom": "51bf160"
5
5
  }
@@ -11,7 +11,7 @@
11
11
 
12
12
  import { parseFrontmatter, buildMarkdown } from '../shared/frontmatter.js';
13
13
  import { COMMANDS_DIR } from './paths.js';
14
- import { existsSync, mkdirSync, cpSync } from 'node:fs';
14
+ import { existsSync, mkdirSync, cpSync, readdirSync } from 'node:fs';
15
15
  import { readFile, writeFile } from 'node:fs/promises';
16
16
  import path from 'path';
17
17
 
@@ -100,12 +100,13 @@ export function convertSkillToCommand(skillContent, skillName) {
100
100
  */
101
101
  export async function installCommand(corePath, targetRoot) {
102
102
  const skillName = path.basename(corePath);
103
- const hasAssets = existsSync(path.join(corePath, 'assets'));
104
- const hasScripts = existsSync(path.join(corePath, 'scripts'));
105
- const hasRules = existsSync(path.join(corePath, 'rules'));
106
- const hasReferences = existsSync(path.join(corePath, 'references'));
107
103
 
108
- if (hasAssets || hasScripts || hasRules || hasReferences) {
104
+ // Discover all subdirectories in the skill
105
+ const subdirs = existsSync(corePath)
106
+ ? readdirSync(corePath, { withFileTypes: true }).filter(e => e.isDirectory()).map(e => e.name)
107
+ : [];
108
+
109
+ if (subdirs.length > 0) {
109
110
  // Use directory structure for commands with resources
110
111
  const targetDir = path.join(targetRoot, COMMANDS_DIR, skillName);
111
112
  mkdirSync(targetDir, { recursive: true });
@@ -118,12 +119,9 @@ export async function installCommand(corePath, targetRoot) {
118
119
  await writeFile(path.join(targetDir, `${skillName}.md`), converted);
119
120
  }
120
121
 
121
- // Copy assets and scripts
122
- for (const subdir of ['scripts', 'assets', 'rules', 'references']) {
123
- const srcSubdir = path.join(corePath, subdir);
124
- if (existsSync(srcSubdir)) {
125
- cpSync(srcSubdir, path.join(targetDir, subdir), { recursive: true });
126
- }
122
+ // Copy all subdirectories
123
+ for (const subdir of subdirs) {
124
+ cpSync(path.join(corePath, subdir), path.join(targetDir, subdir), { recursive: true });
127
125
  }
128
126
  } else {
129
127
  // Single file command
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.149",
2
+ "version": "1.0.150",
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.",
@@ -58,23 +58,21 @@ Do NOT use this skill when the user only wants to run the pipeline (`dev-pipelin
58
58
 
59
59
  ## Resource Loading Rules (Mandatory)
60
60
 
61
- `SKILL_DIR` definition:
62
- - `SKILL_DIR` is the absolute path of this skill directory.
63
61
  1. **Choose scenario reference before planning**:
64
- - New app → read `references/new-app-planning.md`
65
- - Existing app incremental features → read `references/incremental-feature-planning.md`
62
+ - New app → read `${SKILL_DIR}/references/new-app-planning.md`
63
+ - Existing app incremental features → read `${SKILL_DIR}/references/incremental-feature-planning.md`
66
64
 
67
65
  2. **Use shared quality examples as needed**:
68
- - read `assets/planning-guide.md` for decomposition and acceptance criteria patterns
66
+ - read `${SKILL_DIR}/assets/planning-guide.md` for decomposition and acceptance criteria patterns
69
67
 
70
68
  3. **Load on-demand references when triggered**:
71
- - Validation errors or interrupted session → read `references/error-recovery.md`
72
- - Architecture decisions emerged → read `references/architecture-decisions.md`
73
- - Browser interaction fields needed → read `references/browser-interaction.md`
69
+ - Validation errors or interrupted session → read `${SKILL_DIR}/references/error-recovery.md`
70
+ - Architecture decisions emerged → read `${SKILL_DIR}/references/architecture-decisions.md`
71
+ - Browser interaction fields needed → read `${SKILL_DIR}/references/browser-interaction.md`
74
72
 
75
73
  4. **Brainstorm deep-dive** — If the user chooses to continue discussing or exploring ideas before finalizing features (e.g., during Intent Confirmation the user selects "just explore ideas", or at any point says "let's discuss more" / "I want to think through this"):
76
- → read `references/brainstorm-guide.md` and follow its four-phase structured ideation process (Assess Clarity → Understand → Explore Approaches → Capture Design)
77
- → During Phase C (Explore Approaches), also read `references/red-team-checklist.md` for adversarial critique of each approach
74
+ → read `${SKILL_DIR}/references/brainstorm-guide.md` and follow its four-phase structured ideation process (Assess Clarity → Understand → Explore Approaches → Capture Design)
75
+ → During Phase C (Explore Approaches), also read `${SKILL_DIR}/references/red-team-checklist.md` for adversarial critique of each approach
78
76
  → When brainstorm Phase D produces a "Capture Design" summary, use it as the Vision Summary (fulfilling CP-AP-2) and proceed to Phase 2 (constraints and tech assumptions)
79
77
 
80
78
  5. **Frontend / UI design check** — Evaluate during Phase 2 (constraints and tech assumptions), after tech stack is confirmed. If the project has a frontend framework:
@@ -82,17 +80,17 @@ Do NOT use this skill when the user only wants to run the pipeline (`dev-pipelin
82
80
  → Also search the active CLI's project instruction file (`CLAUDE.md` / `CODEBUDDY.md`) for keywords: "UI", "UX", "design system", "style guide", "theme", "typography", "color palette"
83
81
  → If unified design guidance is found → use it as constraint for feature descriptions
84
82
  → If NO unified design guidance found → ask user: "项目中未找到统一的 UI/UX 设计规范。是否需要在特性规划前先建立一套 UI/UX 设计方向?(No unified UI/UX design system found. Would you like to establish one before feature planning?)"
85
- → If yes → read `references/frontend-design-guide.md` and conduct a design direction session. Capture the result in the project instruction file (with user consent).
83
+ → If yes → read `${SKILL_DIR}/references/frontend-design-guide.md` and conduct a design direction session. Capture the result in the project instruction file (with user consent).
86
84
  → If no → proceed without; individual features may still define their own UI approach.
87
85
 
88
86
  6. **Project conventions check** — After Intent Confirmation (CP-AP-0), before brainstorm or Phase 1 vision work. This runs regardless of session goal (produce or explore):
89
87
  → Read `.prizmkit/project-conventions.json` if it exists
90
88
  → If the file exists but cannot be parsed as valid JSON → warn user ("conventions file is corrupted, will re-ask all questions"), treat all conventions as unanswered
91
- → Cross-reference with `references/project-conventions.md` for the full question list
89
+ → Cross-reference with `${SKILL_DIR}/references/project-conventions.md` for the full question list
92
90
  → For any convention with a `null` or missing value → batch all unanswered questions into a single prompt to the user
93
91
  → Save answers to `.prizmkit/project-conventions.json` (create `.prizmkit/` directory if needed — this is an allowed writable output)
94
92
  → If all conventions are already answered → skip silently, do not re-ask
95
- → Use convention answers as context when writing feature descriptions and proposing features (see `references/project-conventions.md` §How Conventions Are Used)
93
+ → Use convention answers as context when writing feature descriptions and proposing features (see `${SKILL_DIR}/references/project-conventions.md` §How Conventions Are Used)
96
94
 
97
95
  7. **Always validate output via script**:
98
96
  - run:
@@ -134,7 +132,7 @@ Classify user intent first:
134
132
  Use when user starts from idea/blank slate or asks for initial end-to-end plan.
135
133
 
136
134
  Actions:
137
- 1. Load `references/new-app-planning.md`
135
+ 1. Load `${SKILL_DIR}/references/new-app-planning.md`
138
136
  2. Run interactive planning phases
139
137
  3. Generate initial `feature-list.json`
140
138
 
@@ -142,7 +140,7 @@ Actions:
142
140
  Use when user already has app/code/plan and asks to add or adjust features.
143
141
 
144
142
  Actions:
145
- 1. Load `references/incremental-feature-planning.md`
143
+ 1. Load `${SKILL_DIR}/references/incremental-feature-planning.md`
146
144
  2. Read existing `feature-list.json` first (if missing, ask whether to start new plan)
147
145
  3. Append features with next sequential `F-NNN` IDs
148
146
  4. Preserve style/language/detail consistency with existing plan
@@ -159,7 +157,7 @@ After scenario routing, immediately confirm the user's deliverable intent:
159
157
  - **"Produce feature-list.json"** → Continue to Core Workflow. Set session goal = `produce`.
160
158
  - **"Just explore ideas"** → Enter **Exploration Mode**:
161
159
  - Run project conventions check first (CP-AP-1) — same as produce mode
162
- - Load `references/brainstorm-guide.md` and follow its structured ideation process (Phases A-D)
160
+ - Load `${SKILL_DIR}/references/brainstorm-guide.md` and follow its structured ideation process (Phases A-D)
163
161
  - Brainstorm Phase D output serves as the Vision Summary (CP-AP-2)
164
162
  - Continue with Phase 2 (constraints — including frontend design check CP-AP-3 if applicable), then Phases 3-5 normally
165
163
  - At Phase 5 completion, re-ask: "Ideas are taking shape. Ready to generate `feature-list.json` now?"
@@ -206,11 +204,11 @@ Note: Checkpoint numbers (CP-AP-N) are sequential identifiers for the gate, NOT
206
204
  | **CP-AP-6** | `feature-list.json` Generated | Schema validates, all required keys present | 6-7 |
207
205
  | **CP-AP-7** | Final Validation Pass | Python script returns `"valid": true` with zero errors | 8 |
208
206
 
209
- **Resume Detection**: If existing artifacts are found, read `references/error-recovery.md` §Resume Support for checkpoint-based resumption.
207
+ **Resume Detection**: If existing artifacts are found, read `${SKILL_DIR}/references/error-recovery.md` §Resume Support for checkpoint-based resumption.
210
208
 
211
209
  ## Architecture Decision Capture
212
210
 
213
- After Phase 5, if framework-shaping architecture decisions emerged during planning (tech stack, communication patterns, data model strategies — not individual feature details), read `references/architecture-decisions.md` and follow the capture flow. Most sessions will NOT produce architecture decisions — only capture when genuinely impactful.
211
+ After Phase 5, if framework-shaping architecture decisions emerged during planning (tech stack, communication patterns, data model strategies — not individual feature details), read `${SKILL_DIR}/references/architecture-decisions.md` and follow the capture flow. Most sessions will NOT produce architecture decisions — only capture when genuinely impactful.
214
212
 
215
213
  ## Fast Path — Incremental Shortcuts
216
214
 
@@ -270,7 +268,7 @@ A feature is **exempt** when ANY of these are true:
270
268
 
271
269
  ### Default Behavior (Phase 4.2)
272
270
 
273
- 1. **Auto-generate** `browser_interaction` for ALL qualifying features. Read `references/browser-interaction.md` for the object format and field rules.
271
+ 1. **Auto-generate** `browser_interaction` for ALL qualifying features. Read `${SKILL_DIR}/references/browser-interaction.md` for the object format and field rules.
274
272
  2. **Present a summary** to the user showing which features received `browser_interaction`:
275
273
  > "以下 N 个前端特性已自动添加 browser_interaction 用于 Playwright 自动验证:F-002, F-004, F-007。如需移除某个特性的浏览器验证,请告知。"
276
274
  3. **User can opt-OUT** specific features — remove the field for declined features.
@@ -371,7 +369,7 @@ When launcher is available, do not prioritize raw scripts.
371
369
 
372
370
  ## Error Recovery & Resume
373
371
 
374
- If validation fails or a session is interrupted → read `references/error-recovery.md` for the full error type table, decision tree, retry logic, and checkpoint-based resume support.
372
+ If validation fails or a session is interrupted → read `${SKILL_DIR}/references/error-recovery.md` for the full error type table, decision tree, retry logic, and checkpoint-based resume support.
375
373
 
376
374
  Key behaviors:
377
375
  - Warnings only → proceed with user approval
@@ -0,0 +1,30 @@
1
+ {
2
+ "skill_name": "recovery-workflow",
3
+ "notes": "These test cases require pipeline state setup. Each has a setup_script that creates the necessary mock state before the skill is invoked. Due to the interactive nature and state-dependency of this skill, automated evaluation is limited — qualitative review is primary.",
4
+ "evals": [
5
+ {
6
+ "id": 1,
7
+ "name": "scenario-a-mid-implementation",
8
+ "prompt": "F-003 的 session 超时了,工作区里已经写了大部分代码了,帮我恢复一下",
9
+ "expected_output": "Should detect existing spec.md, plan.md with partial task completion, code changes in worktree. Should recommend 'Smart Resume' (continue_implementation). Should present clear recovery report showing what was found and what remains.",
10
+ "setup_description": "Create feature-list.json with F-003, .prizmkit/specs/003-*/spec.md and plan.md (3/5 tasks checked), some source files modified, pipeline state showing 'failed'.",
11
+ "files": []
12
+ },
13
+ {
14
+ "id": 2,
15
+ "name": "scenario-b-plan-only",
16
+ "prompt": "我看到 F-001 有 spec 和 plan 但是还没开始写代码,帮我从 plan 开始执行",
17
+ "expected_output": "Should detect spec.md and plan.md exist but no code changes. Should recommend 'Start Implementation'. Should read existing plan and begin implementing from task 1.",
18
+ "setup_description": "Create feature-list.json with F-001, .prizmkit/specs/001-*/spec.md and plan.md (0/4 tasks checked), no code changes, pipeline state showing 'failed' at early phase.",
19
+ "files": []
20
+ },
21
+ {
22
+ "id": 3,
23
+ "name": "scenario-a-nearly-complete",
24
+ "prompt": "recover F-005. Token limit exceeded but I think the code is mostly done, tests should be passing",
25
+ "expected_output": "Should detect all plan tasks completed, code changes present, tests passing. Should recommend 'Review & Commit Only'. Should proceed to code review and commit without re-implementing.",
26
+ "setup_description": "Create feature-list.json with F-005, full spec.md and plan.md (all tasks checked), source files complete and tests passing, pipeline state showing 'failed' with token limit error.",
27
+ "files": []
28
+ }
29
+ ]
30
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.0.149",
3
+ "version": "1.0.150",
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/scaffold.js CHANGED
@@ -156,11 +156,11 @@ export async function installSkills(platform, skills, projectRoot, dryRun) {
156
156
  if (!frontmatter.name) frontmatter.name = skillName;
157
157
  await fs.writeFile(path.join(targetDir, 'SKILL.md'), buildMarkdown(frontmatter, body));
158
158
 
159
- // 复制 assets/、scripts/ references/
160
- for (const subdir of ['assets', 'scripts', 'references']) {
161
- const srcSubdir = path.join(corePath, subdir);
162
- if (await fs.pathExists(srcSubdir)) {
163
- await fs.copy(srcSubdir, path.join(targetDir, subdir));
159
+ // 复制所有子目录(assets/, scripts/, references/ 等)
160
+ const cbEntries = await fs.readdir(corePath, { withFileTypes: true });
161
+ for (const entry of cbEntries) {
162
+ if (entry.isDirectory()) {
163
+ await fs.copy(path.join(corePath, entry.name), path.join(targetDir, entry.name));
164
164
  }
165
165
  }
166
166
 
@@ -170,9 +170,9 @@ export async function installSkills(platform, skills, projectRoot, dryRun) {
170
170
  const content = await fs.readFile(skillMdPath, 'utf8');
171
171
  const converted = convertSkillToCommand(content, skillName);
172
172
 
173
- const hasAssets = await fs.pathExists(path.join(corePath, 'assets'));
174
- const hasScripts = await fs.pathExists(path.join(corePath, 'scripts'));
175
- const hasReferences = await fs.pathExists(path.join(corePath, 'references'));
173
+ // Discover all subdirectories in the skill
174
+ const clEntries = await fs.readdir(corePath, { withFileTypes: true });
175
+ const skillSubdirs = clEntries.filter(e => e.isDirectory()).map(e => e.name);
176
176
 
177
177
  // Always write the command file at the flat level (.claude/commands/skillName.md)
178
178
  // so Claude Code shows it as /skillName (not /skillName:skillName).
@@ -185,16 +185,13 @@ export async function installSkills(platform, skills, projectRoot, dryRun) {
185
185
  await fs.ensureDir(commandsDir);
186
186
  await fs.writeFile(path.join(commandsDir, `${skillName}.md`), converted);
187
187
 
188
- if (hasAssets || hasScripts || hasReferences) {
189
- // Place assets/scripts outside .claude/commands/ to prevent Claude Code
188
+ if (skillSubdirs.length > 0) {
189
+ // Place subdirectories outside .claude/commands/ to prevent Claude Code
190
190
  // from registering them as slash commands (e.g. /skillName:assets:file).
191
191
  const assetTargetDir = path.join(projectRoot, '.claude', 'command-assets', skillName);
192
192
  await fs.ensureDir(assetTargetDir);
193
- for (const subdir of ['assets', 'scripts', 'references']) {
194
- const srcSubdir = path.join(corePath, subdir);
195
- if (await fs.pathExists(srcSubdir)) {
196
- await fs.copy(srcSubdir, path.join(assetTargetDir, subdir));
197
- }
193
+ for (const subdir of skillSubdirs) {
194
+ await fs.copy(path.join(corePath, subdir), path.join(assetTargetDir, subdir));
198
195
  }
199
196
  }
200
197
  console.log(chalk.green(` ✓ .claude/commands/${skillName}.md`));