prizmkit 1.1.108 → 1.1.110

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.
Files changed (46) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/dev-pipeline/prizmkit_runtime/cli.py +20 -0
  3. package/bundled/dev-pipeline/prizmkit_runtime/commands.py +1 -0
  4. package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +21 -0
  5. package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +1 -0
  6. package/bundled/dev-pipeline/prizmkit_runtime/platform_detection.py +208 -0
  7. package/bundled/dev-pipeline/prizmkit_runtime/runtime_helper.py +508 -0
  8. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +3 -1
  9. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +3 -1
  10. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +3 -1
  11. package/bundled/dev-pipeline/scripts/prizmkit-runtime-helper.py +27 -0
  12. package/bundled/dev-pipeline/scripts/utils.py +48 -77
  13. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +44 -71
  14. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +48 -75
  15. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +52 -78
  16. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +2 -2
  17. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +2 -2
  18. package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +1 -1
  19. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +8 -8
  20. package/bundled/dev-pipeline/templates/sections/phase-browser-verification-auto.md +33 -55
  21. package/bundled/dev-pipeline/templates/sections/phase-browser-verification-opencli.md +28 -33
  22. package/bundled/dev-pipeline/templates/sections/phase-browser-verification.md +22 -62
  23. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +2 -2
  24. package/bundled/dev-pipeline/templates/sections/phase-commit.md +1 -1
  25. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-base.md +1 -1
  26. package/bundled/dev-pipeline/templates/sections/phase-critic-plan-full.md +1 -1
  27. package/bundled/dev-pipeline/templates/sections/phase-critic-plan.md +1 -1
  28. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +1 -1
  29. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +1 -1
  30. package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +1 -1
  31. package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +1 -1
  32. package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +2 -2
  33. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +1 -1
  34. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +1 -1
  35. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +7 -6
  36. package/bundled/dev-pipeline/templates/sections/phase0-init.md +1 -1
  37. package/bundled/dev-pipeline/templates/sections/subagent-timeout-recovery.md +1 -1
  38. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +1 -1
  39. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +1 -1
  40. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +152 -3
  41. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +2 -1
  42. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +2 -1
  43. package/bundled/dev-pipeline/tests/test_runtime_helper.py +211 -0
  44. package/bundled/dev-pipeline/tests/test_unified_cli.py +5 -0
  45. package/bundled/skills/_metadata.json +1 -1
  46. package/package.json +1 -1
@@ -52,15 +52,15 @@ You are running in **headless non-interactive mode** with a FINITE context windo
52
52
 
53
53
  1. **context-snapshot.md is your single source of truth** — After Phase 1 builds it, ALWAYS read context-snapshot.md instead of re-reading individual source files
54
54
  2. **Never re-read your own writes** — After you create/modify a file, do NOT read it back to verify. Trust your write was correct.
55
- 3. **Never re-read unmodified files** — Once you have read a file into context, do NOT read it again unless it was modified by an Edit/Write operation after your last read. Use `grep -n '<pattern>' <file>` or `sed -n '<start>,<end>p' <file>` for targeted line lookups instead of full-file Read. Before issuing a Read, ask yourself: "Have I read this file before, and has it changed since?" If the answer is "no, it hasn't changed" — do NOT read it. This applies to all files including those summarized in context-snapshot.md Section 4. Subagents (Critic, Reviewer) must receive context-snapshot.md and rely on it rather than independently re-reading the same files the orchestrator already read.
55
+ 3. **Never re-read unmodified files** — Once you have read a file into context, do NOT read it again unless it was modified by an Edit/Write operation after your last read. Use platform file/search tools for targeted lookup; when shell-free helper lookup is needed, run `{{RUNTIME_HELPER_CMD}} text search <file> --pattern "<pattern>" --json`, then read only the smallest bounded range with the platform file-reading tool instead of full-file Read. Before issuing a Read, ask yourself: "Have I read this file before, and has it changed since?" If the answer is "no, it hasn't changed" — do NOT read it. This applies to all files including those summarized in context-snapshot.md Section 4. Subagents (Critic, Reviewer) must receive context-snapshot.md and rely on it rather than independently re-reading the same files the orchestrator already read.
56
56
  4. **Stay focused** — Do NOT explore code unrelated to this feature. No curiosity-driven reads.
57
57
  4. **One task at a time** — In Phase 4 (implement), complete and test one task before starting the next.
58
- 5. **Minimize tool output** — Never load full command output into context. First capture to a temp file (`cmd 2>&1 | tee /tmp/out.txt | tail -20`), then scan the head/tail to identify relevant fields, and use targeted filtering (`grep`, `sed`, `awk`) to extract only the information needed for the current task. Only read the filtered result — never the raw full output.
58
+ 5. **Minimize tool output** — Never load full command output into context. First capture command output to a temp file using the command/tool output option or the host-appropriate redirection, then inspect only the final relevant lines and use targeted search helpers to extract the information needed for the current task. Only read the filtered result — never the raw full output.
59
59
  6. **No intermediate commits** — Do NOT run `git add`/`git commit` during Phase 1-5. All changes are committed once at the end in Phase 6 via `/prizmkit-committer`.
60
- 7. **Capture test output once** — When running test suites, always use `<test-command> 2>&1 | tee /tmp/test-out.txt | tail -20`. Then grep `/tmp/test-out.txt` for details. Never re-run the suite just to apply a different filter.
60
+ 7. **Capture test output once** — When running test suites, capture output once to `/tmp/test-out.txt` using the command/tool output option or the host-appropriate redirection, surface only the final relevant lines, then search `/tmp/test-out.txt` for details. Never re-run the suite just to apply a different filter.
61
61
  9. **Package version verification (BLOCKING)** — Verify dependency versions via registry query before writing them. NEVER guess.
62
62
  10. **Build artifact hygiene** — After build/compile, ensure output is in `.gitignore`.
63
- 11. **Read offset safety (BLOCKING)** — If Read returns "shorter than offset"/"File is empty"/"Wasted call" — do NOT retry same offset. Run `wc -l <file>` to get real line count, then `sed -n` for exact range. 2 consecutive offset errors → STOP Reading that file. Never guess offsets `grep -n '<anchor>'` first.
63
+ 11. **Read offset safety (BLOCKING)** — If Read returns "shorter than offset"/"File is empty"/"Wasted call" — do NOT retry same offset. Use the platform file-reading tool to refresh bounded line information, or locate an anchor with `{{RUNTIME_HELPER_CMD}} text search <file> --pattern "<anchor>" --json` before reading a small bounded range. 2 consecutive offset errors → STOP Reading that file. Never guess offsets or prescribe POSIX-only lookup commands.
64
64
 
65
65
  ---
