prizmkit 1.0.128 → 1.0.130

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "frameworkVersion": "1.0.128",
3
- "bundledAt": "2026-03-28T06:01:48.243Z",
4
- "bundledFrom": "ece8a06"
2
+ "frameworkVersion": "1.0.130",
3
+ "bundledAt": "2026-03-28T07:12:12.286Z",
4
+ "bundledFrom": "1fdcacb"
5
5
  }
@@ -0,0 +1,113 @@
1
+ # playwright-cli Quick Reference (for AI Agents)
2
+
3
+ Token-efficient browser automation tool. State is saved to `.playwright-cli/` on disk — only file paths are returned, not page content.
4
+
5
+ ## Core Workflow
6
+
7
+ ```
8
+ playwright-cli open <url> # open browser + navigate (returns snapshot path)
9
+ playwright-cli snapshot # capture page state → .yml file with element refs (e.g. ref=e15)
10
+ playwright-cli click <ref> # click element by ref from snapshot
11
+ playwright-cli fill <ref> <text> # fill text into input/textarea by ref
12
+ playwright-cli type <text> # type text into active element
13
+ playwright-cli press <key> # press key: Enter, Tab, Escape, ArrowDown, etc.
14
+ playwright-cli screenshot # capture viewport → .png file
15
+ playwright-cli close # close browser
16
+ ```
17
+
18
+ ## Reading Snapshots
19
+
20
+ After `open` or `snapshot`, read the `.yml` file. Each element has a `ref=eXX`:
21
+
22
+ ```yaml
23
+ - navigation "Main" [ref=e4]:
24
+ - link "Docs" [ref=e11] [cursor=pointer]:
25
+ - /url: /docs/intro
26
+ - button "Login" [ref=e14] [cursor=pointer]
27
+ - searchbox "Search" [ref=e20]
28
+ ```
29
+
30
+ Use refs in subsequent commands: `playwright-cli click e14`, `playwright-cli fill e20 "query"`.
31
+
32
+ **Important**: Refs change after navigation — always `snapshot` after clicking a link.
33
+
34
+ ## Additional Commands
35
+
36
+ ```
37
+ # Navigation
38
+ goto <url> # navigate without reopening browser
39
+ go-back / go-forward # browser history
40
+ reload # reload page
41
+
42
+ # Form interaction
43
+ select <ref> <value> # select dropdown option
44
+ check <ref> / uncheck <ref> # checkbox/radio
45
+ upload <file> # file upload
46
+ dblclick <ref> # double click
47
+ hover <ref> # hover over element
48
+ drag <startRef> <endRef> # drag and drop
49
+
50
+ # Tabs
51
+ tab-list # list all open tabs
52
+ tab-new [url] # open new tab
53
+ tab-select <index> # switch to tab by index
54
+ tab-close [index] # close tab
55
+
56
+ # JavaScript
57
+ eval <expression> # evaluate JS on page (e.g. eval "document.title")
58
+ eval <expression> <ref> # evaluate JS on specific element
59
+
60
+ # Session management
61
+ list # list browser sessions
62
+ close-all # close all browsers
63
+ -s=<name> <command> # target specific session (for multiple browsers)
64
+
65
+ # DevTools
66
+ console # list console messages
67
+ network # list network requests
68
+ screenshot [ref] # screenshot specific element (not just viewport)
69
+
70
+ # Storage / Auth
71
+ state-save [file] # save cookies + localStorage (for auth reuse)
72
+ state-load <file> # restore saved state
73
+ ```
74
+
75
+ ## Typical Verification Flow
76
+
77
+ ```bash
78
+ # 1. Start dev server (if needed)
79
+ npm run dev &
80
+ sleep 5
81
+
82
+ # 2. Open and get initial snapshot
83
+ playwright-cli open http://localhost:3000
84
+ # → reads .playwright-cli/page-*.yml for element refs
85
+
86
+ # 3. Interact — map acceptance criteria to actions
87
+ playwright-cli snapshot
88
+ # read the .yml, find the target element ref
89
+ playwright-cli click e14 # e.g. click "Login" button
90
+ playwright-cli fill e20 "admin" # e.g. fill username
91
+ playwright-cli fill e22 "pass" # e.g. fill password
92
+ playwright-cli click e25 # e.g. click "Submit"
93
+
94
+ # 4. Verify result
95
+ playwright-cli snapshot
96
+ # read the new .yml — check if expected elements exist
97
+ # e.g. look for "Welcome" heading, dashboard nav, etc.
98
+
99
+ # 5. Screenshot for human review
100
+ playwright-cli screenshot
101
+
102
+ # 6. Cleanup
103
+ playwright-cli close
104
+ ```
105
+
106
+ ## Tips for AI Agents
107
+
108
+ - **Always snapshot before interacting** — you need refs, and they change after navigation
109
+ - **Read the .yml file** to find the right ref — don't guess ref numbers
110
+ - **One command at a time** — each command returns immediately, check result before next
111
+ - **Failures are non-blocking** — if an element isn't found, log it and continue
112
+ - **Screenshots are evidence** — take one after each major verification step
113
+ - `.playwright-cli/` artifacts are gitignored — they're ephemeral
@@ -285,11 +285,13 @@ def process_conditional_blocks(content, resume_phase):
285
285
  return content
286
286
 
287
287
 
288
- def process_mode_blocks(content, pipeline_mode, init_done, critic_enabled=False):
289
- """Process pipeline mode, init, and critic conditional blocks.
288
+ def process_mode_blocks(content, pipeline_mode, init_done, critic_enabled=False,
289
+ browser_interaction=False):
290
+ """Process pipeline mode, init, critic, and browser conditional blocks.
290
291
 
291
292
  Keeps the block matching the current mode, removes the others.
292
293
  Handles {{IF_CRITIC_ENABLED}} / {{END_IF_CRITIC_ENABLED}} blocks.
