prizmkit 1.1.48 → 1.1.51
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/dev-pipeline/scripts/update-checkpoint.py +173 -0
- package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +39 -9
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification-auto.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification-opencli.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +14 -1
- package/bundled/dev-pipeline/templates/sections/phase-commit.md +14 -1
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-lite-suffix.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-critic-plan-full.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-critic-plan.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase0-init.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase0-test-baseline.md +7 -1
- package/bundled/skills/_metadata.json +9 -1
- package/bundled/skills/bug-planner/SKILL.md +17 -5
- package/bundled/skills/bug-planner/scripts/validate-bug-list.py +234 -64
- package/bundled/skills/feature-planner/SKILL.md +10 -4
- package/bundled/skills/feature-planner/scripts/validate-and-generate.py +82 -0
- package/bundled/skills/prizmkit-implement/SKILL.md +3 -0
- package/bundled/skills/prizmkit-test/SKILL.md +281 -0
- package/bundled/skills/refactor-planner/SKILL.md +11 -6
- package/bundled/skills/refactor-planner/scripts/validate-and-generate-refactor.py +72 -0
- package/package.json +1 -1
- package/src/scaffold.js +5 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "prizmkit-test"
|
|
3
|
+
description: "Full-stack test generation and orchestration. Detects architecture, discovers/runs existing tests, analyzes coverage gaps, generates missing tests (unit/integration/E2E), outputs unified report. Use after completing development to verify quality before deploy. Trigger on: 'test', 'run tests', 'check quality', 'verify code', 'generate tests', 'test coverage', 'fill test gaps', 'quality check', '测试', '验证', '跑测试', '补测试'. (project)"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PrizmKit Test
|
|
7
|
+
|
|
8
|
+
A comprehensive test generation and orchestration skill. Discovers existing tests, runs them, compares coverage against spec acceptance criteria and module interfaces, generates missing tests at three levels (unit → integration → E2E), and produces a unified report.
|
|
9
|
+
|
|
10
|
+
### When to Use
|
|
11
|
+
- After completing one or more features/refactors/bugfixes
|
|
12
|
+
- As a quality gate before deploy
|
|
13
|
+
- Project has a test framework installed but zero tests written (first-time test generation)
|
|
14
|
+
- User says "test", "run tests", "verify", "check quality", "补测试"
|
|
15
|
+
|
|
16
|
+
### When NOT to Use
|
|
17
|
+
- Project has no test framework AND no code to test
|
|
18
|
+
- Trivial single-line config changes
|
|
19
|
+
|
|
20
|
+
## Precondition
|
|
21
|
+
|
|
22
|
+
| Required State | Check | If Missing |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `.prizmkit/prizm-docs/root.prizm` exists | File exists | Run `/prizmkit-init` first |
|
|
25
|
+
| Test framework installed | Dependency in package.json or equivalent | Offer to skip or let user install one manually |
|
|
26
|
+
|
|
27
|
+
If `.prizmkit/prizm-docs/` exists but may be stale (no retrospective run after recent changes), warn user: "Prizm docs may be out of date. Gap analysis accuracy depends on current docs. Continue anyway?"
|
|
28
|
+
|
|
29
|
+
## Context Loading
|
|
30
|
+
|
|
31
|
+
Before execution, load context once:
|
|
32
|
+
|
|
33
|
+
1. **Architecture context**: Read `.prizmkit/prizm-docs/root.prizm` (L0 — project overview, module index, tech stack, conventions) and relevant L1 docs for modules in scope. If scope includes specific modules, also load relevant L2 docs for INTERFACES, DATA_FLOW, TRAPS, and DECISIONS.
|
|
34
|
+
2. **Project config**: Read `.prizmkit/config.json` (tech stack, AI CLI config).
|
|
35
|
+
3. **Dependencies**: Read `package.json` or equivalent to detect test framework and project type.
|
|
36
|
+
|
|
37
|
+
## Input
|
|
38
|
+
|
|
39
|
+
| Parameter | Required | Description |
|
|
40
|
+
|-----------|----------|-------------|
|
|
41
|
+
| `scope` | No | User selects interactively in Phase 1. In headless mode, defaults to full project. |
|
|
42
|
+
|
|
43
|
+
## Execution
|
|
44
|
+
|
|
45
|
+
### Phase 0: Architecture Detection
|
|
46
|
+
|
|
47
|
+
1. From context already loaded, classify project type:
|
|
48
|
+
|
|
49
|
+
| Signal | Classification |
|
|
50
|
+
|--------|---------------|
|
|
51
|
+
| react/vue/angular/next in deps, no backend framework | Frontend |
|
|
52
|
+
| express/fastify/django/flask in deps, no frontend framework | Backend |
|
|
53
|
+
| Both present | Fullstack |
|
|
54
|
+
| Neither clear | Ask user (headless: mark as "unknown", skip E2E) |
|
|
55
|
+
|
|
56
|
+
2. Detect test framework by scanning dependencies:
|
|
57
|
+
- Jest → `npx jest` or `npm test`
|
|
58
|
+
- Vitest → `npx vitest run`
|
|
59
|
+
- pytest → `python -m pytest`
|
|
60
|
+
- Go testing → `go test ./...`
|
|
61
|
+
- Multiple frameworks found → use the one with the most test files; list all in report
|
|
62
|
+
- Custom `npm test` script → use `npm test`
|
|
63
|
+
|
|
64
|
+
3. **Interactive mode**: Show "Detected: {type}, test framework: {name}. Correct?"
|
|
65
|
+
**Headless mode**: Auto-proceed with detected values, note assumptions in report.
|
|
66
|
+
|
|
67
|
+
### Phase 1: Scope Selection
|
|
68
|
+
|
|
69
|
+
**Interactive mode** — present three options:
|
|
70
|
+
|
|
71
|
+
1. **Full project** — all modules, all specs in `.prizmkit/specs/`
|
|
72
|
+
2. **Single module** — pick from L1 doc module names (e.g., "auth", "payment")
|
|
73
|
+
3. **Single feature** — pick from `.prizmkit/specs/###-*/` directories
|
|
74
|
+
|
|
75
|
+
**Headless mode** — default to full project. If `artifact_dir` or `scope` was passed by the caller, use that.
|
|
76
|
+
|
|
77
|
+
### Phase 2: Run Existing Tests
|
|
78
|
+
|
|
79
|
+
1. Find test directories matching common patterns: `tests/`, `__tests__/`, `*.test.*`, `*.spec.*`. If no test files exist at all, note this and skip to Phase 3 (all coverage is "missing").
|
|
80
|
+
|
|
81
|
+
2. Run the detected test command in scope. Capture:
|
|
82
|
+
- Pass/fail counts and failed test details
|
|
83
|
+
- Which test files exist (for gap analysis)
|
|
84
|
+
- Raw output (saved to report directory)
|
|
85
|
+
|
|
86
|
+
3. If existing tests fail: record failures but continue — this is coverage data. Do not attempt to fix pre-existing test failures (they predate this session).
|
|
87
|
+
|
|
88
|
+
### Phase 3: Coverage Gap Analysis
|
|
89
|
+
|
|
90
|
+
Staleness of `.prizmkit/prizm-docs/` was already checked during Context Loading (see Precondition). Gap analysis proceeds with the available data.
|
|
91
|
+
|
|
92
|
+
Compare what exists against what should exist, across three levels:
|
|
93
|
+
|
|
94
|
+
**Unit test gaps** — for each module in scope:
|
|
95
|
+
- Read the corresponding L2 `.prizm` doc INTERFACES section to get exported functions/classes. If no L2 doc exists for a module, analyze source files directly to identify exported functions/classes.
|
|
96
|
+
- Check if each has a corresponding test file (match project's test naming: `foo.test.ts`, `foo.spec.ts`, `test_foo.py`)
|
|
97
|
+
- Flag uncovered interfaces
|
|
98
|
+
|
|
99
|
+
**Integration test gaps** (skip if project has no API/DB layer — pure library/CLI tool):
|
|
100
|
+
- Read L1 doc DEPENDENCIES section for cross-module interactions
|
|
101
|
+
- Check if tests exist covering module boundaries, API endpoints, DB operations
|
|
102
|
+
- Flag missing integration coverage
|
|
103
|
+
|
|
104
|
+
**E2E test gaps** (skip if project has no UI):
|
|
105
|
+
- Collect acceptance criteria from all spec.md files in scope
|
|
106
|
+
- Check existing E2E test files against these criteria
|
|
107
|
+
- Flag uncovered criteria
|
|
108
|
+
|
|
109
|
+
### Phase 4: Generate Missing Tests
|
|
110
|
+
|
|
111
|
+
Generate tests in priority order: unit → integration → E2E. After each batch, run immediately.
|
|
112
|
+
|
|
113
|
+
When generated tests fail, distinguish two cases:
|
|
114
|
+
- **Test bug** (syntax error, wrong import, wrong mock, wrong framework API usage) → fix the test and re-run
|
|
115
|
+
- **Assertion failure** (test is valid but code returns unexpected result) → mark as "needs review" in report; do NOT modify production code. This is a potential bug discovered by the generated test.
|
|
116
|
+
|
|
117
|
+
If a test fails repeatedly after 2 fix attempts, skip it and mark as "unresolved" in the report.
|
|
118
|
+
|
|
119
|
+
**4a. Unit Tests (always applicable)**
|
|
120
|
+
|
|
121
|
+
For each uncovered interface:
|
|
122
|
+
- Read the source file to understand function signature and logic
|
|
123
|
+
- Generate test file matching project conventions (framework, naming, directory, import style, mock/fixture patterns)
|
|
124
|
+
- Common naming patterns to match:
|
|
125
|
+
- `src/foo.ts` → `src/__tests__/foo.test.ts` or `src/foo.spec.ts` or `tests/foo_test.py`
|
|
126
|
+
- Mirror the existing pattern; if no tests exist, use the framework's default convention
|
|
127
|
+
- Cover: happy path, edge cases (null/undefined/empty), error conditions, boundary values
|
|
128
|
+
- Do NOT test framework internals or third-party library behavior
|
|
129
|
+
- Run tests immediately after generating
|
|
130
|
+
|
|
131
|
+
**4b. Integration Tests**
|
|
132
|
+
|
|
133
|
+
For each module with dependencies:
|
|
134
|
+
- Generate tests for the module's primary interface exercising its real dependencies
|
|
135
|
+
- If API endpoints exist: request/response tests (valid input, invalid input, missing params, auth)
|
|
136
|
+
- If database operations exist: CRUD tests using the project's existing test database config
|
|
137
|
+
- Run tests immediately after generating
|
|
138
|
+
|
|
139
|
+
**4c. E2E Tests (conditional)**
|
|
140
|
+
|
|
141
|
+
Preconditions (ALL must be met):
|
|
142
|
+
- Playwright is available (`@playwright/test` or `playwright` in package.json dependencies, or `npx playwright --version` succeeds as fallback)
|
|
143
|
+
- Playwright browsers are installed (check `npx playwright install --dry-run 2>/dev/null` exits cleanly, or `node_modules/.cache/ms-playwright/` directory exists; if missing, warn in report and skip E2E)
|
|
144
|
+
- Project has a UI layer
|
|
145
|
+
- Project can be started (start/dev script in package.json)
|
|
146
|
+
- Acceptance criteria exist in spec.md files
|
|
147
|
+
|
|
148
|
+
If ALL met:
|
|
149
|
+
- **Before starting dev server**: detect whether it's already running: (1) check `package.json` scripts for port flags (`--port`, `-p`, `PORT=`), (2) fall back to framework defaults (3000 for React/Next/Express, 5173 for Vite, 8000 for Django, 5000 for Flask), (3) if still unknown, ask the user. Use the detected port in `lsof -i :<port>` to check. If running, tell user: "Dev server appears to be already running on port {N}. Use this running instance for E2E tests?" If user confirms, use existing instance. If user declines, skip E2E.
|
|
150
|
+
- Start the project dev server (only if not already running). Wait for it to be ready.
|
|
151
|
+
- For each uncovered acceptance criterion, generate a Playwright test script
|
|
152
|
+
- Run generated E2E tests, capture screenshots of failures
|
|
153
|
+
- **Only stop dev server if you started it.** Never stop a server that was already running.
|
|
154
|
+
|
|
155
|
+
If NOT met:
|
|
156
|
+
- Note what was skipped and why in the report
|
|
157
|
+
- If only the server wasn't startable: still generate E2E script files but mark as "not run — manual execution needed"
|
|
158
|
+
|
|
159
|
+
### Phase 5: Unified Report
|
|
160
|
+
|
|
161
|
+
Create `.prizmkit/test/{YYYY_MM_DD_HH_MM_SS}_testresult/` directory.
|
|
162
|
+
|
|
163
|
+
**test-report.md** format:
|
|
164
|
+
|
|
165
|
+
```markdown
|
|
166
|
+
# Test Report — {timestamp}
|
|
167
|
+
|
|
168
|
+
## Summary
|
|
169
|
+
- Scope: {full / module: name / feature: ###-name}
|
|
170
|
+
- Architecture: {frontend / backend / fullstack}
|
|
171
|
+
- Test framework: {name}
|
|
172
|
+
- Mode: {interactive / headless}
|
|
173
|
+
|
|
174
|
+
## Existing Tests
|
|
175
|
+
- Total: {N} | Passed: {N} | Failed: {N}
|
|
176
|
+
{failed test details or "All passing"}
|
|
177
|
+
{or "No existing tests found — generated first batch"}
|
|
178
|
+
|
|
179
|
+
## Coverage Gaps Found
|
|
180
|
+
| Module | Interface | Type | Status |
|
|
181
|
+
|--------|-----------|------|--------|
|
|
182
|
+
| ... | ... | unit/integration/e2e | covered / generated / needs-review / unresolved / skipped |
|
|
183
|
+
|
|
184
|
+
## Generated Tests
|
|
185
|
+
- Unit: {N} generated, {N} needs-review, {N} unresolved
|
|
186
|
+
- Integration: {N} generated, {N} needs-review, {N} unresolved
|
|
187
|
+
- E2E: {N} generated, {N} skipped ({reason})
|
|
188
|
+
|
|
189
|
+
## Final Status
|
|
190
|
+
- All tests passing: {yes / no}
|
|
191
|
+
- Needs human review: {list of tests marked needs-review}
|
|
192
|
+
{remaining failures if any}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Also save:
|
|
196
|
+
- `existing-test-output.txt` — raw output from Phase 2
|
|
197
|
+
- `generated-tests/` — copies of all generated test files
|
|
198
|
+
- `e2e-output/` — E2E logs and failure screenshots (if applicable)
|
|
199
|
+
|
|
200
|
+
## Output
|
|
201
|
+
|
|
202
|
+
- Test report: `.prizmkit/test/{timestamp}_testresult/test-report.md`
|
|
203
|
+
- Generated test files written to project test directories
|
|
204
|
+
- Existing test output, generated test copies, and E2E artifacts in the report directory
|
|
205
|
+
|
|
206
|
+
## Recovery
|
|
207
|
+
|
|
208
|
+
If the session is interrupted:
|
|
209
|
+
- Check `.prizmkit/test/` for the most recent report directory — it contains what was completed before interruption
|
|
210
|
+
- Re-run `/prizmkit-test` — it starts fresh, but Phase 2 will skip tests that already pass, and Phase 3 will re-evaluate gaps
|
|
211
|
+
|
|
212
|
+
## Examples
|
|
213
|
+
|
|
214
|
+
### Example 1: Full-Project Quality Check with Test Generation
|
|
215
|
+
|
|
216
|
+
**User**: `/prizmkit-test`
|
|
217
|
+
|
|
218
|
+
**Phase 0 — Architecture Detection**:
|
|
219
|
+
```
|
|
220
|
+
Detected: Fullstack (React + Express)
|
|
221
|
+
Test framework: Vitest (7 existing test files)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Phase 1 — Scope Selection** (user selects option 1):
|
|
225
|
+
```
|
|
226
|
+
Scope: Full project (all modules, all specs)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Phase 2 — Existing Tests**: 7 test files found, 20 tests run, 18 passed, 2 pre-existing failures (recorded, not fixed).
|
|
230
|
+
|
|
231
|
+
**Phase 3 — Gap Analysis** (excerpt):
|
|
232
|
+
| Module | Interface | Type | Status |
|
|
233
|
+
|--------|-----------|------|--------|
|
|
234
|
+
| auth | login() | unit | missing |
|
|
235
|
+
| auth | register() | unit | missing |
|
|
236
|
+
| payment | processPayment() | unit | missing |
|
|
237
|
+
| payment | api/checkout | integration | missing |
|
|
238
|
+
| — | Checkout flow | e2e | missing |
|
|
239
|
+
|
|
240
|
+
**Phase 4**: Generated 5 unit tests (3 passing, 2 assertion failures marked "needs-review"), 1 integration test (passing), 1 E2E test (passing).
|
|
241
|
+
|
|
242
|
+
**Phase 5 — Report Summary**:
|
|
243
|
+
```
|
|
244
|
+
Generated: 5 unit (2 needs-review), 1 integration, 1 E2E
|
|
245
|
+
Report: .prizmkit/test/2026_05_23_14_30_00_testresult/test-report.md
|
|
246
|
+
Needs human review: processPayment (returns 400 for negative amounts, expected 422), refund (missing authorization header causes 500 instead of 401)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Example 2: Single-Feature Targeted Test
|
|
250
|
+
|
|
251
|
+
**User**: `/prizmkit-test`
|
|
252
|
+
|
|
253
|
+
**Phase 0 — Architecture Detection**:
|
|
254
|
+
```
|
|
255
|
+
Detected: Backend (Express)
|
|
256
|
+
Test framework: Vitest
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Phase 1 — Scope Selection** (user selects option 3, then picks "042-payment-gateway"):
|
|
260
|
+
```
|
|
261
|
+
Scope: Single feature — 042-payment-gateway
|
|
262
|
+
Test files in scope: 2
|
|
263
|
+
|
|
264
|
+
**Phase 2 — Existing Tests**: 2 test files, 8 tests, all passing.
|
|
265
|
+
|
|
266
|
+
**Phase 3 — Gap Analysis** (excerpt):
|
|
267
|
+
| Module | Interface | Type | Status |
|
|
268
|
+
|--------|-----------|------|--------|
|
|
269
|
+
| payment | processPayment() | unit | missing |
|
|
270
|
+
| payment | refund() | unit | missing |
|
|
271
|
+
|
|
272
|
+
**Phase 4**: Generated 2 unit tests (both passing). No integration/E2E applicable for this scope.
|
|
273
|
+
|
|
274
|
+
**Phase 5 — Report Summary**:
|
|
275
|
+
```
|
|
276
|
+
Generated: 2 unit tests (all passing)
|
|
277
|
+
Report: .prizmkit/test/2026_05_23_15_00_00_testresult/test-report.md
|
|
278
|
+
All tests passing. Ready for commit.
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**HANDOFF:** Independent skill — no handoff. User may proceed to `/prizmkit-committer` if all tests pass, or fix issues manually if tests are marked "needs-review".
|
|
@@ -293,12 +293,14 @@ If issues found, discuss with user and resolve before proceeding.
|
|
|
293
293
|
|
|
294
294
|
**Goal**: Produce `.prizmkit/plans/refactor-list.json` and validate it.
|
|
295
295
|
|
|
296
|
-
|
|
297
|
-
|
|
296
|
+
**IMPORTANT: Do NOT hand-write the final JSON file.** Instead:
|
|
297
|
+
1. Write a draft JSON to `.prizmkit/plans/refactor-list.draft.json` with all collected refactor data.
|
|
298
|
+
2. Call the generate script to validate and produce the final file:
|
|
298
299
|
```bash
|
|
299
|
-
python3 ${SKILL_DIR}/scripts/validate-and-generate-refactor.py
|
|
300
|
+
python3 ${SKILL_DIR}/scripts/validate-and-generate-refactor.py generate --input .prizmkit/plans/refactor-list.draft.json --output .prizmkit/plans/refactor-list.json
|
|
300
301
|
```
|
|
301
|
-
|
|
302
|
+
The script fills in defaults (`$schema`, `created_at`, `created_by`), validates all fields, and writes the final file only if validation passes.
|
|
303
|
+
3. If validation fails -> fix the draft and retry (max 3 attempts)
|
|
302
304
|
4. If validation passes -> present final summary
|
|
303
305
|
|
|
304
306
|
**CHECKPOINT CP-RP-6**: `.prizmkit/plans/refactor-list.json` generated and validated.
|
|
@@ -380,9 +382,12 @@ For simple refactoring with minimal scope:
|
|
|
380
382
|
|
|
381
383
|
**NEVER proceed without explicit user selection via `AskUserQuestion`. Do NOT render options as plain text — the user must be able to click/select.**
|
|
382
384
|
3. Draft items (title + type + scope + description + acceptance_criteria + behavior_preservation + dependencies)
|
|
383
|
-
4.
|
|
385
|
+
4. Write draft to `.prizmkit/plans/refactor-list.draft.json`, then call the generate script:
|
|
386
|
+
```bash
|
|
387
|
+
python3 ${SKILL_DIR}/scripts/validate-and-generate-refactor.py generate --input .prizmkit/plans/refactor-list.draft.json --output .prizmkit/plans/refactor-list.json
|
|
388
|
+
```
|
|
384
389
|
5. If valid -> summarize and recommend next step
|
|
385
|
-
6. If invalid -> apply fixes, re-
|
|
390
|
+
6. If invalid -> apply fixes to the draft, re-run generate (max 2 attempts, then escalate to full workflow)
|
|
386
391
|
|
|
387
392
|
### When NOT to Use Fast Path
|
|
388
393
|
- More than 2 refactor items
|
|
@@ -6,11 +6,13 @@ for the dev-pipeline system.
|
|
|
6
6
|
Commands:
|
|
7
7
|
validate Validate an existing .prizmkit/plans/refactor-list.json
|
|
8
8
|
template Generate a blank template .prizmkit/plans/refactor-list.json
|
|
9
|
+
generate Validate a draft JSON and generate final refactor-list.json with defaults
|
|
9
10
|
summary Print a summary table of refactors from a .prizmkit/plans/refactor-list.json
|
|
10
11
|
|
|
11
12
|
Usage:
|
|
12
13
|
python3 validate-and-generate-refactor.py validate --input .prizmkit/plans/refactor-list.json [--output validated.json]
|
|
13
14
|
python3 validate-and-generate-refactor.py template --output .prizmkit/plans/refactor-list.json
|
|
15
|
+
python3 validate-and-generate-refactor.py generate --input draft.json --output .prizmkit/plans/refactor-list.json
|
|
14
16
|
python3 validate-and-generate-refactor.py summary --input .prizmkit/plans/refactor-list.json [--format markdown|json]
|
|
15
17
|
|
|
16
18
|
Python 3.6+ required. No external dependencies.
|
|
@@ -22,6 +24,7 @@ import json
|
|
|
22
24
|
import os
|
|
23
25
|
import re
|
|
24
26
|
import sys
|
|
27
|
+
from datetime import datetime, timezone
|
|
25
28
|
|
|
26
29
|
# ---------------------------------------------------------------------------
|
|
27
30
|
# Constants
|
|
@@ -687,6 +690,61 @@ def cmd_template(args):
|
|
|
687
690
|
return 0
|
|
688
691
|
|
|
689
692
|
|
|
693
|
+
def cmd_generate(args):
|
|
694
|
+
"""Handle the 'generate' command.
|
|
695
|
+
|
|
696
|
+
Loads a draft JSON (produced by AI), fills in defaults, validates,
|
|
697
|
+
and writes the final refactor-list.json.
|
|
698
|
+
"""
|
|
699
|
+
if not args.input:
|
|
700
|
+
_err("--input is required for the generate command")
|
|
701
|
+
return 2
|
|
702
|
+
if not args.output:
|
|
703
|
+
_err("--output is required for the generate command")
|
|
704
|
+
return 2
|
|
705
|
+
|
|
706
|
+
# Load draft (supports stdin via '-')
|
|
707
|
+
if args.input == "-":
|
|
708
|
+
try:
|
|
709
|
+
data = json.load(sys.stdin)
|
|
710
|
+
except json.JSONDecodeError as exc:
|
|
711
|
+
_err("Invalid JSON from stdin: {}".format(exc))
|
|
712
|
+
return 2
|
|
713
|
+
else:
|
|
714
|
+
data, load_err = _load_json(args.input)
|
|
715
|
+
if load_err:
|
|
716
|
+
_err(load_err)
|
|
717
|
+
return 2
|
|
718
|
+
|
|
719
|
+
# Fill in defaults
|
|
720
|
+
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
721
|
+
data.setdefault("$schema", SCHEMA_VERSION)
|
|
722
|
+
data.setdefault("created_at", now)
|
|
723
|
+
data.setdefault("created_by", "refactor-planner")
|
|
724
|
+
|
|
725
|
+
# Set default status for refactors without one
|
|
726
|
+
for refactor in data.get("refactors", []):
|
|
727
|
+
refactor.setdefault("status", "pending")
|
|
728
|
+
|
|
729
|
+
# Validate
|
|
730
|
+
result = validate_refactor_list(data)
|
|
731
|
+
|
|
732
|
+
# Output validation result
|
|
733
|
+
print(json.dumps(result, indent=2, ensure_ascii=False))
|
|
734
|
+
|
|
735
|
+
if result["valid"]:
|
|
736
|
+
_write_json(args.output, data)
|
|
737
|
+
_info("Generated refactor-list written to {}".format(args.output))
|
|
738
|
+
return 0
|
|
739
|
+
else:
|
|
740
|
+
_err("Validation failed with {} error(s)".format(len(result["errors"])))
|
|
741
|
+
for e in result["errors"]:
|
|
742
|
+
_err(" " + e)
|
|
743
|
+
for w in result.get("warnings", []):
|
|
744
|
+
_warn(" " + w)
|
|
745
|
+
return 1
|
|
746
|
+
|
|
747
|
+
|
|
690
748
|
def cmd_summary(args):
|
|
691
749
|
"""Handle the 'summary' command."""
|
|
692
750
|
if not args.input:
|
|
@@ -719,6 +777,7 @@ def main():
|
|
|
719
777
|
" %(prog)s validate --input .prizmkit/plans/refactor-list.json\n"
|
|
720
778
|
" %(prog)s validate --input .prizmkit/plans/refactor-list.json --output validated.json\n"
|
|
721
779
|
" %(prog)s template --output .prizmkit/plans/refactor-list.json\n"
|
|
780
|
+
" %(prog)s generate --input draft.json --output .prizmkit/plans/refactor-list.json\n"
|
|
722
781
|
" %(prog)s summary --input .prizmkit/plans/refactor-list.json\n"
|
|
723
782
|
" %(prog)s summary --input .prizmkit/plans/refactor-list.json --format json\n"
|
|
724
783
|
),
|
|
@@ -747,6 +806,18 @@ def main():
|
|
|
747
806
|
"--output", required=True, help="Path to write template file"
|
|
748
807
|
)
|
|
749
808
|
|
|
809
|
+
# -- generate --
|
|
810
|
+
p_generate = subparsers.add_parser(
|
|
811
|
+
"generate",
|
|
812
|
+
help="Validate a draft and generate final refactor-list.json with defaults",
|
|
813
|
+
)
|
|
814
|
+
p_generate.add_argument(
|
|
815
|
+
"--input", required=True, help="Path to draft JSON (or '-' for stdin)"
|
|
816
|
+
)
|
|
817
|
+
p_generate.add_argument(
|
|
818
|
+
"--output", required=True, help="Path to write final refactor-list.json"
|
|
819
|
+
)
|
|
820
|
+
|
|
750
821
|
# -- summary --
|
|
751
822
|
p_summary = subparsers.add_parser(
|
|
752
823
|
"summary",
|
|
@@ -771,6 +842,7 @@ def main():
|
|
|
771
842
|
dispatch = {
|
|
772
843
|
"validate": cmd_validate,
|
|
773
844
|
"template": cmd_template,
|
|
845
|
+
"generate": cmd_generate,
|
|
774
846
|
"summary": cmd_summary,
|
|
775
847
|
}
|
|
776
848
|
|
package/package.json
CHANGED
package/src/scaffold.js
CHANGED
|
@@ -769,6 +769,11 @@ export async function installPlaywrightCli(projectRoot, dryRun) {
|
|
|
769
769
|
try {
|
|
770
770
|
execSync('playwright-cli install --skills', { cwd: projectRoot, stdio: 'pipe', timeout: 60000 });
|
|
771
771
|
console.log(chalk.green(' ✓ playwright-cli skills installed'));
|
|
772
|
+
// playwright-cli creates an empty .playwright directory — remove it
|
|
773
|
+
const dotPlaywright = path.join(projectRoot, '.playwright');
|
|
774
|
+
if (fs.pathExistsSync(dotPlaywright)) {
|
|
775
|
+
fs.removeSync(dotPlaywright);
|
|
776
|
+
}
|
|
772
777
|
} catch (e) {
|
|
773
778
|
console.log(chalk.yellow(` ⚠ Skills install skipped: ${e.message}`));
|
|
774
779
|
console.log(chalk.yellow(' ⚠ Run manually: playwright-cli install --skills'));
|