prizmkit 1.0.149 → 1.0.151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/VERSION.json +3 -3
- package/bundled/adapters/claude/command-adapter.js +10 -12
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/app-planner/SKILL.md +19 -21
- package/bundled/skills/recovery-workflow/evals/evals.json +30 -0
- package/package.json +1 -1
- package/src/scaffold.js +12 -15
package/bundled/VERSION.json
CHANGED
|
@@ -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
|
-
|
|
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
|
|
122
|
-
for (const subdir of
|
|
123
|
-
|
|
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
|
|
@@ -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
|
|
65
|
-
- Existing app incremental features → read
|
|
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
|
|
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
|
|
72
|
-
- Architecture decisions emerged → read
|
|
73
|
-
- Browser interaction fields needed → read
|
|
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
|
|
77
|
-
→ During Phase C (Explore Approaches), also read
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
@@ -101,7 +99,7 @@ Do NOT use this skill when the user only wants to run the pipeline (`dev-pipelin
|
|
|
101
99
|
```
|
|
102
100
|
|
|
103
101
|
8. **Use script output as source of truth**:
|
|
104
|
-
- if validation fails, fix and re-run until pass
|
|
102
|
+
- if validation fails, **MUST** fix and re-run until pass
|
|
105
103
|
|
|
106
104
|
## Prerequisites
|
|
107
105
|
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
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
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (
|
|
163
|
-
await fs.copy(
|
|
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
|
-
|
|
174
|
-
const
|
|
175
|
-
const
|
|
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 (
|
|
189
|
-
// Place
|
|
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
|
|
194
|
-
|
|
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`));
|