294
+ Handles {{IF_BROWSER_INTERACTION}} / {{END_IF_BROWSER_INTERACTION}} blocks.
293
295
  """
294
296
  # Handle lite/standard/full blocks
295
297
  modes = ["lite", "standard", "full"]
@@ -339,6 +341,18 @@ def process_mode_blocks(content, pipeline_mode, init_done, critic_enabled=False)
339
341
  pattern = re.escape(critic_open) + r".*?" + re.escape(critic_close) + r"\n?"
340
342
  content = re.sub(pattern, "", content, flags=re.DOTALL)
341
343
 
344
+ # Browser interaction blocks
345
+ browser_open = "{{IF_BROWSER_INTERACTION}}"
346
+ browser_close = "{{END_IF_BROWSER_INTERACTION}}"
347
+ if browser_interaction:
348
+ content = content.replace(browser_open + "\n", "")
349
+ content = content.replace(browser_open, "")
350
+ content = content.replace(browser_close + "\n", "")
351
+ content = content.replace(browser_close, "")
352
+ else:
353
+ pattern = re.escape(browser_open) + r".*?" + re.escape(browser_close) + r"\n?"
354
+ content = re.sub(pattern, "", content, flags=re.DOTALL)
355
+
342
356
  return content
343
357
 
344
358
 
@@ -517,6 +531,31 @@ def build_replacements(args, feature, features, global_context, script_dir):
517
531
  )
518
532
  critic_enabled = False
519
533
 
534
+ # Browser interaction - extract from feature if present and playwright-cli available
535
+ browser_interaction = feature.get("browser_interaction")
536
+ browser_enabled = False
537
+ browser_url = ""
538
+ browser_setup_command = ""
539
+ browser_verify_steps = ""
540
+
541
+ browser_verify_env = os.environ.get("BROWSER_VERIFY", "").lower()
542
+ if browser_verify_env == "false":
543
+ browser_interaction = None
544
+
545
+ if browser_interaction and isinstance(browser_interaction, dict):
546
+ browser_url = browser_interaction.get("url", "")
547
+ if browser_url:
548
+ browser_enabled = True
549
+ browser_setup_command = browser_interaction.get("setup_command", "# no setup needed")
550
+ steps = browser_interaction.get("verify_steps", [])
551
+ if steps:
552
+ browser_verify_steps = "\n".join(
553
+ " # Step {}: {}".format(i + 1, step)
554
+ for i, step in enumerate(steps)
555
+ )
556
+ else:
557
+ browser_verify_steps = " # (no specific verify steps — just open and screenshot)"
558
+
520
559
  replacements = {
521
560
  "{{RUN_ID}}": args.run_id,
522
561
  "{{SESSION_ID}}": args.session_id,
@@ -552,21 +591,25 @@ def build_replacements(args, feature, features, global_context, script_dir):
552
591
  "{{HAS_SPEC}}": "true" if artifacts["has_spec"] else "false",
553
592
  "{{HAS_PLAN}}": "true" if artifacts["has_plan"] else "false",
554
593
  "{{ARTIFACTS_COMPLETE}}": "true" if artifacts["all_complete"] else "false",
594
+ "{{BROWSER_URL}}": browser_url,
595
+ "{{BROWSER_SETUP_COMMAND}}": browser_setup_command,
596
+ "{{BROWSER_VERIFY_STEPS}}": browser_verify_steps,
555
597
  }
556
598
 
557
- return replacements, effective_resume
599
+ return replacements, effective_resume, browser_enabled
558
600
 
559
601
 
560
- def render_template(template_content, replacements, resume_phase):
602
+ def render_template(template_content, replacements, resume_phase, browser_enabled=False):
561
603
  """Render the template by processing conditionals and replacing placeholders."""
562
604
  # Step 1: Process fresh_start/resume conditional blocks
563
605
  content = process_conditional_blocks(template_content, resume_phase)
564
606
 
565
- # Step 2: Process mode, init, and critic conditional blocks
607
+ # Step 2: Process mode, init, critic, and browser conditional blocks
566
608
  pipeline_mode = replacements.get("{{PIPELINE_MODE}}", "standard")
567
609
  init_done = replacements.get("{{INIT_DONE}}", "false") == "true"
568
610
  critic_enabled = replacements.get("{{CRITIC_ENABLED}}", "false") == "true"
569
- content = process_mode_blocks(content, pipeline_mode, init_done, critic_enabled)
611
+ content = process_mode_blocks(content, pipeline_mode, init_done, critic_enabled,
612
+ browser_enabled)
570
613
 
571
614
  # Step 3: Replace all {{PLACEHOLDER}} variables
572
615
  for placeholder, value in replacements.items():
@@ -661,7 +704,7 @@ def main():
661
704
  global_context = {}
662
705
 
663
706
  # Build replacements
664
- replacements, effective_resume = build_replacements(
707
+ replacements, effective_resume, browser_enabled = build_replacements(
665
708
  args, feature, features, global_context, script_dir
666
709
  )
667
710
 
@@ -670,7 +713,7 @@ def main():
670
713
 
671
714
  # Render the template
672
715
  rendered = render_template(
673
- template_content, replacements, effective_resume
716
+ template_content, replacements, effective_resume, browser_enabled
674
717
  )
675
718
 
676
719
  # Write the output
@@ -161,6 +161,63 @@ Files changed/created: [list]
161
161
  Key decisions: [list]
162
162
  ```
163
163
 
164
+ {{IF_BROWSER_INTERACTION}}
165
+ ### Phase 3.5: Browser Verification (playwright-cli)
166
+
167
+ Verify UI behavior using `playwright-cli` before committing. This phase is best-effort — failures are logged but do NOT block the commit.
168
+
169
+ **Before starting**: Run these commands to learn available playwright-cli commands and usage:
170
+ ```bash
171
+ playwright-cli --help
172
+ ```
173
+ For detailed help on a specific command:
174
+ ```bash
175
+ playwright-cli --help <command> # e.g. playwright-cli --help snapshot
176
+ ```
177
+ Also read `dev-pipeline/assets/playwright-cli-reference.md` for snapshot format and workflow patterns.
178
+
179
+ 1. **Start dev server** (if `setup_command` is specified):
180
+ ```bash
181
+ {{BROWSER_SETUP_COMMAND}} &
182
+ DEV_SERVER_PID=$!
183
+ sleep 5 # wait for server to start
184
+ ```
185
+
186
+ 2. **Open browser and navigate**:
187
+ ```bash
188
+ playwright-cli open {{BROWSER_URL}}
189
+ ```
190
+
191
+ 3. **Take snapshot and execute verify steps**:
192
+ ```bash
193
+ playwright-cli snapshot
194
+ ```
195
+ Read the snapshot file to identify element refs. Then execute each verify step by mapping the descriptive step to actual refs from the snapshot.
196
+ {{BROWSER_VERIFY_STEPS}}
197
+
198
+ 4. **Capture final screenshot**:
199
+ ```bash
200
+ playwright-cli screenshot
201
+ ```
202
+
203
+ 5. **Close browser and cleanup**:
204
+ ```bash
205
+ playwright-cli close
206
+ kill $DEV_SERVER_PID 2>/dev/null || true
207
+ ```
208
+
209
+ 6. **Log results** — append to `context-snapshot.md`:
210
+ ```
211
+ ## Browser Verification
212
+ URL: {{BROWSER_URL}}
213
+ Steps executed: [list]
214
+ Screenshot: [path]
215
+ Result: PASS / FAIL (reason)
216
+ ```
217
+
218
+ If any step fails, log the failure and continue to Phase 4. Do NOT retry browser verification.
219
+ {{END_IF_BROWSER_INTERACTION}}
220
+
164
221
  ### Phase 4: Architecture Sync & Commit (SINGLE COMMIT)
165
222
 
166
223
  **4a.** Run `/prizmkit-retrospective` — maintains `.prizm-docs/` (architecture index):
@@ -275,6 +275,63 @@ If GATE:MISSING — send message to Reviewer (re-spawn if needed): "Write the '#
275
275
 
276
276
  **CP-3**: Tests pass, verdict is not NEEDS_FIXES.
277
277
 
278
+ {{IF_BROWSER_INTERACTION}}
279
+ ### Phase 5.5: Browser Verification (playwright-cli)
280
+
281
+ Verify UI behavior using `playwright-cli` before committing. This phase is best-effort — failures are logged but do NOT block the commit.
282
+
283
+ **Before starting**: Run these commands to learn available playwright-cli commands and usage:
284
+ ```bash
285
+ playwright-cli --help
286
+ ```
287
+ For detailed help on a specific command:
288
+ ```bash
289
+ playwright-cli --help <command> # e.g. playwright-cli --help snapshot
290
+ ```
291
+ Also read `dev-pipeline/assets/playwright-cli-reference.md` for snapshot format and workflow patterns.
292
+
293
+ 1. **Start dev server** (if `setup_command` is specified):
294
+ ```bash
295
+ {{BROWSER_SETUP_COMMAND}} &
296
+ DEV_SERVER_PID=$!
297
+ sleep 5 # wait for server to start
298
+ ```
299
+
300
+ 2. **Open browser and navigate**:
301
+ ```bash
302
+ playwright-cli open {{BROWSER_URL}}
303
+ ```
304
+
305
+ 3. **Take snapshot and execute verify steps**:
306
+ ```bash
307
+ playwright-cli snapshot
308
+ ```
309
+ Read the snapshot file to identify element refs. Then execute each verify step by mapping the descriptive step to actual refs from the snapshot.
310
+ {{BROWSER_VERIFY_STEPS}}
311
+
312
+ 4. **Capture final screenshot**:
313
+ ```bash
314
+ playwright-cli screenshot
315
+ ```
316
+
317
+ 5. **Close browser and cleanup**:
318
+ ```bash
319
+ playwright-cli close
320
+ kill $DEV_SERVER_PID 2>/dev/null || true
321
+ ```
322
+
323
+ 6. **Log results** — append to `context-snapshot.md`:
324
+ ```
325
+ ## Browser Verification
326
+ URL: {{BROWSER_URL}}
327
+ Steps executed: [list]
328
+ Screenshot: [path]
329
+ Result: PASS / FAIL (reason)
330
+ ```
331
+
332
+ If any step fails, log the failure and continue to Phase 6. Do NOT retry browser verification.
333
+ {{END_IF_BROWSER_INTERACTION}}
334
+
278
335
  ### Phase 6: Architecture Sync & Commit (SINGLE COMMIT)
279
336
 
280
337
  **6a.** Run `/prizmkit-retrospective` — maintains `.prizm-docs/` (architecture index):
@@ -375,6 +375,63 @@ If GATE:MISSING — send message to Reviewer (re-spawn if needed): "Write the '#
375
375
 
376
376
  **CP-3**: Integration tests pass, verdict is not NEEDS_FIXES.
377
377
 
378
+ {{IF_BROWSER_INTERACTION}}
379
+ ### Phase 5.5: Browser Verification (playwright-cli)
380
+
381
+ Verify UI behavior using `playwright-cli` before committing. This phase is best-effort — failures are logged but do NOT block the commit.
382
+
383
+ **Before starting**: Run these commands to learn available playwright-cli commands and usage:
384
+ ```bash
385
+ playwright-cli --help
386
+ ```
387
+ For detailed help on a specific command:
388
+ ```bash
389
+ playwright-cli --help <command> # e.g. playwright-cli --help snapshot
390
+ ```
391
+ Also read `dev-pipeline/assets/playwright-cli-reference.md` for snapshot format and workflow patterns.
392
+
393
+ 1. **Start dev server** (if `setup_command` is specified):
394
+ ```bash
395
+ {{BROWSER_SETUP_COMMAND}} &
396
+ DEV_SERVER_PID=$!
397
+ sleep 5 # wait for server to start
398
+ ```
399
+
400
+ 2. **Open browser and navigate**:
401
+ ```bash
402
+ playwright-cli open {{BROWSER_URL}}
403
+ ```
404
+
405
+ 3. **Take snapshot and execute verify steps**:
406
+ ```bash
407
+ playwright-cli snapshot
408
+ ```
409
+ Read the snapshot file to identify element refs. Then execute each verify step by mapping the descriptive step to actual refs from the snapshot.
410
+ {{BROWSER_VERIFY_STEPS}}
411
+
412
+ 4. **Capture final screenshot**:
413
+ ```bash
414
+ playwright-cli screenshot
415
+ ```
416
+
417
+ 5. **Close browser and cleanup**:
418
+ ```bash
419
+ playwright-cli close
420
+ kill $DEV_SERVER_PID 2>/dev/null || true
421
+ ```
422
+
423
+ 6. **Log results** — append to `context-snapshot.md`:
424
+ ```
425
+ ## Browser Verification
426
+ URL: {{BROWSER_URL}}
427
+ Steps executed: [list]
428
+ Screenshot: [path]
429
+ Result: PASS / FAIL (reason)
430
+ ```
431
+
432
+ If any step fails, log the failure and continue to Phase 6. Do NOT retry browser verification.
433
+ {{END_IF_BROWSER_INTERACTION}}
434
+
378
435
 
379
436
  ### Phase 6: Retrospective & Commit (SINGLE COMMIT) — DO NOT SKIP
380
437
 
@@ -111,6 +111,33 @@
111
111
  "type": "integer",
112
112
  "description": "Number of parallel critic agents. 1 = single critic, 3 = multi-critic voting. Default: 1.",
113
113
  "enum": [1, 3]
114
+ },
115
+ "browser_interaction": {
116
+ "type": "object",
117
+ "description": "Browser verification config for features with UI. Requires playwright-cli. Pipeline uses this to verify UI behavior after implementation.",
118
+ "properties": {
119
+ "url": {
120
+ "type": "string",
121
+ "description": "URL to open for verification (e.g. http://localhost:3000/login)"
122
+ },
123
+ "setup_command": {
124
+ "type": "string",
125
+ "description": "Command to start the dev server before verification (e.g. npm run dev)"
126
+ },
127
+ "verify_steps": {
128
+ "type": "array",
129
+ "description": "Ordered playwright-cli commands to execute for verification",
130
+ "items": {
131
+ "type": "string"
132
+ }
133
+ },
134
+ "screenshot": {
135
+ "type": "boolean",
136
+ "description": "Capture screenshot after verification steps. Default: true.",
137
+ "default": true
138
+ }
139
+ },
140
+ "required": ["url"]
114
141
  }
115
142
  }
116
143
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.128",
2
+ "version": "1.0.130",
3
3
  "skills": {
4
4
  "prizm-kit": {
5
5
  "description": "Full-lifecycle dev toolkit. Covers spec-driven development, Prizm context docs, code quality, debugging, deployment, and knowledge management.",
@@ -132,9 +132,11 @@ Execute the selected scenario workflow in conversation mode with mandatory check
132
132
  ### Interactive Phases
133
133
  1. clarify business goal and scope
134
134
  1.1 confirm deliverable intent (→ Intent Confirmation)
135
+ 1.2 **requirement clarification** — apply `/prizmkit-clarify` principles: for ANY unclear aspect of the user's vision, goals, target users, or scope, ask questions one at a time until you fully understand. No limit on rounds or number of questions. Do not proceed to Phase 2 with unresolved ambiguities.
135
136
  2. confirm constraints and tech assumptions
136
137
  3. propose feature set with dependencies
137
138
  4. refine descriptions and acceptance criteria
139
+ 4.1 **per-feature clarification** — for each feature, if the description, acceptance criteria, or scope is vague or could be interpreted multiple ways, ask the user to clarify before finalizing. Continue until every feature has unambiguous, implementation-ready details.
138
140
  5. verify DAG/order/priorities
139
141
  6. build or append `feature-list.json`
140
142
  7. ask whether to enable adversarial critic review for high/critical features
@@ -244,6 +246,52 @@ AI: [Validates immediately]
244
246
  AI: "Ready to proceed to dev-pipeline."
245
247
  ```
246
248
 
249
+ ## Browser Interaction Planning
250
+
251
+ For web apps with UI, features that involve user-facing pages or interactive flows can optionally include a `browser_interaction` field. This enables the dev-pipeline to verify UI behavior automatically using `playwright-cli` after implementation.
252
+
253
+ ### When to Suggest
254
+
255
+ Suggest `browser_interaction` when ALL of these apply:
256
+ - The app has a web frontend (detected from tech stack or `global_context`)
257
+ - The feature produces user-visible UI (pages, forms, modals, navigation flows)
258
+ - The acceptance criteria reference visual/interactive behavior (e.g., "user sees...", "clicking X shows Y")
259
+
260
+ Do NOT suggest for:
261
+ - Backend-only features (APIs, database, services)
262
+ - Config/setup/scaffolding features
263
+ - Features where UI is not the primary deliverable
264
+
265
+ ### How to Capture
266
+
267
+ During Phase 4 (refine descriptions and acceptance criteria), for qualifying features ask:
268
+
269
+ > "This feature has UI behavior. Want to add browser verification so the pipeline can auto-check it after implementation? (Y/n)"
270
+
271
+ If yes, generate the `browser_interaction` object:
272
+
273
+ ```json
274
+ {
275
+ "browser_interaction": {
276
+ "url": "http://localhost:3000/login",
277
+ "setup_command": "npm run dev",
278
+ "verify_steps": [
279
+ "snapshot",
280
+ "click <ref> — click login button",
281
+ "fill <ref> 'test@example.com' — enter email",
282
+ "screenshot"
283
+ ],
284
+ "screenshot": true
285
+ }
286
+ }
287
+ ```
288
+
289
+ **Rules:**
290
+ - `url` is required — the page URL to verify
291
+ - `setup_command` is optional — command to start dev server (omit if already running)
292
+ - `verify_steps` are descriptive placeholders — the actual `ref` IDs are resolved at runtime by `playwright-cli snapshot`. Use natural language descriptions (e.g., "click login button") that the pipeline agent will map to real refs.
293
+ - `screenshot` defaults to `true` — capture final state for human review
294
+
247
295
  ## Output Rules
248
296
 
249
297
  `feature-list.json` must satisfy:
@@ -256,6 +304,7 @@ AI: "Ready to proceed to dev-pipeline."
256
304
  - `model` field is optional — omitting it means the pipeline uses $MODEL env or CLI default
257
305
  - `critic` field is optional (boolean). If user requested adversarial critic review during planning, set `"critic": true` for relevant features. Omitting defaults to `false`.
258
306
  - `critic_count` field is optional (integer, 1 or 3). If omitted, defaults to 1 (single critic). Set to 3 for multi-critic voting mode on critical features.
307
+ - `browser_interaction` field is optional (object). If user opted for browser verification during planning, set for features with UI behavior. Requires `playwright-cli` to be installed.
259
308
  - **descriptions must be implementation-ready** — minimum 15 words (error), recommended 30/50/80 words for low/medium/high complexity (warning). See `planning-guide.md` §4 for what to include.
260
309
 
261
310
  ## Next-Step Execution Policy (after planning)
@@ -44,6 +44,7 @@ Launch the interactive bug planning process through 4 phases.
44
44
  1. **Identify project**: Read project name and description from existing `feature-list.json` or ask user
45
45
  2. **Identify tech stack**: Read from `.prizmkit/config.json` `tech_stack` (preferred), then `feature-list.json` global_context, then `.prizm-docs/root.prizm`. Only ask user if none of these sources provide tech stack info.
46
46
  3. **Identify testing framework**: Read from `.prizmkit/config.json` `tech_stack.testing`, or auto-detect from package.json/requirements.txt/etc., or ask user
47
+ 4. **Clarify context** — apply `/prizmkit-clarify` principles: if the project context, affected systems, or bug scope is unclear, ask questions one at a time until you fully understand the environment. No limit on rounds or number of questions.
47
48
 
48
49
  Output: `project_name`, `project_description`, `global_context` fields populated.
49
50
 
@@ -116,6 +117,8 @@ ALERT: Error rate spike: 500 errors/min on /api/login endpoint
116
117
  - Verification type (suggest `automated` by default, ask user)
117
118
  - Acceptance criteria (auto-suggest based on description, user can edit)
118
119
 
120
+ **Per-bug clarification** — apply `/prizmkit-clarify` principles: if the bug's root cause, reproduction steps, expected behavior, or scope is unclear from the provided information, ask focused questions until the bug is fully understood. Do not finalize a bug entry with ambiguous details. No limit on the number of questions per bug.
121
+
119
122
  **Multiple bugs per session**: After each bug, ask "Any more bugs to add? (yes/no)"
120
123
 
121
124
  ### Phase 3: Prioritization & Review
@@ -57,10 +57,13 @@ Before any action, validate:
57
57
  2. **For start**: `feature-list.json` must exist in project root (or user-specified path)
58
58
  3. **Dependencies**: `jq`, `python3`, AI CLI (`cbc` or `claude`) must be in PATH
59
59
  4. **Python version**: Requires Python 3.8+ for dev-pipeline scripts
60
+ 5. **playwright-cli** (optional): If any feature has `browser_interaction` field, check `playwright-cli` is available
60
61
 
61
62
  Quick check:
62
63
  ```bash
63
64
  command -v jq && command -v python3 && (command -v cbc || command -v claude) && echo "All dependencies OK"
65
+ # Optional: browser interaction support
66
+ command -v playwright-cli && echo "playwright-cli OK" || echo "playwright-cli not found (browser verification will be skipped)"
64
67
  ```
65
68
 
66
69
  If `feature-list.json` is missing, inform user:
@@ -117,6 +120,7 @@ Detect user intent from their message, then follow the corresponding workflow:
117
120
  | **Max retries** | 3 | Max retry attempts per failed feature |
118
121
  | **Session timeout** | None | Per-feature timeout in seconds (e.g. `3600` = 1 hour) |
119
122
  | **Feature filter** | All | Run specific features: `F-001:F-005` (range), `F-001,F-003` (list), or mixed `F-001,F-005:F-010` |
123
+ | **Browser verify** | Auto | Run playwright-cli verification for features with `browser_interaction`. Auto = run if playwright-cli installed and features have the field |
120
124
 
121
125
  Default to Foreground + Verbose On if user doesn't specify. Default Critic to Off unless features have `estimated_complexity: "high"` or above.
122
126
 
@@ -129,6 +133,8 @@ Detect user intent from their message, then follow the corresponding workflow:
129
133
  | "no verbose" / "quiet" | `VERBOSE=0` |
130
134
  | "heartbeat every 60s" | `HEARTBEAT_INTERVAL=60` |
131
135
  | "enable critic review" | `ENABLE_CRITIC=true` |
136
+ | "skip browser verify" | `BROWSER_VERIFY=false` |
137
+ | "enable browser verify" | `BROWSER_VERIFY=true` |
132
138
 
133
139
  Example presentation to user:
134
140
  ```
@@ -187,6 +193,7 @@ Detect user intent from their message, then follow the corresponding workflow:
187
193
  - Summarize results: total features, succeeded, failed, skipped
188
194
  - If all succeeded: each feature session has already run `prizmkit-retrospective` internally. Ask user what's next.
189
195
  - If some failed: show failed feature IDs and suggest `retry-feature.sh <F-XXX>` or `reset-feature.sh <F-XXX> --clean --run`
196
+ - **Browser verification**: If any completed features have `browser_interaction` and `playwright-cli` is installed, offer to run browser verification (see §Post-Pipeline Browser Verification)
190
197
 
191
198
  **If background daemon**:
192
199
  1. Verify launch:
@@ -296,6 +303,64 @@ Notes:
296
303
  - `reset-feature.sh --clean --run` clears the feature state before retrying (fresh start).
297
304
  - Keep pipeline daemon mode for main run management (`launch-daemon.sh`).
298
305
 
306
+ ---
307
+
308
+ #### Post-Pipeline Browser Verification
309
+
310
+ After pipeline completion, if features have `browser_interaction` fields and `playwright-cli` is installed:
311
+
312
+ 1. **Check which features qualify**:
313
+ ```bash
314
+ python3 -c "
315
+ import json
316
+ with open('feature-list.json') as f:
317
+ data = json.load(f)
318
+ for feat in data.get('features', []):
319
+ bi = feat.get('browser_interaction')
320
+ if bi and feat.get('status') == 'completed':
321
+ print(f\" {feat['id']}: {feat.get('title','')} → {bi['url']}\")
322
+ " 2>/dev/null
323
+ ```
324
+
325
+ 2. **Ask user**: "N features have browser verification configured. Run playwright-cli verification now? (Y/n)"
326
+
327
+ 3. **If yes**, first learn the available commands:
328
+ ```bash
329
+ playwright-cli --help
330
+ ```
331
+ Then read `dev-pipeline/assets/playwright-cli-reference.md` for snapshot format and workflow patterns. For each qualifying feature:
332
+ ```bash
333
+ # Start dev server if setup_command is specified
334
+ # (run in background, wait for port to be ready)
335
+
336
+ # Open browser and navigate
337
+ playwright-cli open <url>
338
+
339
+ # Take initial snapshot
340
+ playwright-cli snapshot
341
+
342
+ # Execute verify_steps (if specified) — these are descriptive;
343
+ # map them to actual refs from the snapshot
344
+ # e.g., "click login button" → find button ref in snapshot → playwright-cli click <ref>
345
+
346
+ # Take final screenshot
347
+ playwright-cli screenshot
348
+
349
+ # Close browser
350
+ playwright-cli close
351
+ ```
352
+
353
+ 4. **Report results**:
354
+ - For each feature: URL opened, steps executed, screenshot path
355
+ - If any step fails (element not found, page error): flag as verification failure
356
+ - Screenshots are saved to `.playwright-cli/` for user review
357
+
358
+ 5. **Cleanup**: Stop any dev servers started by `setup_command`
359
+
360
+ **Important**: Browser verification is best-effort — failures here do NOT change the feature's pipeline status. They serve as visual confirmation aids for the user.
361
+
362
+ ---
363
+
299
364
  ### Error Handling
300
365
 
301
366
  | Error | Action |
@@ -308,6 +373,7 @@ Notes:
308
373
  | Launch failed (process died immediately) | Show last 20 lines of log: `tail -20 dev-pipeline/state/pipeline-daemon.log` |
309
374
  | Feature stuck/blocked | Use `retry-feature.sh <F-XXX>` to retry; use `reset-feature.sh <F-XXX> --clean --run` for fresh start |
310
375
  | All features blocked/failed | Show status, suggest daemon-safe recovery: `dev-pipeline/reset-feature.sh <F-XXX> --clean --run feature-list.json` |
376
+ | `playwright-cli` not installed | Browser verification skipped (non-blocking). Suggest: `npm install -g @playwright/cli@latest` |
311
377
  | Permission denied on script | Run `chmod +x dev-pipeline/launch-daemon.sh dev-pipeline/run.sh` |
312
378
 
313
379
  ### Integration Notes
@@ -1,16 +1,17 @@
1
1
  ---
2
2
  name: "prizmkit-clarify"
3
- description: "Interactive requirement clarification. Resolves ambiguities in feature specs by asking sequential questions with recommended answers. Use when spec has unclear parts or you're unsure about requirements before planning. Use this skill whenever a spec has [NEEDS CLARIFICATION] markers, vague requirements, or the user wants to refine their feature definition before planning. Trigger on: 'clarify', 'refine spec', 'resolve ambiguities', 'spec has questions', 'unsure about requirements', 'spec is unclear'. (project)"
3
+ description: "Interactive requirement clarification. Resolves ALL ambiguities in feature specs through unlimited rounds of questions until full understanding is reached. Use when spec has unclear parts, you're unsure about requirements, or before planning to ensure nothing is ambiguous. Trigger on: 'clarify', 'refine spec', 'resolve ambiguities', 'spec has questions', 'unsure about requirements', 'spec is unclear'. (project)"
4
4
  ---
5
5
 
6
6
  # PrizmKit Clarify
7
7
 
8
- Interactive requirement clarification that resolves ambiguities in feature specifications. Asks focused questions one at a time, updating the spec atomically after each answer.
8
+ Exhaustive interactive requirement clarification. Resolves **every** ambiguity in a feature specification by asking questions one at a time no limit on rounds or number of questions. The goal is **complete understanding**: do not stop until every unclear aspect is resolved and you are fully confident about the requirements.
9
9
 
10
10
  ### When to Use
11
11
  - After `/prizmkit-specify` when spec has `[NEEDS CLARIFICATION]` markers
12
12
  - User says "clarify", "resolve ambiguities", "refine spec"
13
13
  - Before `/prizmkit-plan` to ensure spec is unambiguous
14
+ - Whenever you encounter any uncertainty about what the user wants — proactively ask rather than assume
14
15
 
15
16
  **PRECONDITION:**
16
17
 
@@ -21,21 +22,38 @@ Interactive requirement clarification that resolves ambiguities in feature speci
21
22
  ## Execution Steps
22
23
 
23
24
  1. Read `spec.md` from `.prizmkit/specs/###-feature-name/`
24
- 2. Scan for `[NEEDS CLARIFICATION]` markers and underspecified areas
25
+ 2. Scan for ALL ambiguities — not just `[NEEDS CLARIFICATION]` markers but also:
26
+ - Vague terms without measurable criteria (e.g., "fast", "user-friendly", "secure")
27
+ - Missing edge cases that would affect implementation
28
+ - Implicit assumptions not stated explicitly
29
+ - Scope boundaries that could be interpreted multiple ways
30
+ - Data model gaps (entities, relationships, constraints undefined)
25
31
  3. Categorize ambiguities by dimension and prioritize — address the ones that would most affect architecture and data model first, since those are hardest to change later:
26
32
  - Data model (what entities, relationships, constraints?) — **highest priority when DB changes are involved**: field types, nullability, naming conventions, relationships, and constraint patterns must all be resolved before plan finalization. Unresolved DB design decisions during implementation lead to expensive rework.
27
33
  - Functional scope (what does it do?)
28
- - Data model (what entities, relationships?)
29
34
  - UX flow (what does the user see?)
30
35
  - Error handling (what happens when things fail?)
31
36
  - Non-functional requirements (performance, security)
32
37
  - Edge cases, integration points, accessibility
33
- 4. Ask questions one at a time (max 5 per session) — batch questions overwhelm users and produce lower-quality answers because they rush through without thinking deeply about each one
38
+ 4. Ask questions **one at a time** — batch questions overwhelm users and produce lower-quality answers because they rush through without thinking deeply about each one
34
39
  5. For each question: provide a recommended answer with rationale. The recommendation gives users a concrete starting point to accept, modify, or reject — this is much faster than open-ended questions
35
40
  6. After each answer: immediately update `spec.md` (not batched at the end). Atomic updates mean the spec is always in a consistent state, even if the session is interrupted
36
- 7. Support early termination: user says "done" or "stop" — end immediately
37
- 8. Remove resolved `[NEEDS CLARIFICATION]` markers
38
- 9. After all questions resolved or user terminates: output summary of changes made
41
+ 7. Remove resolved `[NEEDS CLARIFICATION]` markers as they are addressed
42
+ 8. **Continue asking** after each answer, re-evaluate the spec for remaining ambiguities. Each user answer may reveal new questions. Keep going until:
43
+ - All `[NEEDS CLARIFICATION]` markers are removed, AND
44
+ - No vague or underspecified areas remain, AND
45
+ - You are fully confident about the requirements
46
+ 9. Support early termination: user says "done", "stop", or "enough" — end immediately and summarize what was resolved vs what remains unclear
47
+ 10. After all questions resolved or user terminates: output summary of all changes made
48
+
49
+ ## No Limits Policy
50
+
51
+ **There is NO cap on the number of questions or rounds.** Ask as many questions as needed to achieve complete understanding. A half-understood spec leads to wrong implementations, which cost far more than thorough clarification upfront.
52
+
53
+ - If you've asked 10 questions and there are still ambiguities — keep asking
54
+ - If the user's answer raises new questions — ask those too
55
+ - If you realize a previously-resolved item needs revisiting because of new context — go back and ask again
56
+ - Only stop when you genuinely have no more uncertainties, or the user explicitly terminates
39
57
 
40
58
  ## Example Session
41
59
 
@@ -54,11 +72,19 @@ File upload: accepts JPEG, PNG, PDF, SVG. Max size: 25MB per file.
54
72
  ```
55
73
  Remove `[NEEDS CLARIFICATION]` marker from §3.2.
56
74
 
75
+ **Question 2** (new question triggered by user's answer):
76
+ > You mentioned SVG files. SVGs can contain embedded scripts which pose XSS risks. Should uploaded SVGs be sanitized (strip `<script>` tags and event handlers), or should SVG upload be restricted to trusted users only?
77
+ >
78
+ > **Recommended answer:** Sanitize all SVG uploads by stripping scripts and event handlers. This allows all users to upload SVGs safely.
79
+
80
+ *(Continue until all ambiguities are resolved...)*
81
+
57
82
  ## Guidelines
58
83
 
59
84
  - Keep questions at the WHAT/WHY level — do not introduce implementation details (HOW). The spec describes the problem space; implementation choices belong in plan.md
60
- - 5-question limit per session keeps clarification focused. If more questions remain, tell the user and suggest running clarify again after they've had time to think
61
85
  - If the user's answer contradicts an existing requirement, point out the conflict and ask which one should change
86
+ - Group related follow-up questions naturally — if a user's answer opens 3 related sub-questions, ask the most impactful one first, then proceed to the others
87
+ - If the user seems fatigued, acknowledge it: "I have N more questions. Want to continue now or come back later?" — but never silently stop with unresolved ambiguities
62
88
 
63
89
  **HANDOFF:** `/prizmkit-plan`
64
90
 
@@ -38,7 +38,7 @@ Create structured feature specifications from natural language descriptions. Thi
38
38
  - Acceptance criteria (Given/When/Then)
39
39
  - Scope boundaries (In scope / Out of scope)
40
40
  - Dependencies and constraints
41
- - `[NEEDS CLARIFICATION]` markers for ambiguous items (max 3)
41
+ - `[NEEDS CLARIFICATION]` markers for all ambiguous items
42
42
  7. **Database design detection**: If the feature involves data persistence (new entities, new fields, schema changes), add a `## Data Model` section to spec.md (see template):
43
43
  - Scan for existing database schema files to understand current conventions:
44
44
  ```bash
@@ -51,7 +51,7 @@ Create structured feature specifications from natural language descriptions. Thi
51
51
  8. Run internal quality validation loop (max 3 iterations):
52
52
  - Check: All user stories have acceptance criteria?
53
53
  - Check: Scope boundaries clearly defined?
54
- - Check: No more than 3 `[NEEDS CLARIFICATION]` markers?
54
+ - Check: All `[NEEDS CLARIFICATION]` markers have recommended defaults?
55
55
  - Check: If Data Model section exists, are existing schema conventions documented?
56
56
  9. Output: `spec.md` path and summary
57
57
 
@@ -60,7 +60,7 @@ Create structured feature specifications from natural language descriptions. Thi
60
60
  - **Focus on WHAT and WHY, never HOW** — the spec describes the problem space; implementation choices belong in plan.md. Mixing in tech stack details couples the spec to a specific solution and makes it harder to explore alternatives during planning.
61
61
  - **Every user story needs acceptance criteria** in Given/When/Then format — without them, the implementer has no way to verify the feature works correctly, and the code reviewer has no baseline to check against.
62
62
  - **Scope boundaries must be explicit** — without "Out of scope" boundaries, implementers tend to gold-plate features with capabilities nobody asked for, wasting time and adding complexity.
63
- - **Max 3 `[NEEDS CLARIFICATION]` markers** more than 3 means the feature idea isn't mature enough to spec. Suggest the user think through the concept further and return, or use `/prizmkit-clarify` to resolve them interactively.
63
+ - **Mark all unclear areas with `[NEEDS CLARIFICATION]`**do not limit the number of markers. Every genuine ambiguity should be surfaced. After spec generation, suggest running `/prizmkit-clarify` to resolve them all interactively.
64
64
  - **Feature numbers are zero-padded to 3 digits** (e.g., `001`, `012`) with a `-MMDD` timestamp suffix — ensures consistent sorting and prevents collisions when multiple sessions run concurrently.
65
65
 
66
66
  ## Handling Vague Inputs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.0.128",
3
+ "version": "1.0.130",
4
4
  "description": "Create a new PrizmKit-powered project with clean initialization — no framework dev files, just what you need.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,6 +30,12 @@ export function generateGitignore(options = {}) {
30
30
  );
31
31
  }
32
32
 
33
+ lines.push(
34
+ '# Playwright CLI 快照和截图',
35
+ '.playwright-cli/',
36
+ '',
37
+ );
38
+
33
39
  lines.push(
34
40
  '# ===========================',
35
41
  '# Common',
package/src/index.js CHANGED
@@ -67,6 +67,7 @@ export async function runScaffold(directory, options) {
67
67
  skills: options.skills || 'full',
68
68
  team: options.team !== false,
69
69
  pipeline: options.pipeline !== false,
70
+ playwrightCli: options.playwrightCli !== false,
70
71
  rules: options.rules || 'recommended',
71
72
  aiCli: options.aiCli || '',
72
73
  externalSkills: options.externalSkills ? options.externalSkills.split(',').map(s => s.trim()).filter(Boolean) : [],
@@ -202,6 +203,12 @@ export async function runScaffold(directory, options) {
202
203
  default: true,
203
204
  });
204
205
 
206
+ // 4.5. Playwright CLI (browser interaction support)
207
+ const playwrightCli = await confirm({
208
+ message: '安装浏览器交互工具 (playwright-cli)? 支持 UI 自动验证',
209
+ default: true,
210
+ });
211
+
205
212
  // 5. Rules 预设
206
213
  const rulesPreset = await select({
207
214
  message: '安装 AI 行为规则 (rules):',
@@ -227,6 +234,7 @@ export async function runScaffold(directory, options) {
227
234
  console.log(` 技能: ${chalk.cyan(suiteLabel)}`);
228
235
  console.log(` 团队模式: ${team ? chalk.green('启用') : chalk.gray('禁用')}`);
229
236
  console.log(` 流水线: ${pipeline ? chalk.green('启用') : chalk.gray('禁用')}`);
237
+ console.log(` 浏览器工具: ${playwrightCli ? chalk.green('启用') : chalk.gray('禁用')}`);
230
238
  console.log(` 规则: ${chalk.cyan(rulesPreset)}`);
231
239
  if (aiCli) console.log(` AI CLI: ${chalk.cyan(aiCli)}`);
232
240
  if (selectedExternalSkills.length > 0) console.log(` 外部技能: ${chalk.cyan(selectedExternalSkills.join(', '))}`);
@@ -249,6 +257,7 @@ export async function runScaffold(directory, options) {
249
257
  skills: skillSuite,
250
258
  team,
251
259
  pipeline,
260
+ playwrightCli,
252
261
  rules: rulesPreset,
253
262
  aiCli: aiCli || '',
254
263
  externalSkills: selectedExternalSkills,
package/src/scaffold.js CHANGED
@@ -10,9 +10,10 @@
10
10
  import chalk from 'chalk';
11
11
  import fs from 'fs-extra';
12
12
  import path from 'path';
13
- import { readFileSync } from 'fs';
13
+ import { readFileSync, existsSync } from 'fs';
14
14
  import { fileURLToPath } from 'url';
15
15
  import { dirname, join } from 'path';
16
+ import { execSync } from 'child_process';
16
17
  import {
17
18
  loadMetadata,
18
19
  getSkillsDir,
@@ -691,6 +692,46 @@ export async function installGitignore(projectRoot, options, dryRun) {
691
692
  }
692
693
  }
693
694
 
695
+ // ============================================================
696
+ // Playwright CLI 安装
697
+ // ============================================================
698
+
699
+ /**
700
+ * 安装 playwright-cli(全局 npm 包 + workspace 初始化)
701
+ * 用于浏览器交互验证(browser_interaction 功能)
702
+ */
703
+ export async function installPlaywrightCli(projectRoot, dryRun) {
704
+ if (dryRun) {
705
+ console.log(chalk.gray(' [dry-run] @playwright/cli (global install + workspace init)'));
706
+ return;
707
+ }
708
+
709
+ // Check if already installed
710
+ try {
711
+ execSync('playwright-cli --version', { stdio: 'pipe' });
712
+ console.log(chalk.green(' ✓ playwright-cli (already installed)'));
713
+ } catch {
714
+ // Not installed, install it
715
+ try {
716
+ console.log(chalk.blue(' ⏳ Installing @playwright/cli globally...'));
717
+ execSync('npm install -g @playwright/cli@latest', { stdio: 'pipe', timeout: 120000 });
718
+ console.log(chalk.green(' ✓ @playwright/cli installed globally'));
719
+ } catch (e) {
720
+ console.log(chalk.yellow(` ⚠ @playwright/cli install failed: ${e.message}`));
721
+ console.log(chalk.yellow(' ⚠ Run manually: npm install -g @playwright/cli@latest'));
722
+ return;
723
+ }
724
+ }
725
+
726
+ // Initialize workspace
727
+ try {
728
+ execSync('playwright-cli install', { cwd: projectRoot, stdio: 'pipe', timeout: 60000 });
729
+ console.log(chalk.green(' ✓ playwright-cli workspace initialized'));
730
+ } catch (e) {
731
+ console.log(chalk.yellow(` ⚠ playwright-cli workspace init skipped: ${e.message}`));
732
+ }
733
+ }
734
+
694
735
  // ============================================================
695
736
  // 主安装函数
696
737
  // ============================================================
@@ -705,11 +746,12 @@ export async function installGitignore(projectRoot, options, dryRun) {
705
746
  * @param {string} [config.rules] - Rules preset: 'recommended' | 'minimal' | 'none'
706
747
  * @param {string} [config.aiCli] - AI CLI 可执行命令(写入 .prizmkit/config.json)
707
748
  * @param {string[]} [config.externalSkills] - 要安装的外部 skill 名称列表
749
+ * @param {boolean} [config.playwrightCli] - 是否安装 playwright-cli
708
750
  * @param {string} config.projectRoot - 目标项目根目录
709
751
  * @param {boolean} config.dryRun - 是否为预览模式
710
752
  */
711
753
  export async function scaffold(config) {
712
- const { platform, skills, team, pipeline, rules, aiCli, externalSkills, projectRoot, dryRun } = config;
754
+ const { platform, skills, team, pipeline, rules, aiCli, externalSkills, playwrightCli, projectRoot, dryRun } = config;
713
755
  const platforms = platform === 'both' ? ['codebuddy', 'claude'] : [platform];
714
756
 
715
757
  if (dryRun) {
@@ -803,7 +845,14 @@ export async function scaffold(config) {
803
845
  }
804
846
  }
805
847
 
806
- // 10. Clean up stray .codebuddy/ directory left by third-party tools (e.g. npx skills)
848
+ // 10. Playwright CLI (optional)
849
+ if (playwrightCli) {
850
+ console.log(chalk.blue(' 浏览器交互工具:'));
851
+ await installPlaywrightCli(projectRoot, dryRun);
852
+ console.log('');
853
+ }
854
+
855
+ // 11. Clean up stray .codebuddy/ directory left by third-party tools (e.g. npx skills)
807
856
  // when installing for Claude Code only. CodeBuddy files should never appear in a
808
857
  // claude-only install.
809
858
  if (!dryRun && !platforms.includes('codebuddy')) {
@@ -890,6 +939,7 @@ export async function scaffold(config) {
890
939
  console.log(chalk.gray(` 平台: ${platforms.map(p => p === 'codebuddy' ? 'CodeBuddy' : 'Claude Code').join(' + ')}`));
891
940
  console.log(chalk.gray(` 团队: ${team ? '已启用' : '未启用'}`));
892
941
  console.log(chalk.gray(` 流水线: ${pipeline ? '已安装' : '未安装'}`));
942
+ console.log(chalk.gray(` 浏览器工具: ${playwrightCli ? '已安装 (playwright-cli)' : '未安装'}`));
893
943
  console.log(chalk.gray(` 规则: ${rules || 'recommended'}`));
894
944
  if (aiCli) console.log(chalk.gray(` AI CLI: ${aiCli}`));
895
945
  console.log('');