66
66
 
@@ -78,7 +78,7 @@ You are running in **headless non-interactive mode** with a FINITE context windo
78
78
  ## Subagent Timeout Recovery
79
79
 
80
80
  If any agent times out:
81
- 1. `ls .prizmkit/specs/{{FEATURE_SLUG}}/` — check what exists
81
+ 1. `{{RUNTIME_HELPER_CMD}} artifact list .prizmkit/specs/{{FEATURE_SLUG}}` — check what exists
82
82
  2. If `context-snapshot.md` exists: open recovery prompt with `"Read .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md for project context and any Implementation Log/Review Notes from previous agents. Run git diff HEAD to see actual code changes already made. Do NOT re-read individual source files unless the File Manifest directs you to."` + only remaining steps + `model: "lite"`
83
83
  3. Max 2 retries per phase. After 2 failures, orchestrator completes the work directly and appends a Recovery Note to context-snapshot.md.
84
84
 
@@ -89,7 +89,7 @@ If any agent times out:
89
89
  {{IF_INIT_NEEDED}}
90
90
  ### Phase 0: Project Bootstrap
91
91
  - Run `/prizmkit-init` (invoke the prizmkit-init skill)
92
- - Run `python3 {{INIT_SCRIPT_PATH}} --project-root {{PROJECT_ROOT}} --feature-id {{FEATURE_ID}} --feature-slug {{FEATURE_SLUG}}`
92
+ - Run `{{PYTHON_CMD}} {{INIT_SCRIPT_PATH}} --project-root {{PROJECT_ROOT}} --feature-id {{FEATURE_ID}} --feature-slug {{FEATURE_SLUG}}`
93
93
  - **CP-0**: Verify `.prizmkit/prizm-docs/root.prizm`, `.prizmkit/config.json` exist
94
94
  {{END_IF_INIT_NEEDED}}
95
95
  {{IF_INIT_DONE}}
@@ -101,30 +101,30 @@ If any agent times out:
101
101
 
102
102
  **Check for previous failure log:**
103
103
  ```bash
104
- cat .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md 2>/dev/null || echo "NO_PREVIOUS_FAILURE"
104
+ {{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md --exists-marker PREVIOUS_FAILURE --missing-marker NO_PREVIOUS_FAILURE
105
105
  ```
106
- If failure-log.md exists:
107
- - Read ROOT_CAUSE and SUGGESTION — adjust your approach accordingly
106
+ If the helper prints `PREVIOUS_FAILURE`:
107
+ - Read `failure-log.md` ROOT_CAUSE and SUGGESTION — adjust your approach accordingly
108
108
  - Read DISCOVERED_TRAPS — if any are genuine, inject into .prizmkit/prizm-docs/ during Phase 6 retrospective
109
109
  - Do NOT delete failure-log.md until this session completes all phases and commits successfully
110
110
 
111
111
  ```bash
112
- ls .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md 2>/dev/null && echo "EXISTS" || echo "MISSING"
112
+ {{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md
113
113
  ```
114
114
 
115
115
  If MISSING — build it now:
116
116
  1. Read `.prizmkit/prizm-docs/root.prizm` and relevant L1/L2 prizm docs
117
- 2. Detect source code directories: read KEY_FILES and STRUCTURE sections from `root.prizm` to identify where source code lives (e.g. `src/`, `app/`, `lib/`, `cmd/`, `packages/`, or project root). If `root.prizm` is missing, scan the project tree:
117
+ 2. Detect source code directories from KEY_FILES and STRUCTURE sections in `root.prizm`; if root docs are unavailable, use the helper to list likely source files:
118
118
  ```bash
119
- find . -maxdepth 2 -type f \( -name "*.js" -o -name "*.ts" -o -name "*.py" -o -name "*.go" -o -name "*.java" -o -name "*.rb" -o -name "*.rs" \) -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/vendor/*' | head -30
119
+ {{RUNTIME_HELPER_CMD}} artifact source-files . --json
120
120
  ```
121
- Identify the top-level source directories from the results.
121
+ Identify the top-level source directories from the helper output.
122
122
  3. Scan the detected source directories for files related to this feature; read each one
123
123
  4. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
124
124
  - **Section 1 — Feature Brief**: feature description + acceptance criteria (copy from above)
125
- - **Section 2 — Project Structure**: run the following to get a visual directory tree, then paste output:
125
+ - **Section 2 — Project Structure**: run the helper to get a visual directory tree, then paste output:
126
126
  ```bash
127
- find . -maxdepth 2 -type d -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/__pycache__/*' -not -path '*/vendor/*' | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
127
+ {{RUNTIME_HELPER_CMD}} artifact tree . --max-depth 2
128
128
  ```
129
129
  - **Section 3 — Key TRAPS & RULES**: relevant TRAPS/RULES from prizm-docs (not full copies)
130
130
  - **Section 4 — File Manifest**: For each file relevant to this feature, list: file path, why it's needed (modify/reference/test), key interface signatures (function names + params + return types). Do NOT include full file content — agents read files on-demand. Format:
@@ -144,7 +144,7 @@ If MISSING — build it now:
144
144
  ### Phase 2: Plan & Tasks (you, the orchestrator)
145
145
 
146
146
  ```bash
147
- ls .prizmkit/specs/{{FEATURE_SLUG}}/plan.md 2>/dev/null
147
+ {{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}/plan.md
148
148
  ```
149
149
 
150
150
  If either missing, run `/prizmkit-plan` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` to generate missing files:
@@ -183,7 +183,7 @@ Wait for Reviewer to return.
183
183
 
184
184
  **Guard**: Verify critic agent file exists before spawning:
185
185
  ```bash
186
- ls {{CRITIC_SUBAGENT_PATH}} 2>/dev/null && echo "CRITIC:READY" || echo "CRITIC:MISSING"
186
+ {{RUNTIME_HELPER_CMD}} artifact exists {{CRITIC_SUBAGENT_PATH}} --exists-marker CRITIC:READY --missing-marker CRITIC:MISSING
187
187
  ```
188
188
  If CRITIC:MISSING — skip Phase 3.5 entirely and proceed to Phase 4. Log: "Critic agent not installed — skipping Plan Challenge."
189
189
 
@@ -264,7 +264,7 @@ After all critics return, read all 3 reports:
264
264
 
265
265
  Before starting, check plan.md Tasks:
266
266
  ```bash
