prizmkit 1.1.35 → 1.1.37
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/bin/create-prizmkit.js +4 -0
- package/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +66 -18
- package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +4 -5
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +74 -4
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +84 -15
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +84 -22
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +4 -4
- package/bundled/dev-pipeline/templates/feature-list-schema.json +8 -2
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +5 -6
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification-auto.md +153 -0
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification-opencli.md +124 -0
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +10 -17
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +11 -18
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/bug-fix-workflow/SKILL.md +17 -27
- package/bundled/skills/feature-planner/SKILL.md +6 -5
- package/bundled/skills/feature-planner/references/browser-interaction.md +14 -1
- package/bundled/skills/prizmkit-code-review/SKILL.md +176 -45
- package/package.json +1 -1
- package/src/index.js +10 -1
- package/src/scaffold.js +52 -3
- package/bundled/skills/prizmkit-code-review/rules/dimensions.md +0 -85
- package/bundled/skills/prizmkit-code-review/rules/fix-strategy.md +0 -61
package/bin/create-prizmkit.js
CHANGED
|
@@ -37,6 +37,10 @@ program
|
|
|
37
37
|
.option('--no-team', 'Disable multi-agent team mode')
|
|
38
38
|
.option('--pipeline', 'Install dev-pipeline (default: true)')
|
|
39
39
|
.option('--no-pipeline', 'Disable dev-pipeline')
|
|
40
|
+
.option('--playwright-cli', 'Install playwright-cli browser tool (default: true)')
|
|
41
|
+
.option('--no-playwright-cli', 'Disable playwright-cli installation')
|
|
42
|
+
.option('--open-cli', 'Install opencli browser tool (default: true)')
|
|
43
|
+
.option('--no-open-cli', 'Disable opencli installation')
|
|
40
44
|
.option('--rules <preset>', 'Rules preset: recommended, minimal, or none', 'recommended')
|
|
41
45
|
.option('--ai-cli <command>', 'AI CLI executable command (e.g. cbc, claude, claude-internal)')
|
|
42
46
|
.option('--external-skills <names>', 'Comma-separated external skill names to install (e.g. find-skills,impeccable)')
|
package/bundled/VERSION.json
CHANGED
|
@@ -460,12 +460,14 @@ def process_conditional_blocks(content, resume_phase):
|
|
|
460
460
|
|
|
461
461
|
|
|
462
462
|
def process_mode_blocks(content, pipeline_mode, init_done, critic_enabled=False,
|
|
463
|
-
browser_interaction=False):
|
|
463
|
+
browser_interaction=False, browser_tool="auto"):
|
|
464
464
|
"""Process pipeline mode, init, critic, and browser conditional blocks.
|
|
465
465
|
|
|
466
466
|
Keeps the block matching the current mode, removes the others.
|
|
467
467
|
Handles {{IF_CRITIC_ENABLED}} / {{END_IF_CRITIC_ENABLED}} blocks.
|
|
468
468
|
Handles {{IF_BROWSER_INTERACTION}} / {{END_IF_BROWSER_INTERACTION}} blocks.
|
|
469
|
+
Handles {{IF_BROWSER_TOOL_PLAYWRIGHT}} / {{IF_BROWSER_TOOL_OPENCLI}} /
|
|
470
|
+
{{IF_BROWSER_TOOL_AUTO}} blocks (nested inside browser interaction block).
|
|
469
471
|
"""
|
|
470
472
|
# Handle lite/standard/full blocks
|
|
471
473
|
modes = ["lite", "standard", "full"]
|
|
@@ -527,6 +529,29 @@ def process_mode_blocks(content, pipeline_mode, init_done, critic_enabled=False,
|
|
|
527
529
|
pattern = re.escape(browser_open) + r".*?" + re.escape(browser_close) + r"\n?"
|
|
528
530
|
content = re.sub(pattern, "", content, flags=re.DOTALL)
|
|
529
531
|
|
|
532
|
+
# Browser tool selection blocks (nested inside browser interaction)
|
|
533
|
+
tool_variants = ["PLAYWRIGHT", "OPENCLI", "AUTO"]
|
|
534
|
+
# Map browser_tool value to the variant tag name
|
|
535
|
+
active_variant = {
|
|
536
|
+
"playwright-cli": "PLAYWRIGHT",
|
|
537
|
+
"opencli": "OPENCLI",
|
|
538
|
+
"auto": "AUTO",
|
|
539
|
+
}.get(browser_tool, "AUTO")
|
|
540
|
+
|
|
541
|
+
for variant in tool_variants:
|
|
542
|
+
tool_open = "{{{{IF_BROWSER_TOOL_{}}}}}".format(variant)
|
|
543
|
+
tool_close = "{{{{END_IF_BROWSER_TOOL_{}}}}}".format(variant)
|
|
544
|
+
if variant == active_variant and browser_interaction:
|
|
545
|
+
# Keep content, remove tags
|
|
546
|
+
content = content.replace(tool_open + "\n", "")
|
|
547
|
+
content = content.replace(tool_open, "")
|
|
548
|
+
content = content.replace(tool_close + "\n", "")
|
|
549
|
+
content = content.replace(tool_close, "")
|
|
550
|
+
else:
|
|
551
|
+
# Remove entire block
|
|
552
|
+
pat = re.escape(tool_open) + r".*?" + re.escape(tool_close) + r"\n?"
|
|
553
|
+
content = re.sub(pat, "", content, flags=re.DOTALL)
|
|
554
|
+
|
|
530
555
|
return content
|
|
531
556
|
|
|
532
557
|
|
|
@@ -869,7 +894,8 @@ def _tier_reminders(pipeline_mode, critic_enabled=False):
|
|
|
869
894
|
|
|
870
895
|
|
|
871
896
|
def assemble_sections(pipeline_mode, sections_dir, init_done, is_resume,
|
|
872
|
-
critic_enabled, browser_enabled, retry_count=0
|
|
897
|
+
critic_enabled, browser_enabled, retry_count=0,
|
|
898
|
+
browser_tool="auto"):
|
|
873
899
|
"""Assemble prompt sections based on tier and conditions.
|
|
874
900
|
|
|
875
901
|
Uses Python code for conditional logic instead of regex-based
|
|
@@ -1040,11 +1066,18 @@ def assemble_sections(pipeline_mode, sections_dir, init_done, is_resume,
|
|
|
1040
1066
|
load_section(sections_dir,
|
|
1041
1067
|
"phase-review-agent.md")))
|
|
1042
1068
|
|
|
1043
|
-
# --- Browser Verification (conditional) ---
|
|
1069
|
+
# --- Browser Verification (conditional, tool-aware) ---
|
|
1044
1070
|
if browser_enabled:
|
|
1071
|
+
if browser_tool == "opencli":
|
|
1072
|
+
browser_section_file = "phase-browser-verification-opencli.md"
|
|
1073
|
+
elif browser_tool == "playwright-cli":
|
|
1074
|
+
browser_section_file = "phase-browser-verification.md"
|
|
1075
|
+
else:
|
|
1076
|
+
# "auto" or unknown → let AI choose at runtime
|
|
1077
|
+
browser_section_file = "phase-browser-verification-auto.md"
|
|
1045
1078
|
sections.append(("phase-browser",
|
|
1046
1079
|
load_section(sections_dir,
|
|
1047
|
-
|
|
1080
|
+
browser_section_file)))
|
|
1048
1081
|
|
|
1049
1082
|
# --- Deploy Verification ---
|
|
1050
1083
|
sections.append(("phase-deploy",
|
|
@@ -1289,26 +1322,37 @@ def build_replacements(args, feature, features, global_context, script_dir):
|
|
|
1289
1322
|
)
|
|
1290
1323
|
critic_enabled = False
|
|
1291
1324
|
|
|
1292
|
-
# Browser interaction - extract from feature if present
|
|
1325
|
+
# Browser interaction - extract from feature if present
|
|
1293
1326
|
browser_interaction = feature.get("browser_interaction")
|
|
1294
1327
|
browser_enabled = False
|
|
1295
1328
|
browser_verify_steps = ""
|
|
1329
|
+
browser_tool = "auto" # default: AI chooses at runtime
|
|
1296
1330
|
|
|
1297
1331
|
browser_verify_env = os.environ.get("BROWSER_VERIFY", "").lower()
|
|
1298
1332
|
if browser_verify_env == "false":
|
|
1299
1333
|
browser_interaction = None
|
|
1300
1334
|
|
|
1301
|
-
if browser_interaction and isinstance(browser_interaction,
|
|
1335
|
+
if browser_interaction and isinstance(browser_interaction, bool):
|
|
1336
|
+
# Simple boolean: browser verification enabled, no specific goals
|
|
1337
|
+
browser_enabled = True
|
|
1338
|
+
browser_tool = "auto"
|
|
1339
|
+
browser_verify_steps = (
|
|
1340
|
+
" # (no specific verify goals — explore the app and "
|
|
1341
|
+
"verify the feature works as expected)")
|
|
1342
|
+
elif browser_interaction and isinstance(browser_interaction, dict):
|
|
1343
|
+
# Extract tool preference (playwright-cli / opencli / auto)
|
|
1344
|
+
browser_tool = browser_interaction.get("tool", "auto")
|
|
1345
|
+
if browser_tool not in ("playwright-cli", "opencli", "auto"):
|
|
1346
|
+
LOGGER.warning(
|
|
1347
|
+
"Unknown browser_interaction.tool '%s', defaulting to 'auto'",
|
|
1348
|
+
browser_tool,
|
|
1349
|
+
)
|
|
1350
|
+
browser_tool = "auto"
|
|
1351
|
+
|
|
1302
1352
|
# browser_interaction only needs verify_steps — AI auto-detects
|
|
1303
1353
|
# dev server command, URL, and port from project config
|
|
1304
1354
|
steps = browser_interaction.get("verify_steps", [])
|
|
1305
|
-
if
|
|
1306
|
-
# Simple boolean: browser verification enabled, no specific goals
|
|
1307
|
-
browser_enabled = True
|
|
1308
|
-
browser_verify_steps = (
|
|
1309
|
-
" # (no specific verify goals — explore the app and "
|
|
1310
|
-
"verify the feature works as expected)")
|
|
1311
|
-
elif steps:
|
|
1355
|
+
if steps:
|
|
1312
1356
|
browser_enabled = True
|
|
1313
1357
|
browser_verify_steps = "\n".join(
|
|
1314
1358
|
" # Goal {}: {}".format(i + 1, step)
|
|
@@ -1404,6 +1448,7 @@ def build_replacements(args, feature, features, global_context, script_dir):
|
|
|
1404
1448
|
"{{HAS_SPEC}}": "true" if artifacts["has_spec"] else "false",
|
|
1405
1449
|
"{{HAS_PLAN}}": "true" if artifacts["has_plan"] else "false",
|
|
1406
1450
|
"{{BROWSER_VERIFY_STEPS}}": browser_verify_steps,
|
|
1451
|
+
"{{BROWSER_TOOL}}": browser_tool,
|
|
1407
1452
|
"{{AC_CHECKLIST}}": format_ac_checklist(
|
|
1408
1453
|
feature.get("acceptance_criteria", [])
|
|
1409
1454
|
),
|
|
@@ -1414,10 +1459,11 @@ def build_replacements(args, feature, features, global_context, script_dir):
|
|
|
1414
1459
|
"{{DEV_URL}}": dev_url,
|
|
1415
1460
|
}
|
|
1416
1461
|
|
|
1417
|
-
return replacements, effective_resume, browser_enabled
|
|
1462
|
+
return replacements, effective_resume, browser_enabled, browser_tool
|
|
1418
1463
|
|
|
1419
1464
|
|
|
1420
|
-
def render_template(template_content, replacements, resume_phase,
|
|
1465
|
+
def render_template(template_content, replacements, resume_phase,
|
|
1466
|
+
browser_enabled=False, browser_tool="auto"):
|
|
1421
1467
|
"""Render the template by processing conditionals and replacing placeholders."""
|
|
1422
1468
|
# Step 1: Process fresh_start/resume conditional blocks
|
|
1423
1469
|
content = process_conditional_blocks(template_content, resume_phase)
|
|
@@ -1427,7 +1473,7 @@ def render_template(template_content, replacements, resume_phase, browser_enable
|
|
|
1427
1473
|
init_done = replacements.get("{{INIT_DONE}}", "false") == "true"
|
|
1428
1474
|
critic_enabled = replacements.get("{{CRITIC_ENABLED}}", "false") == "true"
|
|
1429
1475
|
content = process_mode_blocks(content, pipeline_mode, init_done, critic_enabled,
|
|
1430
|
-
browser_enabled)
|
|
1476
|
+
browser_enabled, browser_tool)
|
|
1431
1477
|
|
|
1432
1478
|
# Step 3: Replace all {{PLACEHOLDER}} variables (two passes for nested
|
|
1433
1479
|
# agent prompt templates that may contain their own placeholders)
|
|
@@ -1489,7 +1535,7 @@ def main():
|
|
|
1489
1535
|
global_context = {}
|
|
1490
1536
|
|
|
1491
1537
|
# Build replacements (shared by both code paths)
|
|
1492
|
-
replacements, effective_resume, browser_enabled = build_replacements(
|
|
1538
|
+
replacements, effective_resume, browser_enabled, browser_tool = build_replacements(
|
|
1493
1539
|
args, feature, features, global_context, script_dir
|
|
1494
1540
|
)
|
|
1495
1541
|
|
|
@@ -1514,6 +1560,7 @@ def main():
|
|
|
1514
1560
|
pipeline_mode, sections_dir, init_done, is_resume,
|
|
1515
1561
|
critic_enabled, browser_enabled,
|
|
1516
1562
|
retry_count=int(args.retry_count),
|
|
1563
|
+
browser_tool=browser_tool,
|
|
1517
1564
|
)
|
|
1518
1565
|
rendered = render_from_sections(sections, replacements)
|
|
1519
1566
|
except FileNotFoundError as exc:
|
|
@@ -1552,7 +1599,8 @@ def main():
|
|
|
1552
1599
|
emit_failure("Template error: {}".format(err))
|
|
1553
1600
|
|
|
1554
1601
|
rendered = render_template(
|
|
1555
|
-
template_content, replacements, effective_resume, browser_enabled
|
|
1602
|
+
template_content, replacements, effective_resume, browser_enabled,
|
|
1603
|
+
browser_tool
|
|
1556
1604
|
)
|
|
1557
1605
|
|
|
1558
1606
|
# ── Validate rendered output ───────────────────────────────────────
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"Read {{REVIEWER_SUBAGENT_PATH}}. For feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}):
|
|
2
2
|
1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/spec.md` (if it exists) for goals and acceptance criteria; if spec.md does not exist, read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` Section 1 instead
|
|
3
3
|
2. Read `.prizmkit/specs/{{FEATURE_SLUG}}/plan.md` for architecture decisions and completed tasks
|
|
4
|
-
3.
|
|
5
|
-
4. Run
|
|
6
|
-
5.
|
|
7
|
-
|
|
8
|
-
Report: number of findings found, or 'no findings' if clean."
|
|
4
|
+
3. Run /prizmkit-code-review with artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/. The skill will run its internal review-fix loop (Reviewer → filter → Dev fix, max 3 rounds) and write review-report.md.
|
|
5
|
+
4. Run the full test suite using `{{TEST_CMD}}`. When running tests: `({{TEST_CMD}}) 2>&1 | tee /tmp/review-test-out.txt | tail -20`, then grep `/tmp/review-test-out.txt` for details — do NOT re-run the suite multiple times.
|
|
6
|
+
5. review-report.md will be written to .prizmkit/specs/{{FEATURE_SLUG}}/ by prizmkit-code-review.
|
|
7
|
+
Report: verdict (PASS/NEEDS_FIXES), number of rounds, findings fixed/rejected."
|
|
@@ -32,7 +32,7 @@ Infer what needs to be done from the feature context above and follow the standa
|
|
|
32
32
|
|
|
33
33
|
4. **Test**: Run the project test suite to verify all tests pass with no regressions.
|
|
34
34
|
|
|
35
|
-
5. **Review**: Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` to review changes against the spec
|
|
35
|
+
5. **Review**: Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` to review and auto-fix changes against the spec (internal review-fix loop, max 3 rounds).
|
|
36
36
|
|
|
37
37
|
6. **Retrospective**: Run `/prizmkit-retrospective` to sync `.prizm-docs/` with code changes.
|
|
38
38
|
|
|
@@ -164,9 +164,14 @@ When tests fail, use convergence recovery — keep fixing while progress is bein
|
|
|
164
164
|
|
|
165
165
|
|
|
166
166
|
{{IF_BROWSER_INTERACTION}}
|
|
167
|
-
### Phase 3.5: Browser Verification
|
|
167
|
+
### Phase 3.5: Browser Verification — MANDATORY
|
|
168
168
|
|
|
169
|
-
You MUST execute this phase. Do NOT skip it.
|
|
169
|
+
You MUST execute this phase. Do NOT skip it.
|
|
170
|
+
|
|
171
|
+
**Browser Tool**: {{BROWSER_TOOL}}
|
|
172
|
+
|
|
173
|
+
{{IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
174
|
+
**Using: playwright-cli**
|
|
170
175
|
|
|
171
176
|
**CRITICAL CONSTRAINT — playwright-cli ONLY, NO Playwright MCP**:
|
|
172
177
|
- You MUST use `playwright-cli` (the CLI tool) for ALL browser interactions in this phase
|
|
@@ -253,16 +258,81 @@ Construct your verification workflow based on: (1) the playwright-cli skill docu
|
|
|
253
258
|
1. Close the playwright-cli browser: `playwright-cli close`
|
|
254
259
|
2. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
|
|
255
260
|
3. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
|
|
261
|
+
{{END_IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
262
|
+
{{IF_BROWSER_TOOL_OPENCLI}}
|
|
263
|
+
**Using: opencli** (reuses Chrome logged-in sessions)
|
|
264
|
+
|
|
265
|
+
**CRITICAL CONSTRAINT — opencli browser ONLY**:
|
|
266
|
+
- You MUST use `opencli browser` for ALL browser interactions in this phase
|
|
267
|
+
- All browser actions go through `opencli browser <command>` in the Bash tool
|
|
268
|
+
|
|
269
|
+
**Step 0 — OpenCLI Readiness Check (BLOCKING)**:
|
|
270
|
+
|
|
271
|
+
0a. Check if `opencli` is installed:
|
|
272
|
+
```bash
|
|
273
|
+
which opencli 2>/dev/null && opencli --version 2>/dev/null || echo "NOT_INSTALLED"
|
|
274
|
+
```
|
|
275
|
+
If `NOT_INSTALLED`: `npm install -g @jackwener/opencli@latest`. If installation fails, log `## Browser Verification: SKIPPED — opencli installation failed` and proceed.
|
|
276
|
+
|
|
277
|
+
0b. Verify Browser Bridge: `opencli doctor`. If fails, log skip and proceed.
|
|
278
|
+
|
|
279
|
+
0c. Learn usage: `opencli browser --help 2>/dev/null || opencli --help`
|
|
280
|
+
|
|
281
|
+
**Step 1 — Start Dev Server**: (same port detection as playwright path)
|
|
282
|
+
```bash
|
|
283
|
+
DEV_PORT={{DEV_PORT}}
|
|
284
|
+
if [ "$DEV_PORT" = "{{DEV_PORT}}" ]; then
|
|
285
|
+
DEV_PORT=$(node -e "const s=require('./package.json').scripts.dev; const m=s.match(/-p\s+(\d+)/); console.log(m?m[1]:'')" 2>/dev/null)
|
|
286
|
+
DEV_PORT=${DEV_PORT:-3000}
|
|
287
|
+
fi
|
|
288
|
+
```
|
|
289
|
+
Start server, wait for ready, then: `opencli browser open http://localhost:$DEV_PORT && opencli browser state`
|
|
290
|
+
|
|
291
|
+
**Step 2 — Verification**:
|
|
292
|
+
|
|
293
|
+
Use `opencli browser state` to discover elements with `[N]` indices, then verify:
|
|
294
|
+
{{BROWSER_VERIFY_STEPS}}
|
|
295
|
+
|
|
296
|
+
Chain commands: `opencli browser click <N> && opencli browser wait time 1 && opencli browser state`
|
|
297
|
+
|
|
298
|
+
**Step 3 — Cleanup**:
|
|
299
|
+
1. `opencli browser close`
|
|
300
|
+
2. `kill $DEV_SERVER_PID 2>/dev/null || true`
|
|
301
|
+
3. `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
|
|
302
|
+
{{END_IF_BROWSER_TOOL_OPENCLI}}
|
|
303
|
+
{{IF_BROWSER_TOOL_AUTO}}
|
|
304
|
+
**Tool Selection**: Choose the best browser tool at runtime.
|
|
305
|
+
|
|
306
|
+
**Step 0 — Detect available tools**:
|
|
307
|
+
```bash
|
|
308
|
+
echo "=== playwright-cli ===" && which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
|
|
309
|
+
echo "=== opencli ===" && which opencli 2>/dev/null && opencli --version 2>/dev/null || echo "NOT_INSTALLED"
|
|
310
|
+
```
|
|
311
|
+
If opencli installed: `opencli doctor 2>/dev/null || echo "OPENCLI_BRIDGE_FAILED"`
|
|
312
|
+
|
|
313
|
+
**Decision table**:
|
|
314
|
+
| Condition | Tool |
|
|
315
|
+
|-----------|------|
|
|
316
|
+
| Only playwright-cli available | playwright-cli |
|
|
317
|
+
| Only opencli available (doctor passes) | opencli |
|
|
318
|
+
| Both — local dev server, forms, components | playwright-cli |
|
|
319
|
+
| Both — needs real login state (OAuth/SSO) | opencli |
|
|
320
|
+
| Both — third-party integration verification | opencli |
|
|
321
|
+
| Neither available | Install playwright-cli as default |
|
|
322
|
+
|
|
323
|
+
Then follow the corresponding tool's workflow above (Steps 1-3).
|
|
324
|
+
{{END_IF_BROWSER_TOOL_AUTO}}
|
|
256
325
|
|
|
257
326
|
**Step 4 — Reporting**:
|
|
258
327
|
|
|
259
328
|
Append results to `context-snapshot.md`:
|
|
260
329
|
```
|
|
261
330
|
## Browser Verification
|
|
331
|
+
Tool: <playwright-cli or opencli>
|
|
262
332
|
URL: http://localhost:$DEV_PORT
|
|
263
333
|
Dev Server Command: <actual command used>
|
|
264
|
-
|
|
265
|
-
Steps executed: [list of
|
|
334
|
+
Tool version: <version>
|
|
335
|
+
Steps executed: [list of commands used]
|
|
266
336
|
Screenshot: [path]
|
|
267
337
|
Result: PASS / FAIL (reason)
|
|
268
338
|
Server cleanup: confirmed
|
|
@@ -263,31 +263,35 @@ Prompt:
|
|
|
263
263
|
> "Read {{REVIEWER_SUBAGENT_PATH}}. For feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}):
|
|
264
264
|
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/spec.md` for goals and acceptance criteria
|
|
265
265
|
> 2. Read `.prizmkit/specs/{{FEATURE_SLUG}}/plan.md` for architecture decisions and completed tasks
|
|
266
|
-
> 3.
|
|
267
|
-
> 4. Run
|
|
268
|
-
> 5.
|
|
269
|
-
>
|
|
270
|
-
> Report: number of findings found, or 'no findings' if clean."
|
|
266
|
+
> 3. Run /prizmkit-code-review with artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/. The skill runs an internal review-fix loop (Reviewer → filter → Dev fix, max 3 rounds) and writes review-report.md.
|
|
267
|
+
> 4. Run the full test suite using `{{TEST_CMD}}`. When running: `({{TEST_CMD}}) 2>&1 | tee /tmp/review-test-out.txt | tail -20`, then grep the file for details — do NOT re-run the suite multiple times.
|
|
268
|
+
> 5. review-report.md will be written to .prizmkit/specs/{{FEATURE_SLUG}}/ by prizmkit-code-review.
|
|
269
|
+
> Report: verdict (PASS/NEEDS_FIXES), number of rounds, findings fixed/rejected."
|
|
271
270
|
|
|
272
271
|
Wait for Reviewer to return.
|
|
273
272
|
|
|
274
273
|
**Gate Check — Review Report**:
|
|
275
274
|
After Reviewer agent returns, verify the review report was written:
|
|
276
275
|
```bash
|
|
277
|
-
grep -q "##
|
|
276
|
+
grep -q "## Verdict" .prizmkit/specs/{{FEATURE_SLUG}}/review-report.md && echo "GATE:PASS" || echo "GATE:MISSING"
|
|
278
277
|
```
|
|
279
|
-
If GATE:MISSING — send message to Reviewer (re-spawn if needed): "Write review-report.md to .prizmkit/specs/{{FEATURE_SLUG}}
|
|
278
|
+
If GATE:MISSING — send message to Reviewer (re-spawn if needed): "Write review-report.md to .prizmkit/specs/{{FEATURE_SLUG}}/."
|
|
280
279
|
|
|
281
|
-
|
|
280
|
+
Read `review-report.md` and check the Verdict:
|
|
281
|
+
- `PASS` → proceed to next phase
|
|
282
|
+
- `NEEDS_FIXES` → the skill exhausted its max rounds; log the remaining findings and proceed
|
|
282
283
|
|
|
283
|
-
-
|
|
284
|
-
|
|
285
|
-
**CP-3**: Tests pass, no unresolved findings.
|
|
284
|
+
**CP-3**: Tests pass, review complete.
|
|
286
285
|
|
|
287
286
|
{{IF_BROWSER_INTERACTION}}
|
|
288
|
-
### Phase 5.5: Browser Verification
|
|
287
|
+
### Phase 5.5: Browser Verification — MANDATORY
|
|
288
|
+
|
|
289
|
+
You MUST execute this phase. Do NOT skip it.
|
|
289
290
|
|
|
290
|
-
|
|
291
|
+
**Browser Tool**: {{BROWSER_TOOL}}
|
|
292
|
+
|
|
293
|
+
{{IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
294
|
+
**Using: playwright-cli**
|
|
291
295
|
|
|
292
296
|
**CRITICAL CONSTRAINT — playwright-cli ONLY, NO Playwright MCP**:
|
|
293
297
|
- You MUST use `playwright-cli` (the CLI tool) for ALL browser interactions in this phase
|
|
@@ -374,16 +378,81 @@ Construct your verification workflow based on: (1) the playwright-cli skill docu
|
|
|
374
378
|
1. Close the playwright-cli browser: `playwright-cli close`
|
|
375
379
|
2. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
|
|
376
380
|
3. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
|
|
381
|
+
{{END_IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
382
|
+
{{IF_BROWSER_TOOL_OPENCLI}}
|
|
383
|
+
**Using: opencli** (reuses Chrome logged-in sessions)
|
|
384
|
+
|
|
385
|
+
**CRITICAL CONSTRAINT — opencli browser ONLY**:
|
|
386
|
+
- You MUST use `opencli browser` for ALL browser interactions in this phase
|
|
387
|
+
- All browser actions go through `opencli browser <command>` in the Bash tool
|
|
388
|
+
|
|
389
|
+
**Step 0 — OpenCLI Readiness Check (BLOCKING)**:
|
|
390
|
+
|
|
391
|
+
0a. Check if `opencli` is installed:
|
|
392
|
+
```bash
|
|
393
|
+
which opencli 2>/dev/null && opencli --version 2>/dev/null || echo "NOT_INSTALLED"
|
|
394
|
+
```
|
|
395
|
+
If `NOT_INSTALLED`: `npm install -g @jackwener/opencli@latest`. If installation fails, log `## Browser Verification: SKIPPED — opencli installation failed` and proceed.
|
|
396
|
+
|
|
397
|
+
0b. Verify Browser Bridge: `opencli doctor`. If fails, log skip and proceed.
|
|
398
|
+
|
|
399
|
+
0c. Learn usage: `opencli browser --help 2>/dev/null || opencli --help`
|
|
400
|
+
|
|
401
|
+
**Step 1 — Start Dev Server**: (same port detection as playwright path)
|
|
402
|
+
```bash
|
|
403
|
+
DEV_PORT={{DEV_PORT}}
|
|
404
|
+
if [ "$DEV_PORT" = "{{DEV_PORT}}" ]; then
|
|
405
|
+
DEV_PORT=$(node -e "const s=require('./package.json').scripts.dev; const m=s.match(/-p\s+(\d+)/); console.log(m?m[1]:'')" 2>/dev/null)
|
|
406
|
+
DEV_PORT=${DEV_PORT:-3000}
|
|
407
|
+
fi
|
|
408
|
+
```
|
|
409
|
+
Start server, wait for ready, then: `opencli browser open http://localhost:$DEV_PORT && opencli browser state`
|
|
410
|
+
|
|
411
|
+
**Step 2 — Verification**:
|
|
412
|
+
|
|
413
|
+
Use `opencli browser state` to discover elements with `[N]` indices, then verify:
|
|
414
|
+
{{BROWSER_VERIFY_STEPS}}
|
|
415
|
+
|
|
416
|
+
Chain commands: `opencli browser click <N> && opencli browser wait time 1 && opencli browser state`
|
|
417
|
+
|
|
418
|
+
**Step 3 — Cleanup**:
|
|
419
|
+
1. `opencli browser close`
|
|
420
|
+
2. `kill $DEV_SERVER_PID 2>/dev/null || true`
|
|
421
|
+
3. `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
|
|
422
|
+
{{END_IF_BROWSER_TOOL_OPENCLI}}
|
|
423
|
+
{{IF_BROWSER_TOOL_AUTO}}
|
|
424
|
+
**Tool Selection**: Choose the best browser tool at runtime.
|
|
425
|
+
|
|
426
|
+
**Step 0 — Detect available tools**:
|
|
427
|
+
```bash
|
|
428
|
+
echo "=== playwright-cli ===" && which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
|
|
429
|
+
echo "=== opencli ===" && which opencli 2>/dev/null && opencli --version 2>/dev/null || echo "NOT_INSTALLED"
|
|
430
|
+
```
|
|
431
|
+
If opencli installed: `opencli doctor 2>/dev/null || echo "OPENCLI_BRIDGE_FAILED"`
|
|
432
|
+
|
|
433
|
+
**Decision table**:
|
|
434
|
+
| Condition | Tool |
|
|
435
|
+
|-----------|------|
|
|
436
|
+
| Only playwright-cli available | playwright-cli |
|
|
437
|
+
| Only opencli available (doctor passes) | opencli |
|
|
438
|
+
| Both — local dev server, forms, components | playwright-cli |
|
|
439
|
+
| Both — needs real login state (OAuth/SSO) | opencli |
|
|
440
|
+
| Both — third-party integration verification | opencli |
|
|
441
|
+
| Neither available | Install playwright-cli as default |
|
|
442
|
+
|
|
443
|
+
Then follow the corresponding tool's workflow above (Steps 1-3).
|
|
444
|
+
{{END_IF_BROWSER_TOOL_AUTO}}
|
|
377
445
|
|
|
378
446
|
**Step 4 — Reporting**:
|
|
379
447
|
|
|
380
448
|
Append results to `context-snapshot.md`:
|
|
381
449
|
```
|
|
382
450
|
## Browser Verification
|
|
451
|
+
Tool: <playwright-cli or opencli>
|
|
383
452
|
URL: http://localhost:$DEV_PORT
|
|
384
453
|
Dev Server Command: <actual command used>
|
|
385
|
-
|
|
386
|
-
Steps executed: [list of
|
|
454
|
+
Tool version: <version>
|
|
455
|
+
Steps executed: [list of commands used]
|
|
387
456
|
Screenshot: [path]
|
|
388
457
|
Result: PASS / FAIL (reason)
|
|
389
458
|
Server cleanup: confirmed
|
|
@@ -328,38 +328,35 @@ Prompt:
|
|
|
328
328
|
> "Read {{REVIEWER_SUBAGENT_PATH}}. For feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}):
|
|
329
329
|
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/spec.md` for goals and acceptance criteria
|
|
330
330
|
> 2. Read `.prizmkit/specs/{{FEATURE_SLUG}}/plan.md` for architecture decisions and completed tasks
|
|
331
|
-
> 3.
|
|
332
|
-
> 4. Run
|
|
333
|
-
> 5.
|
|
334
|
-
>
|
|
335
|
-
> Report: number of findings found, or 'no findings' if clean."
|
|
331
|
+
> 3. Run /prizmkit-code-review with artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/. The skill runs an internal review-fix loop (Reviewer → filter → Dev fix, max 3 rounds) and writes review-report.md.
|
|
332
|
+
> 4. Run the full test suite using `{{TEST_CMD}}`. When running tests: `({{TEST_CMD}}) 2>&1 | tee /tmp/review-test-out.txt | tail -20`, then grep `/tmp/review-test-out.txt` for details — do NOT re-run the suite multiple times.
|
|
333
|
+
> 5. review-report.md will be written to .prizmkit/specs/{{FEATURE_SLUG}}/ by prizmkit-code-review.
|
|
334
|
+
> Report: verdict (PASS/NEEDS_FIXES), number of rounds, findings fixed/rejected."
|
|
336
335
|
|
|
337
336
|
Wait for Reviewer to return.
|
|
338
337
|
|
|
339
338
|
**Gate Check — Review Report**:
|
|
340
339
|
After Reviewer agent returns, verify the review report was written:
|
|
341
340
|
```bash
|
|
342
|
-
grep -q "##
|
|
341
|
+
grep -q "## Verdict" .prizmkit/specs/{{FEATURE_SLUG}}/review-report.md && echo "GATE:PASS" || echo "GATE:MISSING"
|
|
343
342
|
```
|
|
344
|
-
If GATE:MISSING — send message to Reviewer (re-spawn if needed): "Write review-report.md to .prizmkit/specs/{{FEATURE_SLUG}}
|
|
343
|
+
If GATE:MISSING — send message to Reviewer (re-spawn if needed): "Write review-report.md to .prizmkit/specs/{{FEATURE_SLUG}}/."
|
|
345
344
|
|
|
346
|
-
|
|
345
|
+
Read `review-report.md` and check the Verdict:
|
|
346
|
+
- `PASS` → proceed to next phase
|
|
347
|
+
- `NEEDS_FIXES` → the skill exhausted its max rounds; log the remaining findings and proceed
|
|
347
348
|
|
|
348
|
-
-
|
|
349
|
-
> "Read {{DEV_SUBAGENT_PATH}}. Fix issues for feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
|
|
350
|
-
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/review-report.md` — contains structured Fix Instructions with exact steps.
|
|
351
|
-
> 2. Follow Fix Instructions in order (respect Depends On / Blocks dependencies). Each finding has: Root Cause, Fix Strategy, Code Guidance, and Verification criteria.
|
|
352
|
-
> 3. After each fix, run the Verification command listed in that finding to confirm it works.
|
|
353
|
-
> 4. Run `{{TEST_CMD}}` to verify no regressions.
|
|
354
|
-
> 5. Do NOT execute any git commands."
|
|
355
|
-
Then re-run Review (max 3 rounds).
|
|
356
|
-
|
|
357
|
-
**CP-3**: Integration tests pass, no unresolved findings.
|
|
349
|
+
**CP-3**: Integration tests pass, review complete.
|
|
358
350
|
|
|
359
351
|
{{IF_BROWSER_INTERACTION}}
|
|
360
|
-
### Phase 5.5: Browser Verification
|
|
352
|
+
### Phase 5.5: Browser Verification — MANDATORY
|
|
353
|
+
|
|
354
|
+
You MUST execute this phase. Do NOT skip it.
|
|
361
355
|
|
|
362
|
-
|
|
356
|
+
**Browser Tool**: {{BROWSER_TOOL}}
|
|
357
|
+
|
|
358
|
+
{{IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
359
|
+
**Using: playwright-cli**
|
|
363
360
|
|
|
364
361
|
**CRITICAL CONSTRAINT — playwright-cli ONLY, NO Playwright MCP**:
|
|
365
362
|
- You MUST use `playwright-cli` (the CLI tool) for ALL browser interactions in this phase
|
|
@@ -446,16 +443,81 @@ Construct your verification workflow based on: (1) the playwright-cli skill docu
|
|
|
446
443
|
1. Close the playwright-cli browser: `playwright-cli close`
|
|
447
444
|
2. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
|
|
448
445
|
3. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
|
|
446
|
+
{{END_IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
447
|
+
{{IF_BROWSER_TOOL_OPENCLI}}
|
|
448
|
+
**Using: opencli** (reuses Chrome logged-in sessions)
|
|
449
|
+
|
|
450
|
+
**CRITICAL CONSTRAINT — opencli browser ONLY**:
|
|
451
|
+
- You MUST use `opencli browser` for ALL browser interactions in this phase
|
|
452
|
+
- All browser actions go through `opencli browser <command>` in the Bash tool
|
|
453
|
+
|
|
454
|
+
**Step 0 — OpenCLI Readiness Check (BLOCKING)**:
|
|
455
|
+
|
|
456
|
+
0a. Check if `opencli` is installed:
|
|
457
|
+
```bash
|
|
458
|
+
which opencli 2>/dev/null && opencli --version 2>/dev/null || echo "NOT_INSTALLED"
|
|
459
|
+
```
|
|
460
|
+
If `NOT_INSTALLED`: `npm install -g @jackwener/opencli@latest`. If installation fails, log `## Browser Verification: SKIPPED — opencli installation failed` and proceed.
|
|
461
|
+
|
|
462
|
+
0b. Verify Browser Bridge: `opencli doctor`. If fails, log skip and proceed.
|
|
463
|
+
|
|
464
|
+
0c. Learn usage: `opencli browser --help 2>/dev/null || opencli --help`
|
|
465
|
+
|
|
466
|
+
**Step 1 — Start Dev Server**: (same port detection as playwright path)
|
|
467
|
+
```bash
|
|
468
|
+
DEV_PORT={{DEV_PORT}}
|
|
469
|
+
if [ "$DEV_PORT" = "{{DEV_PORT}}" ]; then
|
|
470
|
+
DEV_PORT=$(node -e "const s=require('./package.json').scripts.dev; const m=s.match(/-p\s+(\d+)/); console.log(m?m[1]:'')" 2>/dev/null)
|
|
471
|
+
DEV_PORT=${DEV_PORT:-3000}
|
|
472
|
+
fi
|
|
473
|
+
```
|
|
474
|
+
Start server, wait for ready, then: `opencli browser open http://localhost:$DEV_PORT && opencli browser state`
|
|
475
|
+
|
|
476
|
+
**Step 2 — Verification**:
|
|
477
|
+
|
|
478
|
+
Use `opencli browser state` to discover elements with `[N]` indices, then verify:
|
|
479
|
+
{{BROWSER_VERIFY_STEPS}}
|
|
480
|
+
|
|
481
|
+
Chain commands: `opencli browser click <N> && opencli browser wait time 1 && opencli browser state`
|
|
482
|
+
|
|
483
|
+
**Step 3 — Cleanup**:
|
|
484
|
+
1. `opencli browser close`
|
|
485
|
+
2. `kill $DEV_SERVER_PID 2>/dev/null || true`
|
|
486
|
+
3. `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
|
|
487
|
+
{{END_IF_BROWSER_TOOL_OPENCLI}}
|
|
488
|
+
{{IF_BROWSER_TOOL_AUTO}}
|
|
489
|
+
**Tool Selection**: Choose the best browser tool at runtime.
|
|
490
|
+
|
|
491
|
+
**Step 0 — Detect available tools**:
|
|
492
|
+
```bash
|
|
493
|
+
echo "=== playwright-cli ===" && which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
|
|
494
|
+
echo "=== opencli ===" && which opencli 2>/dev/null && opencli --version 2>/dev/null || echo "NOT_INSTALLED"
|
|
495
|
+
```
|
|
496
|
+
If opencli installed: `opencli doctor 2>/dev/null || echo "OPENCLI_BRIDGE_FAILED"`
|
|
497
|
+
|
|
498
|
+
**Decision table**:
|
|
499
|
+
| Condition | Tool |
|
|
500
|
+
|-----------|------|
|
|
501
|
+
| Only playwright-cli available | playwright-cli |
|
|
502
|
+
| Only opencli available (doctor passes) | opencli |
|
|
503
|
+
| Both — local dev server, forms, components | playwright-cli |
|
|
504
|
+
| Both — needs real login state (OAuth/SSO) | opencli |
|
|
505
|
+
| Both — third-party integration verification | opencli |
|
|
506
|
+
| Neither available | Install playwright-cli as default |
|
|
507
|
+
|
|
508
|
+
Then follow the corresponding tool's workflow above (Steps 1-3).
|
|
509
|
+
{{END_IF_BROWSER_TOOL_AUTO}}
|
|
449
510
|
|
|
450
511
|
**Step 4 — Reporting**:
|
|
451
512
|
|
|
452
513
|
Append results to `context-snapshot.md`:
|
|
453
514
|
```
|
|
454
515
|
## Browser Verification
|
|
516
|
+
Tool: <playwright-cli or opencli>
|
|
455
517
|
URL: http://localhost:$DEV_PORT
|
|
456
518
|
Dev Server Command: <actual command used>
|
|
457
|
-
|
|
458
|
-
Steps executed: [list of
|
|
519
|
+
Tool version: <version>
|
|
520
|
+
Steps executed: [list of commands used]
|
|
459
521
|
Screenshot: [path]
|
|
460
522
|
Result: PASS / FAIL (reason)
|
|
461
523
|
Server cleanup: confirmed
|
|
@@ -154,11 +154,11 @@ After implement completes, verify:
|
|
|
154
154
|
If `FAST_PATH=true` (≤ 2 tasks, obvious root cause), skip this phase entirely.
|
|
155
155
|
|
|
156
156
|
Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/bugfix/{{BUG_ID}}/`:
|
|
157
|
-
-
|
|
158
|
-
- If
|
|
159
|
-
- If
|
|
157
|
+
- The skill runs an internal review-fix loop (Reviewer → filter → Dev fix, max 3 rounds) and writes review-report.md
|
|
158
|
+
- If PASS: proceed
|
|
159
|
+
- If NEEDS_FIXES: the skill exhausted its max rounds; log remaining findings and proceed
|
|
160
160
|
|
|
161
|
-
**CP-3**: Code review
|
|
161
|
+
**CP-3**: Code review complete, all tests green.
|
|
162
162
|
|
|
163
163
|
**Checkpoint update**: Set step `prizmkit-code-review` to `"completed"`.
|
|
164
164
|
|
|
@@ -172,11 +172,17 @@
|
|
|
172
172
|
},
|
|
173
173
|
"browser_interaction": {
|
|
174
174
|
"type": "object",
|
|
175
|
-
"description": "Browser verification config for features with UI.
|
|
175
|
+
"description": "Browser verification config for features with UI. Supports playwright-cli and opencli. AI auto-detects dev server command, URL, and port from project config at runtime.",
|
|
176
176
|
"properties": {
|
|
177
|
+
"tool": {
|
|
178
|
+
"type": "string",
|
|
179
|
+
"enum": ["playwright-cli", "opencli", "auto"],
|
|
180
|
+
"default": "auto",
|
|
181
|
+
"description": "Browser tool to use. 'auto' (default) = AI chooses at runtime. 'playwright-cli' = local dev server verification in isolated browser. 'opencli' = reuses Chrome logged-in session, ideal for verifying third-party integrations or OAuth flows."
|
|
182
|
+
},
|
|
177
183
|
"verify_steps": {
|
|
178
184
|
"type": "array",
|
|
179
|
-
"description": "Verification goals describing WHAT to verify (not HOW). AI decides concrete
|
|
185
|
+
"description": "Verification goals describing WHAT to verify (not HOW). AI decides concrete browser tool actions at runtime based on actual code and snapshot. If omitted, AI explores the app and verifies the feature works.",
|
|
180
186
|
"items": {
|
|
181
187
|
"type": "string"
|
|
182
188
|
}
|