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.
- package/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/prizmkit_runtime/cli.py +20 -0
- package/bundled/dev-pipeline/prizmkit_runtime/commands.py +1 -0
- package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +21 -0
- package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +1 -0
- package/bundled/dev-pipeline/prizmkit_runtime/platform_detection.py +208 -0
- package/bundled/dev-pipeline/prizmkit_runtime/runtime_helper.py +508 -0
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +3 -1
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +3 -1
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +3 -1
- package/bundled/dev-pipeline/scripts/prizmkit-runtime-helper.py +27 -0
- package/bundled/dev-pipeline/scripts/utils.py +48 -77
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +44 -71
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +48 -75
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +52 -78
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +2 -2
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +2 -2
- package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +1 -1
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +8 -8
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification-auto.md +33 -55
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification-opencli.md +28 -33
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification.md +22 -62
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +2 -2
- package/bundled/dev-pipeline/templates/sections/phase-commit.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-base.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-critic-plan-full.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-critic-plan.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +2 -2
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +7 -6
- package/bundled/dev-pipeline/templates/sections/phase0-init.md +1 -1
- package/bundled/dev-pipeline/templates/sections/subagent-timeout-recovery.md +1 -1
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +1 -1
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +1 -1
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +152 -3
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +2 -1
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +2 -1
- package/bundled/dev-pipeline/tests/test_runtime_helper.py +211 -0
- package/bundled/dev-pipeline/tests/test_unified_cli.py +5 -0
- package/bundled/skills/_metadata.json +1 -1
- package/package.json +1 -1
|
@@ -9,8 +9,50 @@ import json
|
|
|
9
9
|
import logging
|
|
10
10
|
import os
|
|
11
11
|
import re
|
|
12
|
+
import shlex
|
|
12
13
|
import sys
|
|
13
14
|
|
|
15
|
+
_PIPELINE_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
|
16
|
+
if _PIPELINE_ROOT not in sys.path:
|
|
17
|
+
sys.path.insert(0, _PIPELINE_ROOT)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def shell_quote(value):
|
|
21
|
+
"""Return a shell-safe token for prompt command examples."""
|
|
22
|
+
return shlex.quote(str(value))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def runtime_python_command():
|
|
26
|
+
"""Return the current Python executable for rendered prompt commands."""
|
|
27
|
+
return shell_quote(sys.executable or "python3")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def runtime_helper_command(script_dir):
|
|
31
|
+
"""Return the installed-project helper command prefix for prompt templates."""
|
|
32
|
+
helper_path = os.path.join(
|
|
33
|
+
".prizmkit", "dev-pipeline", "scripts", "prizmkit-runtime-helper.py"
|
|
34
|
+
)
|
|
35
|
+
return "{} {}".format(runtime_python_command(), helper_path)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def checkpoint_python_command():
|
|
39
|
+
"""Return the checkpoint update Python command prefix for prompt templates."""
|
|
40
|
+
return "{} {}".format(
|
|
41
|
+
runtime_python_command(),
|
|
42
|
+
os.path.join(".prizmkit", "dev-pipeline", "scripts", "update-checkpoint.py"),
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def helper_replacements(script_dir):
|
|
47
|
+
"""Return common prompt placeholders for Python runtime helpers."""
|
|
48
|
+
return {
|
|
49
|
+
"{{PYTHON_CMD}}": runtime_python_command(),
|
|
50
|
+
"{{RUNTIME_HELPER_CMD}}": runtime_helper_command(script_dir),
|
|
51
|
+
"{{CHECKPOINT_PYTHON_CMD}}": checkpoint_python_command(),
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
14
56
|
|
|
15
57
|
def load_json_file(path):
|
|
16
58
|
"""Load and return parsed JSON from a file.
|
|
@@ -99,7 +141,7 @@ A checkpoint file tracks your progress through this workflow:
|
|
|
99
141
|
Use this helper to update checkpoint status. Do not hand-edit `workflow-checkpoint.json` directly.
|
|
100
142
|
|
|
101
143
|
```bash
|
|
102
|
-
|
|
144
|
+
{{CHECKPOINT_PYTHON_CMD}} \\
|
|
103
145
|
--checkpoint-path {{CHECKPOINT_PATH}} \\
|
|
104
146
|
--step <step-id-or-skill-name> \\
|
|
105
147
|
--status <in_progress|completed|failed|skipped> \\
|
|
@@ -560,84 +602,13 @@ def enrich_global_context(global_context, project_root):
|
|
|
560
602
|
return global_context
|
|
561
603
|
|
|
562
604
|
|
|
563
|
-
|
|
564
|
-
def read_json_object(path):
|
|
565
|
-
"""Read a JSON object, returning an empty dict when unavailable."""
|
|
566
|
-
try:
|
|
567
|
-
with open(path, "r", encoding="utf-8") as f:
|
|
568
|
-
data = json.load(f)
|
|
569
|
-
except (IOError, OSError, json.JSONDecodeError):
|
|
570
|
-
return {}
|
|
571
|
-
return data if isinstance(data, dict) else {}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
def platform_from_command(command):
|
|
575
|
-
"""Map an AI CLI command/config value to a PrizmKit platform name."""
|
|
576
|
-
cmd = str(command or "").strip().lower()
|
|
577
|
-
if not cmd:
|
|
578
|
-
return ""
|
|
579
|
-
base = os.path.basename(cmd.split()[0])
|
|
580
|
-
if base in ("claude", "claude-code") or "claude" in base:
|
|
581
|
-
return "claude"
|
|
582
|
-
if base in ("codex", "openai-codex") or "codex" in base:
|
|
583
|
-
return "codex"
|
|
584
|
-
if base in ("cbc", "codebuddy") or "codebuddy" in base:
|
|
585
|
-
return "codebuddy"
|
|
586
|
-
return ""
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
def valid_prompt_platform(value):
|
|
590
|
-
"""Normalize a platform value for prompt path rendering."""
|
|
591
|
-
value = str(value or "").strip().lower()
|
|
592
|
-
if value in ("claude", "codex", "codebuddy"):
|
|
593
|
-
return value
|
|
594
|
-
return ""
|
|
595
|
-
|
|
596
|
-
|
|
597
605
|
def resolve_prompt_platform(project_root):
|
|
598
|
-
"""Resolve the platform whose agent paths should appear in prompts.
|
|
599
|
-
|
|
600
|
-
Explicit ``PRIZMKIT_PLATFORM`` wins. Otherwise prefer active/configured AI
|
|
601
|
-
CLI because mixed installs contain several platform directories. Filesystem
|
|
602
|
-
markers are only a final fallback.
|
|
603
|
-
"""
|
|
604
|
-
explicit = valid_prompt_platform(os.environ.get("PRIZMKIT_PLATFORM", ""))
|
|
605
|
-
if explicit:
|
|
606
|
-
return explicit
|
|
607
|
-
|
|
608
|
-
for env_name in ("AI_CLI", "CLAUDECODE", "CLAUDE_CODE"):
|
|
609
|
-
detected = platform_from_command(os.environ.get(env_name, ""))
|
|
610
|
-
if detected:
|
|
611
|
-
return detected
|
|
612
|
-
|
|
613
|
-
config = read_json_object(os.path.join(project_root, ".prizmkit", "config.json"))
|
|
614
|
-
for key in ("ai_cli", "aiCli"):
|
|
615
|
-
detected = platform_from_command(config.get(key, ""))
|
|
616
|
-
if detected:
|
|
617
|
-
return detected
|
|
618
|
-
detected = valid_prompt_platform(config.get("platform", ""))
|
|
619
|
-
if detected:
|
|
620
|
-
return detected
|
|
621
|
-
|
|
622
|
-
manifest = read_json_object(os.path.join(project_root, ".prizmkit", "manifest.json"))
|
|
623
|
-
options = manifest.get("options", {}) if isinstance(manifest.get("options"), dict) else {}
|
|
624
|
-
for value in (manifest.get("aiCli", ""), options.get("aiCli", "")):
|
|
625
|
-
detected = platform_from_command(value)
|
|
626
|
-
if detected:
|
|
627
|
-
return detected
|
|
628
|
-
detected = valid_prompt_platform(manifest.get("platform", ""))
|
|
629
|
-
if detected:
|
|
630
|
-
return detected
|
|
631
|
-
|
|
632
|
-
marker_order = (
|
|
633
|
-
("claude", os.path.join(project_root, ".claude", "agents")),
|
|
634
|
-
("codex", os.path.join(project_root, ".codex", "agents")),
|
|
635
|
-
("codebuddy", os.path.join(project_root, ".codebuddy", "agents")),
|
|
636
|
-
)
|
|
637
|
-
for candidate, marker in marker_order:
|
|
638
|
-
if os.path.isdir(marker):
|
|
639
|
-
return candidate
|
|
606
|
+
"""Resolve the platform whose agent paths should appear in prompts."""
|
|
607
|
+
from prizmkit_runtime.platform_detection import resolve_platform
|
|
640
608
|
|
|
609
|
+
resolution = resolve_platform(project_root)
|
|
610
|
+
if resolution.platform:
|
|
611
|
+
return resolution.platform
|
|
641
612
|
raise RuntimeError(
|
|
642
613
|
"PrizmKit agents not found. None of .claude/agents/, .codex/agents/, or .codebuddy/agents/ exists. "
|
|
643
614
|
"Run `npx prizmkit install` first, set .prizmkit/config.json ai_cli/platform, or set PRIZMKIT_PLATFORM=claude|codex|codebuddy explicitly."
|
|
@@ -46,15 +46,15 @@ You are running in **headless non-interactive mode** with a FINITE context windo
|
|
|
46
46
|
|
|
47
47
|
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
|
|
48
48
|
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.
|
|
49
|
-
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
|
|
49
|
+
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.
|
|
50
50
|
4. **Stay focused** — Do NOT explore code unrelated to this feature. No curiosity-driven reads.
|
|
51
51
|
4. **One task at a time** — In Phase 3 (implement), complete and test one task before starting the next.
|
|
52
|
-
5. **Minimize tool output** — Never load full command output into context. First capture to a temp file
|
|
52
|
+
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.
|
|
53
53
|
6. **No intermediate commits** — Do NOT run `git add`/`git commit` during Phase 1-3. All changes are committed once at the end in Phase 4 via `/prizmkit-committer`.
|
|
54
|
-
7. **Capture test output once** — When running test suites,
|
|
54
|
+
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.
|
|
55
55
|
9. **Package version verification (BLOCKING)** — Before writing ANY dependency version, verify it exists via registry query (`npm view <pkg> dist-tags.latest`, `pip index versions <pkg>`, etc.). NEVER guess version numbers.
|
|
56
56
|
10. **Build artifact hygiene** — After build/compile, ensure output is in `.gitignore`. Never commit binaries/build output.
|
|
57
|
-
11. **Read offset safety (BLOCKING)** — If Read returns "shorter than offset"/"File is empty"/"Wasted call" — do NOT retry same offset.
|
|
57
|
+
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.
|
|
58
58
|
|
|
59
59
|
---
|
|
60
60
|
|
|
@@ -72,7 +72,7 @@ You are running in **headless non-interactive mode** with a FINITE context windo
|
|
|
72
72
|
{{IF_INIT_NEEDED}}
|
|
73
73
|
### Phase 0: Project Bootstrap
|
|
74
74
|
- Run `/prizmkit-init` (invoke the prizmkit-init skill)
|
|
75
|
-
- Run `
|
|
75
|
+
- Run `{{PYTHON_CMD}} {{INIT_SCRIPT_PATH}} --project-root {{PROJECT_ROOT}} --feature-id {{FEATURE_ID}} --feature-slug {{FEATURE_SLUG}}`
|
|
76
76
|
- **CP-0**: Verify `.prizmkit/prizm-docs/root.prizm`, `.prizmkit/config.json` exist
|
|
77
77
|
{{END_IF_INIT_NEEDED}}
|
|
78
78
|
{{IF_INIT_DONE}}
|
|
@@ -82,22 +82,22 @@ You are running in **headless non-interactive mode** with a FINITE context windo
|
|
|
82
82
|
### Phase 1: Build Context Snapshot
|
|
83
83
|
|
|
84
84
|
```bash
|
|
85
|
-
|
|
85
|
+
{{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
If MISSING — build it now:
|
|
89
89
|
1. Read `.prizmkit/prizm-docs/root.prizm` and relevant L1 prizm docs
|
|
90
|
-
2. Detect source code directories
|
|
90
|
+
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:
|
|
91
91
|
```bash
|
|
92
|
-
|
|
92
|
+
{{RUNTIME_HELPER_CMD}} artifact source-files . --json
|
|
93
93
|
```
|
|
94
|
-
Identify the top-level source directories from the
|
|
94
|
+
Identify the top-level source directories from the helper output.
|
|
95
95
|
3. Scan the detected source directories for files related to this feature; read each one
|
|
96
96
|
4. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
|
|
97
97
|
- **Section 1 — Feature Brief**: feature description + acceptance criteria (copy from above)
|
|
98
|
-
- **Section 2 — Project Structure**: run the
|
|
98
|
+
- **Section 2 — Project Structure**: run the helper to get a visual directory tree, then paste output:
|
|
99
99
|
```bash
|
|
100
|
-
|
|
100
|
+
{{RUNTIME_HELPER_CMD}} artifact tree . --max-depth 2
|
|
101
101
|
```
|
|
102
102
|
- **Section 3 — Prizm Context**: content of root.prizm and relevant L1/L2 docs
|
|
103
103
|
- **Section 4 — Existing Source Files**: **full verbatim content** of each related file in fenced code blocks (with `### path/to/file` heading and line count). Include ALL files needed for implementation and review — downstream phases read this section instead of re-reading individual source files
|
|
@@ -106,7 +106,7 @@ If MISSING — build it now:
|
|
|
106
106
|
### Phase 2: Plan & Tasks
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
|
-
|
|
109
|
+
{{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
If plan.md missing, run `/prizmkit-plan` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` to generate `plan.md`:
|
|
@@ -126,9 +126,9 @@ Before proceeding past CP-1:
|
|
|
126
126
|
**Build artifacts**: After any build/compile command (`go build`, `npm run build`, `tsc`, etc.), ensure the output binary or build directory is in `.gitignore`:
|
|
127
127
|
```bash
|
|
128
128
|
# Example for Go
|
|
129
|
-
|
|
129
|
+
{{RUNTIME_HELPER_CMD}} text contains .gitignore --pattern "/binary-name" --found-marker IGNORED --missing-marker NEEDS_IGNORE_ENTRY
|
|
130
130
|
```
|
|
131
|
-
Never commit compiled binaries, build output, or generated artifacts.
|
|
131
|
+
If the helper prints `NEEDS_IGNORE_ENTRY`, edit `.gitignore` and add `/binary-name` as a single line. Never commit compiled binaries, build output, or generated artifacts.
|
|
132
132
|
|
|
133
133
|
**3a.** Run `/prizmkit-implement` — this handles the implementation cycle:
|
|
134
134
|
- Reads plan.md Tasks section from `.prizmkit/specs/{{FEATURE_SLUG}}/`
|
|
@@ -157,7 +157,7 @@ The skill runs an internal review-fix loop (Reviewer Agent → filter → orches
|
|
|
157
157
|
**Gate Check — Review Report**:
|
|
158
158
|
After `/prizmkit-code-review` returns, verify the review report:
|
|
159
159
|
```bash
|
|
160
|
-
|
|
160
|
+
{{RUNTIME_HELPER_CMD}} text contains .prizmkit/specs/{{FEATURE_SLUG}}/review-report.md --pattern "## Verdict"
|
|
161
161
|
```
|
|
162
162
|
If GATE:MISSING:
|
|
163
163
|
- Do not re-run `/prizmkit-code-review` in an unbounded report-repair loop.
|
|
@@ -177,8 +177,8 @@ Run `/prizmkit-test scope=this-change artifact_dir=.prizmkit/specs/{{FEATURE_SLU
|
|
|
177
177
|
|
|
178
178
|
Before invoking the skill, create a current-run marker so stale reports are ignored:
|
|
179
179
|
```bash
|
|
180
|
-
|
|
181
|
-
touch .prizmkit/specs/{{FEATURE_SLUG}}/.prizmkit-test-started
|
|
180
|
+
{{RUNTIME_HELPER_CMD}} artifact ensure-dir .prizmkit/specs/{{FEATURE_SLUG}}
|
|
181
|
+
{{RUNTIME_HELPER_CMD}} artifact touch .prizmkit/specs/{{FEATURE_SLUG}}/.prizmkit-test-started
|
|
182
182
|
```
|
|
183
183
|
|
|
184
184
|
Gate requirements:
|
|
@@ -209,13 +209,13 @@ You MUST execute this phase. Do NOT skip it.
|
|
|
209
209
|
|
|
210
210
|
0a. Check if `playwright-cli` is installed:
|
|
211
211
|
```bash
|
|
212
|
-
|
|
212
|
+
{{RUNTIME_HELPER_CMD}} executable version playwright-cli --arg=--version
|
|
213
213
|
```
|
|
214
214
|
If output is `NOT_INSTALLED`, install it:
|
|
215
215
|
```bash
|
|
216
216
|
npm install -g @playwright/cli@latest
|
|
217
217
|
```
|
|
218
|
-
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.
|
|
218
|
+
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.
|
|
219
219
|
|
|
220
220
|
0b. Learn playwright-cli usage (run once per session):
|
|
221
221
|
```bash
|
|
@@ -224,21 +224,9 @@ playwright-cli --help
|
|
|
224
224
|
|
|
225
225
|
0c. Check if playwright-cli skill is installed for the current AI platform:
|
|
226
226
|
```bash
|
|
227
|
-
|
|
228
|
-
if which claude >/dev/null 2>&1; then
|
|
229
|
-
CURRENT_PLATFORM="claude"; SKILL_DIR="$HOME/.claude/skills"
|
|
230
|
-
elif which cbc >/dev/null 2>&1; then
|
|
231
|
-
CURRENT_PLATFORM="codebuddy"; SKILL_DIR="$HOME/.cbc/skills"
|
|
232
|
-
else
|
|
233
|
-
CURRENT_PLATFORM="unknown"
|
|
234
|
-
fi
|
|
235
|
-
if [ -d "$SKILL_DIR/playwright-cli" ] || ls "$SKILL_DIR"/playwright* 2>/dev/null | grep -q .; then
|
|
236
|
-
echo "SKILL_EXISTS"
|
|
237
|
-
else
|
|
238
|
-
echo "SKILL_MISSING"
|
|
239
|
-
fi
|
|
227
|
+
{{RUNTIME_HELPER_CMD}} platform skill playwright-cli --prefix
|
|
240
228
|
```
|
|
241
|
-
If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform is NOT claude, copy installed skill from
|
|
229
|
+
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.
|
|
242
230
|
|
|
243
231
|
0d. Read the installed playwright-cli skill (SKILL.md) for workflow guidance. Use its recommended patterns to construct your verification flow.
|
|
244
232
|
|
|
@@ -247,29 +235,17 @@ If `SKILL_MISSING`: run `playwright-cli install --skills`. If current platform i
|
|
|
247
235
|
You know this project's tech stack. Detect and start the dev server yourself:
|
|
248
236
|
|
|
249
237
|
1. Identify the dev server start command from project config (`package.json` scripts, `Makefile`, `docker-compose.yml`, etc.)
|
|
250
|
-
2.
|
|
251
|
-
```bash
|
|
252
|
-
DEV_PORT={{DEV_PORT}}
|
|
253
|
-
if [ "$DEV_PORT" = "{{DEV_PORT}}" ]; then
|
|
254
|
-
DEV_PORT=$(node -e "const s=require('./package.json').scripts.dev; const m=s.match(/-p\s+(\d+)/); console.log(m?m[1]:'')")
|
|
255
|
-
if [ -z "$DEV_PORT" ]; then
|
|
256
|
-
DEV_PORT=$(echo "$NEXT_PUBLIC_SITE_URL" | sed -nE 's|.*:([0-9]+).*|\1|p')
|
|
257
|
-
fi
|
|
258
|
-
DEV_PORT=${DEV_PORT:-3000}
|
|
259
|
-
fi
|
|
260
|
-
echo "Detected DEV_PORT=$DEV_PORT"
|
|
261
|
-
```
|
|
238
|
+
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.
|
|
262
239
|
3. Verify the port is available:
|
|
263
240
|
```bash
|
|
264
|
-
|
|
241
|
+
{{RUNTIME_HELPER_CMD}} port check {{DEV_PORT}}
|
|
265
242
|
```
|
|
266
243
|
4. Start the dev server in background, capture PID:
|
|
267
244
|
```bash
|
|
268
|
-
<start-command>
|
|
269
|
-
DEV_SERVER_PID=$!
|
|
245
|
+
{{RUNTIME_HELPER_CMD}} process start --pid-file .prizmkit/state/browser-dev-server.pid -- <start-command tokens>
|
|
270
246
|
```
|
|
271
|
-
5. Wait for server to be ready:
|
|
272
|
-
6. Open the app in playwright-cli: `playwright-cli open http://localhost
|
|
247
|
+
5. Wait for server to be ready: run `{{RUNTIME_HELPER_CMD}} web wait-ready --url http://localhost:{{DEV_PORT}} --timeout 30 --interval 2`
|
|
248
|
+
6. Open the app in playwright-cli: `playwright-cli open http://localhost:{{DEV_PORT}}`
|
|
273
249
|
7. If the page requires authentication, use playwright-cli to register a test user and log in first
|
|
274
250
|
|
|
275
251
|
**Step 2 — Verification**:
|
|
@@ -282,8 +258,8 @@ Construct your verification workflow based on: (1) the playwright-cli skill docu
|
|
|
282
258
|
**Step 3 — Cleanup (REQUIRED — you started it, you stop it)**:
|
|
283
259
|
|
|
284
260
|
1. Close the playwright-cli browser: `playwright-cli close`
|
|
285
|
-
2. Kill the dev server process: `
|
|
286
|
-
3. Verify port is released: `
|
|
261
|
+
2. Kill the dev server process: `{{RUNTIME_HELPER_CMD}} process cleanup-pid <pid-from-.prizmkit/state/browser-dev-server.pid>`
|
|
262
|
+
3. Verify port is released: `{{RUNTIME_HELPER_CMD}} port check {{DEV_PORT}}`
|
|
287
263
|
{{END_IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
288
264
|
{{IF_BROWSER_TOOL_OPENCLI}}
|
|
289
265
|
**Using: opencli** (reuses Chrome logged-in sessions)
|
|
@@ -296,45 +272,42 @@ Construct your verification workflow based on: (1) the playwright-cli skill docu
|
|
|
296
272
|
|
|
297
273
|
0a. Check if `opencli` is installed:
|
|
298
274
|
```bash
|
|
299
|
-
|
|
275
|
+
{{RUNTIME_HELPER_CMD}} executable version opencli --arg=--version
|
|
300
276
|
```
|
|
301
277
|
If `NOT_INSTALLED`: `npm install -g @jackwener/opencli@latest`. If installation fails, log `## Browser Verification: SKIPPED — opencli installation failed` and proceed.
|
|
302
278
|
|
|
303
279
|
0b. Verify Browser Bridge: `opencli doctor`. If fails, log skip and proceed.
|
|
304
280
|
|
|
305
|
-
0c. Learn usage: `opencli browser --help
|
|
281
|
+
0c. Learn usage: `opencli browser --help`
|
|
306
282
|
|
|
307
|
-
**Step 1 — Start Dev Server**:
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
fi
|
|
314
|
-
```
|
|
315
|
-
Start server, wait for ready, then: `opencli browser open http://localhost:$DEV_PORT && opencli browser state`
|
|
283
|
+
**Step 1 — Start Dev Server**:
|
|
284
|
+
1. Determine `DEV_PORT` from the pipeline value (`{{DEV_PORT}}`) or project config; do not guess.
|
|
285
|
+
2. Verify port available: `{{RUNTIME_HELPER_CMD}} port check <DEV_PORT>`
|
|
286
|
+
3. Start server: `{{RUNTIME_HELPER_CMD}} process start --pid-file .prizmkit/state/browser-dev-server.pid -- <start-command tokens>`
|
|
287
|
+
4. Wait for ready: `{{RUNTIME_HELPER_CMD}} web wait-ready --url http://localhost:<DEV_PORT> --timeout 30 --interval 2`
|
|
288
|
+
5. Open: `opencli browser open http://localhost:<DEV_PORT>`; then inspect: `opencli browser state`
|
|
316
289
|
|
|
317
290
|
**Step 2 — Verification**:
|
|
318
291
|
|
|
319
292
|
Use `opencli browser state` to discover elements with `[N]` indices, then verify:
|
|
320
293
|
{{BROWSER_VERIFY_STEPS}}
|
|
321
294
|
|
|
322
|
-
|
|
295
|
+
Run page-changing commands sequentially, then run `opencli browser state` to refresh indices.
|
|
323
296
|
|
|
324
297
|
**Step 3 — Cleanup**:
|
|
325
298
|
1. `opencli browser close`
|
|
326
|
-
2. `
|
|
327
|
-
3. `
|
|
299
|
+
2. `{{RUNTIME_HELPER_CMD}} process cleanup-pid <pid-from-.prizmkit/state/browser-dev-server.pid>`
|
|
300
|
+
3. `{{RUNTIME_HELPER_CMD}} port check {{DEV_PORT}}`
|
|
328
301
|
{{END_IF_BROWSER_TOOL_OPENCLI}}
|
|
329
302
|
{{IF_BROWSER_TOOL_AUTO}}
|
|
330
303
|
**Tool Selection**: Choose the best browser tool at runtime.
|
|
331
304
|
|
|
332
305
|
**Step 0 — Detect available tools**:
|
|
333
306
|
```bash
|
|
334
|
-
|
|
335
|
-
|
|
307
|
+
{{RUNTIME_HELPER_CMD}} executable version playwright-cli --arg=--version
|
|
308
|
+
{{RUNTIME_HELPER_CMD}} executable version opencli --arg=--version
|
|
336
309
|
```
|
|
337
|
-
If opencli installed
|
|
310
|
+
If opencli is installed, run `opencli doctor`. If it fails, mark OpenCLI unusable and choose playwright-cli or skip browser verification.
|
|
338
311
|
|
|
339
312
|
**Decision table**:
|
|
340
313
|
| Condition | Tool |
|
|
@@ -355,7 +328,7 @@ Append results to `context-snapshot.md`:
|
|
|
355
328
|
```
|
|
356
329
|
## Browser Verification
|
|
357
330
|
Tool: <playwright-cli or opencli>
|
|
358
|
-
URL: http://localhost
|
|
331
|
+
URL: http://localhost:{{DEV_PORT}}
|
|
359
332
|
Dev Server Command: <actual command used>
|
|
360
333
|
Tool version: <version>
|
|
361
334
|
Steps executed: [list of commands used]
|
|
@@ -393,7 +366,7 @@ This single commit includes: feature code + tests + .prizmkit/prizm-docs/ update
|
|
|
393
366
|
```bash
|
|
394
367
|
git status --short
|
|
395
368
|
```
|
|
396
|
-
Working tree MUST be clean after this step. If any feature-related files remain, stage them
|
|
369
|
+
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.
|
|
397
370
|
|
|
398
371
|
**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.
|
|
399
372
|
|