267
- grep -c '^\- \[ \]' .prizmkit/specs/{{FEATURE_SLUG}}/plan.md 2>/dev/null || true
267
+ {{RUNTIME_HELPER_CMD}} text count .prizmkit/specs/{{FEATURE_SLUG}}/plan.md --pattern "- [ ]"
268
268
  ```
269
269
  - If result is `0` (all tasks already `[x]`) → **SKIP to Review**.
270
270
  - If non-zero → implement directly below.
@@ -314,7 +314,7 @@ The skill runs an internal review-fix loop (Reviewer Agent → filter → orches
314
314
  **Gate Check — Review Report**:
315
315
  After `/prizmkit-code-review` returns, verify the review report:
316
316
  ```bash
317
- grep -q "## Verdict" .prizmkit/specs/{{FEATURE_SLUG}}/review-report.md && echo "GATE:PASS" || echo "GATE:MISSING"
317
+ {{RUNTIME_HELPER_CMD}} text contains .prizmkit/specs/{{FEATURE_SLUG}}/review-report.md --pattern "## Verdict"
318
318
  ```
319
319
  If GATE:MISSING:
320
320
  - Do not re-run `/prizmkit-code-review` in an unbounded report-repair loop.
@@ -334,8 +334,8 @@ Run `/prizmkit-test scope=this-change artifact_dir=.prizmkit/specs/{{FEATURE_SLU
334
334
 
335
335
  Before invoking the skill, create a current-run marker so stale reports are ignored:
336
336
  ```bash
337
- mkdir -p .prizmkit/specs/{{FEATURE_SLUG}}
338
- touch .prizmkit/specs/{{FEATURE_SLUG}}/.prizmkit-test-started
337
+ {{RUNTIME_HELPER_CMD}} artifact ensure-dir .prizmkit/specs/{{FEATURE_SLUG}}
338
+ {{RUNTIME_HELPER_CMD}} artifact touch .prizmkit/specs/{{FEATURE_SLUG}}/.prizmkit-test-started
339
339
  ```
340
340
 
341
341
  Gate requirements:
@@ -366,13 +366,13 @@ You MUST execute this phase. Do NOT skip it.
366
366
 
367
367
  0a. Check if `playwright-cli` is installed:
368
368
  ```bash
369
- which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
369
+ {{RUNTIME_HELPER_CMD}} executable version playwright-cli --arg=--version
370
370
  ```
371
371
  If output is `NOT_INSTALLED`, install it:
372
372
  ```bash
373
373
  npm install -g @playwright/cli@latest
374
374
  ```
375
- Then verify installation succeeded: `playwright-cli --version`. If installation fails, log `## Browser Verification: SKIPPED — playwright-cli installation failed` in context-snapshot.md and proceed to the next phase.
375
+ Then verify installation succeeded: `{{RUNTIME_HELPER_CMD}} executable version playwright-cli --arg=--version`. If installation fails, log `## Browser Verification: SKIPPED — playwright-cli installation failed` in context-snapshot.md and proceed to the next phase.
376
376
 
377
377
  0b. Learn playwright-cli usage (run once per session):
378
378
  ```bash
@@ -381,21 +381,9 @@ playwright-cli --help
381
381
 
382
382
  0c. Check if playwright-cli skill is installed for the current AI platform:
383
383
  ```bash
384
- CURRENT_PLATFORM=""
385
- if which claude >/dev/null 2>&1; then
386
- CURRENT_PLATFORM="claude"; SKILL_DIR="$HOME/.claude/skills"
387
- elif which cbc >/dev/null 2>&1; then
388
- CURRENT_PLATFORM="codebuddy"; SKILL_DIR="$HOME/.cbc/skills"
389
- else
390
- CURRENT_PLATFORM="unknown"
391
- fi
392
- if [ -d "$SKILL_DIR/playwright-cli" ] || ls "$SKILL_DIR"/playwright* 2>/dev/null | grep -q .; then
393
- echo "SKILL_EXISTS"
394
- else
395
- echo "SKILL_MISSING"
396
- fi
384
+ {{RUNTIME_HELPER_CMD}} platform skill playwright-cli --prefix
397
385
  ```
398
- If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform is NOT claude, copy installed skill from `$HOME/.claude/skills/playwright-cli` to `$SKILL_DIR/playwright-cli`.
386
+ If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform is NOT claude, copy the installed skill from the Claude user skills directory to the path shown by the helper output for the current platform.
399
387
 
400
388
  0d. Read the installed playwright-cli skill (SKILL.md) for workflow guidance. Use its recommended patterns to construct your verification flow.
401
389
 
@@ -404,29 +392,17 @@ If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform i
404
392
  You know this project's tech stack. Detect and start the dev server yourself:
405
393
 
406
394
  1. Identify the dev server start command from project config (`package.json` scripts, `Makefile`, `docker-compose.yml`, etc.)
407
- 2. **Detect the dev server port** use the pre-detected port from pipeline if available, otherwise extract from project config. Do NOT hardcode or guess the port:
408
- ```bash
409
- DEV_PORT={{DEV_PORT}}
410
- if [ "$DEV_PORT" = "{{DEV_PORT}}" ]; then
411
- DEV_PORT=$(node -e "const s=require('./package.json').scripts.dev; const m=s.match(/-p\s+(\d+)/); console.log(m?m[1]:'')")
412
- if [ -z "$DEV_PORT" ]; then
413
- DEV_PORT=$(echo "$NEXT_PUBLIC_SITE_URL" | sed -nE 's|.*:([0-9]+).*|\1|p')
414
- fi
415
- DEV_PORT=${DEV_PORT:-3000}
416
- fi
417
- echo "Detected DEV_PORT=$DEV_PORT"
418
- ```
395
+ 2. Determine the dev server port from the pre-detected pipeline value (`{{DEV_PORT}}`) or project config. Do NOT hardcode or guess the port. Record it as `DEV_PORT` in your notes.
419
396
  3. Verify the port is available:
420
397
  ```bash
421
- lsof -ti:$DEV_PORT 2>/dev/null && echo "PORT_IN_USE" || echo "PORT_FREE"
398
+ {{RUNTIME_HELPER_CMD}} port check {{DEV_PORT}}
422
399
  ```
423
400
  4. Start the dev server in background, capture PID:
424
401
  ```bash
425
- <start-command> &
426
- DEV_SERVER_PID=$!
402
+ {{RUNTIME_HELPER_CMD}} process start --pid-file .prizmkit/state/browser-dev-server.pid -- <start-command tokens>
427
403
  ```
428
- 5. Wait for server to be ready: poll `http://localhost:$DEV_PORT` with `curl -s -o /dev/null -w "%{http_code}"` until it returns 200 or 302 (max 30 seconds, 2s interval)
429
- 6. Open the app in playwright-cli: `playwright-cli open http://localhost:$DEV_PORT`
404
+ 5. Wait for server to be ready: run `{{RUNTIME_HELPER_CMD}} web wait-ready --url http://localhost:{{DEV_PORT}} --timeout 30 --interval 2`
405
+ 6. Open the app in playwright-cli: `playwright-cli open http://localhost:{{DEV_PORT}}`
430
406
  7. If the page requires authentication, use playwright-cli to register a test user and log in first
431
407
 
432
408
  **Step 2 — Verification**:
@@ -439,8 +415,8 @@ Construct your verification workflow based on: (1) the playwright-cli skill docu
439
415
  **Step 3 — Cleanup (REQUIRED — you started it, you stop it)**:
440
416
 
441
417
  1. Close the playwright-cli browser: `playwright-cli close`
442
- 2. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
443
- 3. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
418
+ 2. Kill the dev server process: `{{RUNTIME_HELPER_CMD}} process cleanup-pid <pid-from-.prizmkit/state/browser-dev-server.pid>`
419
+ 3. Verify port is released: `{{RUNTIME_HELPER_CMD}} port check {{DEV_PORT}}`
444
420
  {{END_IF_BROWSER_TOOL_PLAYWRIGHT}}
445
421
  {{IF_BROWSER_TOOL_OPENCLI}}
446
422
  **Using: opencli** (reuses Chrome logged-in sessions)
@@ -453,45 +429,42 @@ Construct your verification workflow based on: (1) the playwright-cli skill docu
453
429
 
454
430
  0a. Check if `opencli` is installed:
455
431
  ```bash
456
- which opencli 2>/dev/null && opencli --version 2>/dev/null || echo "NOT_INSTALLED"
432
+ {{RUNTIME_HELPER_CMD}} executable version opencli --arg=--version
457
433
  ```
458
434
  If `NOT_INSTALLED`: `npm install -g @jackwener/opencli@latest`. If installation fails, log `## Browser Verification: SKIPPED — opencli installation failed` and proceed.
459
435
 
460
436
  0b. Verify Browser Bridge: `opencli doctor`. If fails, log skip and proceed.
461
437
 
462
- 0c. Learn usage: `opencli browser --help 2>/dev/null || opencli --help`
438
+ 0c. Learn usage: `opencli browser --help`
463
439
 
464
- **Step 1 — Start Dev Server**: (same port detection as playwright path)
465
- ```bash
466
- DEV_PORT={{DEV_PORT}}
467
- if [ "$DEV_PORT" = "{{DEV_PORT}}" ]; then
468
- 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)
469
- DEV_PORT=${DEV_PORT:-3000}
470
- fi
471
- ```
472
- Start server, wait for ready, then: `opencli browser open http://localhost:$DEV_PORT && opencli browser state`
440
+ **Step 1 — Start Dev Server**:
441
+ 1. Determine `DEV_PORT` from the pipeline value (`{{DEV_PORT}}`) or project config; do not guess.
442
+ 2. Verify port available: `{{RUNTIME_HELPER_CMD}} port check <DEV_PORT>`
443
+ 3. Start server: `{{RUNTIME_HELPER_CMD}} process start --pid-file .prizmkit/state/browser-dev-server.pid -- <start-command tokens>`
444
+ 4. Wait for ready: `{{RUNTIME_HELPER_CMD}} web wait-ready --url http://localhost:<DEV_PORT> --timeout 30 --interval 2`
445
+ 5. Open: `opencli browser open http://localhost:<DEV_PORT>`; then inspect: `opencli browser state`
473
446
 
474
447
  **Step 2 — Verification**:
475
448
 
476
449
  Use `opencli browser state` to discover elements with `[N]` indices, then verify:
477
450
  {{BROWSER_VERIFY_STEPS}}
478
451
 
479
- Chain commands: `opencli browser click <N> && opencli browser wait time 1 && opencli browser state`
452
+ Run page-changing commands sequentially, then run `opencli browser state` to refresh indices.
480
453
 
481
454
  **Step 3 — Cleanup**:
482
455
  1. `opencli browser close`
483
- 2. `kill $DEV_SERVER_PID 2>/dev/null || true`
484
- 3. `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
456
+ 2. `{{RUNTIME_HELPER_CMD}} process cleanup-pid <pid-from-.prizmkit/state/browser-dev-server.pid>`
457
+ 3. `{{RUNTIME_HELPER_CMD}} port check {{DEV_PORT}}`
485
458
  {{END_IF_BROWSER_TOOL_OPENCLI}}
486
459
  {{IF_BROWSER_TOOL_AUTO}}
487
460
  **Tool Selection**: Choose the best browser tool at runtime.
488
461
 
489
462
  **Step 0 — Detect available tools**:
490
463
  ```bash
491
- echo "=== playwright-cli ===" && which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
492
- echo "=== opencli ===" && which opencli 2>/dev/null && opencli --version 2>/dev/null || echo "NOT_INSTALLED"
464
+ {{RUNTIME_HELPER_CMD}} executable version playwright-cli --arg=--version
465
+ {{RUNTIME_HELPER_CMD}} executable version opencli --arg=--version
493
466
  ```
494
- If opencli installed: `opencli doctor 2>/dev/null || echo "OPENCLI_BRIDGE_FAILED"`
467
+ If opencli is installed, run `opencli doctor`. If it fails, mark OpenCLI unusable and choose playwright-cli or skip browser verification.
495
468
 
496
469
  **Decision table**:
497
470
  | Condition | Tool |
@@ -512,7 +485,7 @@ Append results to `context-snapshot.md`:
512
485
  ```
513
486
  ## Browser Verification
514
487
  Tool: <playwright-cli or opencli>
515
- URL: http://localhost:$DEV_PORT
488
+ URL: http://localhost:{{DEV_PORT}}
516
489
  Dev Server Command: <actual command used>
517
490
  Tool version: <version>
518
491
  Steps executed: [list of commands used]
@@ -550,7 +523,7 @@ This single commit includes: feature code + tests + .prizmkit/prizm-docs/ update
550
523
  ```bash
551
524
  git status --short
552
525
  ```
553
- Working tree MUST be clean after this step. If any feature-related files remain, stage them into the SAME commit via `git add <file> && git commit --amend --no-edit`, do NOT create a separate commit.
526
+ Working tree MUST be clean after this step. If any feature-related files remain, stage them explicitly and amend the SAME commit with `git commit --amend --no-edit`; do NOT create a separate commit.
554
527
 
555
528
  **Exception**: `session-summary.md` in the artifact directory is a local cross-session artifact generated by `/prizmkit-committer` — it is NOT committed to git. Ignore it in the clean-tree check.
556
529
 
@@ -52,15 +52,15 @@ You are running in **headless non-interactive mode** with a FINITE context windo
52
52
 
53
53
  1. **context-snapshot.md is your single source of truth** — After Phase 1-2 builds it, ALWAYS read context-snapshot.md instead of re-reading individual source files
54
54
  2. **Never re-read your own writes** — After you create/modify a file, do NOT read it back to verify. Trust your write was correct.
55
- 3. **Never re-read unmodified files** — Once you have read a file into context, do NOT read it again unless it was modified by an Edit/Write operation after your last read. Use `grep -n '<pattern>' <file>` or `sed -n '<start>,<end>p' <file>` for targeted line lookups instead of full-file Read. Before issuing a Read, ask yourself: "Have I read this file before, and has it changed since?" If the answer is "no, it hasn't changed" — do NOT read it. This applies to all files including those summarized in context-snapshot.md Section 4. Subagents (Critic, Reviewer) must receive context-snapshot.md and rely on it rather than independently re-reading the same files the orchestrator already read.
55
+ 3. **Never re-read unmodified files** — Once you have read a file into context, do NOT read it again unless it was modified by an Edit/Write operation after your last read. Use platform file/search tools for targeted lookup; when shell-free helper lookup is needed, run `{{RUNTIME_HELPER_CMD}} text search <file> --pattern "<pattern>" --json`, then read only the smallest bounded range with the platform file-reading tool instead of full-file Read. Before issuing a Read, ask yourself: "Have I read this file before, and has it changed since?" If the answer is "no, it hasn't changed" — do NOT read it. This applies to all files including those summarized in context-snapshot.md Section 4. Subagents (Critic, Reviewer) must receive context-snapshot.md and rely on it rather than independently re-reading the same files the orchestrator already read.
56
56
  4. **Stay focused** — Do NOT explore code unrelated to this feature. No curiosity-driven reads.
57
57
  4. **One task at a time** — In Phase 4 (implement), complete and test one task before starting the next.
58
- 5. **Minimize tool output** — Never load full command output into context. First capture to a temp file (`cmd 2>&1 | tee /tmp/out.txt | tail -20`), then scan the head/tail to identify relevant fields, and use targeted filtering (`grep`, `sed`, `awk`) to extract only the information needed for the current task. Only read the filtered result — never the raw full output.
58
+ 5. **Minimize tool output** — Never load full command output into context. First capture command output to a temp file using the command/tool output option or the host-appropriate redirection, then inspect only the final relevant lines and use targeted search helpers to extract the information needed for the current task. Only read the filtered result — never the raw full output.
59
59
  6. **No intermediate commits** — Do NOT run `git add`/`git commit` during Phase 1-5. All changes are committed once at the end in Phase 6 via `/prizmkit-committer`.
60
60
  7. **Batch independent operations** — Issue multiple independent `Write`/`Read` calls in a single message turn when they have no dependencies. Combine multiple `mkdir -p` into one command. Never run `npm test` twice just to apply a different grep filter — capture output to `/tmp/test-out.txt` once and grep the file.
61
61
  9. **Package version verification (BLOCKING)** — Verify dependency versions via registry query before writing them. NEVER guess.
62
62
  10. **Build artifact hygiene** — After build/compile, ensure output is in `.gitignore`.
63
- 11. **Read offset safety (BLOCKING)** — If Read returns "shorter than offset"/"File is empty"/"Wasted call" — do NOT retry same offset. Run `wc -l <file>` to get real line count, then `sed -n` for exact range. 2 consecutive offset errors → STOP Reading that file. Never guess offsets `grep -n '<anchor>'` first.
63
+ 11. **Read offset safety (BLOCKING)** — If Read returns "shorter than offset"/"File is empty"/"Wasted call" — do NOT retry same offset. Use the platform file-reading tool to refresh bounded line information, or locate an anchor with `{{RUNTIME_HELPER_CMD}} text search <file> --pattern "<anchor>" --json` before reading a small bounded range. 2 consecutive offset errors → STOP Reading that file. Never guess offsets or prescribe POSIX-only lookup commands.
64
64
 
65
65
  ---
66
66
 
@@ -79,7 +79,7 @@ You are running in **headless non-interactive mode** with a FINITE context windo
79
79
  ## Subagent Timeout Recovery
80
80
 
81
81
  If any agent times out:
82
- 1. `ls .prizmkit/specs/{{FEATURE_SLUG}}/` — check what exists
82
+ 1. `{{RUNTIME_HELPER_CMD}} artifact list .prizmkit/specs/{{FEATURE_SLUG}}` — check what exists
83
83
  2. If `context-snapshot.md` exists: open recovery prompt with `"Read .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md for project context and any Implementation Log/Review Notes from previous agents. Run git diff HEAD to see actual code changes already made. Do NOT re-read individual source files unless the File Manifest directs you to."` + only remaining steps + `model: "lite"`
84
84
  3. Max 2 retries per phase. After 2 failures, orchestrator completes the work directly and appends a Recovery Note to context-snapshot.md.
85
85
 
@@ -90,7 +90,7 @@ If any agent times out:
90
90
  {{IF_INIT_NEEDED}}
91
91
  ### Phase 0: Project Bootstrap
92
92
  - Run `/prizmkit-init` (invoke the prizmkit-init skill)
93
- - Run `python3 {{INIT_SCRIPT_PATH}} --project-root {{PROJECT_ROOT}} --feature-id {{FEATURE_ID}} --feature-slug {{FEATURE_SLUG}}`
93
+ - Run `{{PYTHON_CMD}} {{INIT_SCRIPT_PATH}} --project-root {{PROJECT_ROOT}} --feature-id {{FEATURE_ID}} --feature-slug {{FEATURE_SLUG}}`
94
94
  - **CP-0**: Verify `.prizmkit/prizm-docs/root.prizm`, `.prizmkit/config.json` exist
95
95
  {{END_IF_INIT_NEEDED}}
96
96
  {{IF_INIT_DONE}}
@@ -98,14 +98,14 @@ If any agent times out:
98
98
  ### Step 1: Initialize
99
99
 
100
100
  1. Run init script:
101
- `python3 {{INIT_SCRIPT_PATH}} --project-root {{PROJECT_ROOT}} --feature-id {{FEATURE_ID}} --feature-slug {{FEATURE_SLUG}}`
101
+ `{{PYTHON_CMD}} {{INIT_SCRIPT_PATH}} --project-root {{PROJECT_ROOT}} --feature-id {{FEATURE_ID}} --feature-slug {{FEATURE_SLUG}}`
102
102
 
103
103
  2. Check for existing artifacts:
104
- `ls .prizmkit/specs/{{FEATURE_SLUG}}/ 2>/dev/null`
104
+ `{{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}`
105
105
 
106
106
  {{IF_FRESH_START}}
107
107
  ```bash
108
- python3 {{INIT_SCRIPT_PATH}} --project-root {{PROJECT_ROOT}} --feature-id {{FEATURE_ID}} --feature-slug {{FEATURE_SLUG}}
108
+ {{PYTHON_CMD}} {{INIT_SCRIPT_PATH}} --project-root {{PROJECT_ROOT}} --feature-id {{FEATURE_ID}} --feature-slug {{FEATURE_SLUG}}
109
109
  ```
110
110
  {{END_IF_FRESH_START}}
111
111
 
@@ -113,30 +113,30 @@ python3 {{INIT_SCRIPT_PATH}} --project-root {{PROJECT_ROOT}} --feature-id {{FEAT
113
113
 
114
114
  Check existing artifacts first:
115
115
  ```bash
116
- ls .prizmkit/specs/{{FEATURE_SLUG}}/ 2>/dev/null
116
+ {{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}
117
117
  ```
118
118
 
119
119
  - Both (spec.md, plan.md) exist → **SKIP to CP-1**
120
120
  - `context-snapshot.md` exists → use it directly, skip Phase 1
121
121
  - Some missing → generate only missing files
122
122
 
123
- Before planning, check whether feature code already exists in the project (search in source directories identified from `root.prizm` or the project tree scan):
123
+ Before planning, check whether feature code already exists in the project (use the helper to search source directories identified from `root.prizm` or the project tree scan):
124
124
  ```bash
125
- grep -r "{{FEATURE_SLUG}}" . --include="*.js" --include="*.ts" --include="*.py" --include="*.go" --include="*.java" --include="*.rb" --include="*.rs" -l --exclude-dir=node_modules --exclude-dir=.git --exclude-dir=dist --exclude-dir=build --exclude-dir=vendor --exclude-dir=.prizmkit 2>/dev/null | head -20
125
+ {{RUNTIME_HELPER_CMD}} text search . --pattern "{{FEATURE_SLUG}}" --json
126
126
  ```
127
127
 
128
- Record result as `EXISTING_CODE` (list of files, or empty).
128
+ Record result as `EXISTING_CODE` (helper `match` entries for source files, or empty; ignore `.prizmkit/` artifact matches).
129
129
 
130
130
  If `EXISTING_CODE` is non-empty: your spec/plan/tasks must reflect this existing implementation — document what exists, identify gaps, do NOT re-implement what is already done.
131
131
 
132
132
  **Step A — Build Context Snapshot** (skip if `context-snapshot.md` already exists):
133
133
 
134
134
  1. Read `.prizmkit/prizm-docs/root.prizm` and relevant L1/L2 prizm docs
135
- 2. Detect source code directories: read KEY_FILES and STRUCTURE sections from `root.prizm` to identify where source code lives (e.g. `src/`, `app/`, `lib/`, `cmd/`, `packages/`, or project root). If `root.prizm` is missing, scan the project tree:
135
+ 2. Detect source code directories from KEY_FILES and STRUCTURE sections in `root.prizm`; if root docs are unavailable, use the helper to list likely source files:
136
136
  ```bash
137
- find . -maxdepth 2 -type f \( -name "*.js" -o -name "*.ts" -o -name "*.py" -o -name "*.go" -o -name "*.java" -o -name "*.rb" -o -name "*.rs" \) -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/vendor/*' | head -30
137
+ {{RUNTIME_HELPER_CMD}} artifact source-files . --json
138
138
  ```
139
- Identify the top-level source directories from the results.
139
+ Identify the top-level source directories from the helper output.
140
140
  3. Scan the detected source directories for files related to this feature; read each one
141
141
  4. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
142
142
  - **Section 1 — Feature Brief**: feature description (2-3 lines) + acceptance criteria (copy from above)
@@ -155,14 +155,15 @@ If `EXISTING_CODE` is non-empty: your spec/plan/tasks must reflect this existing
155
155
 
156
156
  ### Known TRAPS (from .prizmkit/prizm-docs/)
157
157
  - <trap entries extracted from L1/L2 docs>
158
- 4. Confirm: `ls .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`
158
+ 4. Confirm: `{{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`
159
159
 
160
160
  **After Step A**: Use context-snapshot.md Section 4 File Manifest to guide targeted file reads. Do NOT scan directories or read unrelated files.
161
161
 
162
162
  **Step B — Planning Artifacts** (generate only missing files):
163
163
 
164
164
  ```bash
165
- ls .prizmkit/specs/{{FEATURE_SLUG}}/spec.md .prizmkit/specs/{{FEATURE_SLUG}}/plan.md 2>/dev/null
165
+ {{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}/spec.md
166
+ {{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}/plan.md
166
167
  ```
167
168
 
168
169
  - spec.md missing: Run `/prizmkit-plan` → generate spec.md. Resolve uncertain requirements from the feature description, existing code, and conservative existing-project patterns.
@@ -202,7 +203,7 @@ Wait for Reviewer to return.
202
203
 
203
204
  **Guard**: Verify critic agent file exists before spawning:
204
205
  ```bash
205
- ls {{CRITIC_SUBAGENT_PATH}} 2>/dev/null && echo "CRITIC:READY" || echo "CRITIC:MISSING"
206
+ {{RUNTIME_HELPER_CMD}} artifact exists {{CRITIC_SUBAGENT_PATH}} --exists-marker CRITIC:READY --missing-marker CRITIC:MISSING
206
207
  ```
207
208
  If CRITIC:MISSING — skip Phase 3.5 entirely and proceed to Phase 4. Log: "Critic agent not installed — skipping Plan Challenge."
208
209
 
@@ -258,7 +259,7 @@ After all critics return, read all 3 reports:
258
259
 
259
260
  Before starting, check plan.md Tasks:
260
261
  ```bash
261
- grep -c '^\- \[ \]' .prizmkit/specs/{{FEATURE_SLUG}}/plan.md 2>/dev/null || true
262
+ {{RUNTIME_HELPER_CMD}} text count .prizmkit/specs/{{FEATURE_SLUG}}/plan.md --pattern "- [ ]"
262
263
  ```
263
264
  - If result is `0` (all tasks already `[x]`) → **SKIP to Review**.
264
265
  - If non-zero → implement directly below.
@@ -308,7 +309,7 @@ The skill runs an internal review-fix loop (Reviewer Agent → filter → orches
308
309
  **Gate Check — Review Report**:
309
310
  After `/prizmkit-code-review` returns, verify the review report:
310
311
  ```bash
311
- grep -q "## Verdict" .prizmkit/specs/{{FEATURE_SLUG}}/review-report.md && echo "GATE:PASS" || echo "GATE:MISSING"
312
+ {{RUNTIME_HELPER_CMD}} text contains .prizmkit/specs/{{FEATURE_SLUG}}/review-report.md --pattern "## Verdict"
312
313
  ```
313
314
  If GATE:MISSING:
314
315
  - Do not re-run `/prizmkit-code-review` in an unbounded report-repair loop.
@@ -328,8 +329,8 @@ Run `/prizmkit-test scope=this-change artifact_dir=.prizmkit/specs/{{FEATURE_SLU
328
329
 
329
330
  Before invoking the skill, create a current-run marker so stale reports are ignored:
330
331
  ```bash
331
- mkdir -p .prizmkit/specs/{{FEATURE_SLUG}}
332
- touch .prizmkit/specs/{{FEATURE_SLUG}}/.prizmkit-test-started
332
+ {{RUNTIME_HELPER_CMD}} artifact ensure-dir .prizmkit/specs/{{FEATURE_SLUG}}
333
+ {{RUNTIME_HELPER_CMD}} artifact touch .prizmkit/specs/{{FEATURE_SLUG}}/.prizmkit-test-started
333
334
  ```
334
335
 
335
336
  Gate requirements:
@@ -360,13 +361,13 @@ You MUST execute this phase. Do NOT skip it.
360
361
 
361
362
  0a. Check if `playwright-cli` is installed:
362
363
  ```bash
363
- which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
364
+ {{RUNTIME_HELPER_CMD}} executable version playwright-cli --arg=--version
364
365
  ```
365
366
  If output is `NOT_INSTALLED`, install it:
366
367
  ```bash
367
368
  npm install -g @playwright/cli@latest
368
369
  ```
369
- Then verify installation succeeded: `playwright-cli --version`. If installation fails, log `## Browser Verification: SKIPPED — playwright-cli installation failed` in context-snapshot.md and proceed to the next phase.
370
+ Then verify installation succeeded: `{{RUNTIME_HELPER_CMD}} executable version playwright-cli --arg=--version`. If installation fails, log `## Browser Verification: SKIPPED — playwright-cli installation failed` in context-snapshot.md and proceed to the next phase.
370
371
 
371
372
  0b. Learn playwright-cli usage (run once per session):
372
373
  ```bash
@@ -375,21 +376,9 @@ playwright-cli --help
375
376
 
376
377
  0c. Check if playwright-cli skill is installed for the current AI platform:
377
378
  ```bash
378
- CURRENT_PLATFORM=""
379
- if which claude >/dev/null 2>&1; then
380
- CURRENT_PLATFORM="claude"; SKILL_DIR="$HOME/.claude/skills"
381
- elif which cbc >/dev/null 2>&1; then
382
- CURRENT_PLATFORM="codebuddy"; SKILL_DIR="$HOME/.cbc/skills"
383
- else
384
- CURRENT_PLATFORM="unknown"
385
- fi
386
- if [ -d "$SKILL_DIR/playwright-cli" ] || ls "$SKILL_DIR"/playwright* 2>/dev/null | grep -q .; then
387
- echo "SKILL_EXISTS"
388
- else
389
- echo "SKILL_MISSING"
390
- fi
379
+ {{RUNTIME_HELPER_CMD}} platform skill playwright-cli --prefix
391
380
  ```
392
- If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform is NOT claude, copy installed skill from `$HOME/.claude/skills/playwright-cli` to `$SKILL_DIR/playwright-cli`.
381
+ If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform is NOT claude, copy the installed skill from the Claude user skills directory to the path shown by the helper output for the current platform.
393
382
 
394
383
  0d. Read the installed playwright-cli skill (SKILL.md) for workflow guidance. Use its recommended patterns to construct your verification flow.
395
384
 
@@ -398,29 +387,17 @@ If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform i
398
387
  You know this project's tech stack. Detect and start the dev server yourself:
399
388
 
400
389
  1. Identify the dev server start command from project config (`package.json` scripts, `Makefile`, `docker-compose.yml`, etc.)
401
- 2. **Detect the dev server port** use the pre-detected port from pipeline if available, otherwise extract from project config. Do NOT hardcode or guess the port:
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]:'')")
406
- if [ -z "$DEV_PORT" ]; then
407
- DEV_PORT=$(echo "$NEXT_PUBLIC_SITE_URL" | sed -nE 's|.*:([0-9]+).*|\1|p')
408
- fi
409
- DEV_PORT=${DEV_PORT:-3000}
410
- fi
411
- echo "Detected DEV_PORT=$DEV_PORT"
412
- ```
390
+ 2. Determine the dev server port from the pre-detected pipeline value (`{{DEV_PORT}}`) or project config. Do NOT hardcode or guess the port. Record it as `DEV_PORT` in your notes.
413
391
  3. Verify the port is available:
414
392
  ```bash
415
- lsof -ti:$DEV_PORT 2>/dev/null && echo "PORT_IN_USE" || echo "PORT_FREE"
393
+ {{RUNTIME_HELPER_CMD}} port check {{DEV_PORT}}
416
394
  ```
417
395
  4. Start the dev server in background, capture PID:
418
396
  ```bash
419
- <start-command> &
420
- DEV_SERVER_PID=$!
397
+ {{RUNTIME_HELPER_CMD}} process start --pid-file .prizmkit/state/browser-dev-server.pid -- <start-command tokens>
421
398
  ```
422
- 5. Wait for server to be ready: poll `http://localhost:$DEV_PORT` with `curl -s -o /dev/null -w "%{http_code}"` until it returns 200 or 302 (max 30 seconds, 2s interval)
423
- 6. Open the app in playwright-cli: `playwright-cli open http://localhost:$DEV_PORT`
399
+ 5. Wait for server to be ready: run `{{RUNTIME_HELPER_CMD}} web wait-ready --url http://localhost:{{DEV_PORT}} --timeout 30 --interval 2`
400
+ 6. Open the app in playwright-cli: `playwright-cli open http://localhost:{{DEV_PORT}}`
424
401
  7. If the page requires authentication, use playwright-cli to register a test user and log in first
425
402
 
426
403
  **Step 2 — Verification**:
@@ -433,8 +410,8 @@ Construct your verification workflow based on: (1) the playwright-cli skill docu
433
410
  **Step 3 — Cleanup (REQUIRED — you started it, you stop it)**:
434
411
 
435
412
  1. Close the playwright-cli browser: `playwright-cli close`
436
- 2. Kill the dev server process: `kill $DEV_SERVER_PID 2>/dev/null || true`
437
- 3. Verify port is released: `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
413
+ 2. Kill the dev server process: `{{RUNTIME_HELPER_CMD}} process cleanup-pid <pid-from-.prizmkit/state/browser-dev-server.pid>`
414
+ 3. Verify port is released: `{{RUNTIME_HELPER_CMD}} port check {{DEV_PORT}}`
438
415
  {{END_IF_BROWSER_TOOL_PLAYWRIGHT}}
439
416
  {{IF_BROWSER_TOOL_OPENCLI}}
440
417
  **Using: opencli** (reuses Chrome logged-in sessions)
@@ -447,45 +424,42 @@ Construct your verification workflow based on: (1) the playwright-cli skill docu
447
424
 
448
425
  0a. Check if `opencli` is installed:
449
426
  ```bash
450
- which opencli 2>/dev/null && opencli --version 2>/dev/null || echo "NOT_INSTALLED"
427
+ {{RUNTIME_HELPER_CMD}} executable version opencli --arg=--version
451
428
  ```
452
429
  If `NOT_INSTALLED`: `npm install -g @jackwener/opencli@latest`. If installation fails, log `## Browser Verification: SKIPPED — opencli installation failed` and proceed.
453
430
 
454
431
  0b. Verify Browser Bridge: `opencli doctor`. If fails, log skip and proceed.
455
432
 
456
- 0c. Learn usage: `opencli browser --help 2>/dev/null || opencli --help`
433
+ 0c. Learn usage: `opencli browser --help`
457
434
 
458
- **Step 1 — Start Dev Server**: (same port detection as playwright path)
459
- ```bash
460
- DEV_PORT={{DEV_PORT}}
461
- if [ "$DEV_PORT" = "{{DEV_PORT}}" ]; then
462
- 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)
463
- DEV_PORT=${DEV_PORT:-3000}
464
- fi
465
- ```
466
- Start server, wait for ready, then: `opencli browser open http://localhost:$DEV_PORT && opencli browser state`
435
+ **Step 1 — Start Dev Server**:
436
+ 1. Determine `DEV_PORT` from the pipeline value (`{{DEV_PORT}}`) or project config; do not guess.
437
+ 2. Verify port available: `{{RUNTIME_HELPER_CMD}} port check <DEV_PORT>`
438
+ 3. Start server: `{{RUNTIME_HELPER_CMD}} process start --pid-file .prizmkit/state/browser-dev-server.pid -- <start-command tokens>`
439
+ 4. Wait for ready: `{{RUNTIME_HELPER_CMD}} web wait-ready --url http://localhost:<DEV_PORT> --timeout 30 --interval 2`
440
+ 5. Open: `opencli browser open http://localhost:<DEV_PORT>`; then inspect: `opencli browser state`
467
441
 
468
442
  **Step 2 — Verification**:
469
443
 
470
444
  Use `opencli browser state` to discover elements with `[N]` indices, then verify:
471
445
  {{BROWSER_VERIFY_STEPS}}
472
446
 
473
- Chain commands: `opencli browser click <N> && opencli browser wait time 1 && opencli browser state`
447
+ Run page-changing commands sequentially, then run `opencli browser state` to refresh indices.
474
448
 
475
449
  **Step 3 — Cleanup**:
476
450
  1. `opencli browser close`
477
- 2. `kill $DEV_SERVER_PID 2>/dev/null || true`
478
- 3. `lsof -ti:$DEV_PORT | xargs kill -9 2>/dev/null || true`
451
+ 2. `{{RUNTIME_HELPER_CMD}} process cleanup-pid <pid-from-.prizmkit/state/browser-dev-server.pid>`
452
+ 3. `{{RUNTIME_HELPER_CMD}} port check {{DEV_PORT}}`
479
453
  {{END_IF_BROWSER_TOOL_OPENCLI}}
480
454
  {{IF_BROWSER_TOOL_AUTO}}
481
455
  **Tool Selection**: Choose the best browser tool at runtime.
482
456
 
483
457
  **Step 0 — Detect available tools**:
484
458
  ```bash
485
- echo "=== playwright-cli ===" && which playwright-cli 2>/dev/null && playwright-cli --version 2>/dev/null || echo "NOT_INSTALLED"
486
- echo "=== opencli ===" && which opencli 2>/dev/null && opencli --version 2>/dev/null || echo "NOT_INSTALLED"
459
+ {{RUNTIME_HELPER_CMD}} executable version playwright-cli --arg=--version
460
+ {{RUNTIME_HELPER_CMD}} executable version opencli --arg=--version
487
461
  ```
488
- If opencli installed: `opencli doctor 2>/dev/null || echo "OPENCLI_BRIDGE_FAILED"`
462
+ If opencli is installed, run `opencli doctor`. If it fails, mark OpenCLI unusable and choose playwright-cli or skip browser verification.
489
463
 
490
464
  **Decision table**:
491
465
  | Condition | Tool |
@@ -506,7 +480,7 @@ Append results to `context-snapshot.md`:
506
480
  ```
507
481
  ## Browser Verification
508
482
  Tool: <playwright-cli or opencli>
509
- URL: http://localhost:$DEV_PORT
483
+ URL: http://localhost:{{DEV_PORT}}
510
484
  Dev Server Command: <actual command used>
511
485
  Tool version: <version>
512
486
  Steps executed: [list of commands used]
@@ -528,9 +502,9 @@ If verification fails, log the failure details but continue to commit. Failures
528
502
  - Complex bugs (multi-module, cascading): Use `/prizmkit-plan` with `artifact_dir=.prizmkit/bugfix/<BUG_ID>/`.
529
503
  - Commit prefix: `fix(<scope>):` (not `feat:`).
530
504
 
531
- **6a.** Check if feature already committed:
505
+ **6a.** Check if feature already committed by inspecting recent git history for `{{FEATURE_ID}}`:
532
506
  ```bash
533
- git log --oneline | grep "{{FEATURE_ID}}" | head -3
507
+ git log --oneline
534
508
  ```
535
509
  - If a commit for `{{FEATURE_ID}}` already exists → **skip 6d** (do NOT run /prizmkit-committer, do NOT run git reset, do NOT stage or unstage anything). Proceed directly to 6e Final verification.
536
510
  - If no existing commit → proceed normally with 6b–6d.
@@ -559,7 +533,7 @@ This single commit includes: feature code + tests + .prizmkit/prizm-docs/ update
559
533
  ```bash
560
534
  git status --short
561
535
  ```
562
- Working tree MUST be clean after this step. If any feature-related files remain, stage them into the SAME commit via `git add <file> && git commit --amend --no-edit`, do NOT create a separate commit.
536
+ Working tree MUST be clean after this step. If any feature-related files remain, stage them explicitly and amend the SAME commit with `git commit --amend --no-edit`; do NOT create a separate commit.
563
537
 
564
538
  **Exception**: `session-summary.md` in the artifact directory is a local cross-session artifact generated by `/prizmkit-committer` — it is NOT committed to git. Ignore it in the clean-tree check.
565
539