prizmkit 1.1.39 → 1.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +118 -1
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +123 -8
- package/bundled/dev-pipeline/templates/bug-fix-list-schema.json +22 -3
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +56 -0
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +64 -4
- package/bundled/dev-pipeline/templates/refactor-list-schema.json +22 -3
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +26 -4
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +35 -17
- package/bundled/skills/recovery-workflow/SKILL.md +96 -7
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +32 -7
- package/package.json +1 -1
package/bundled/VERSION.json
CHANGED
|
@@ -260,6 +260,39 @@ def build_replacements(args, bug, global_context, script_dir):
|
|
|
260
260
|
# Determine verification type
|
|
261
261
|
vtype = bug.get("verification_type", "automated")
|
|
262
262
|
|
|
263
|
+
# Browser interaction - extract from bug if present
|
|
264
|
+
browser_interaction = bug.get("browser_interaction")
|
|
265
|
+
browser_enabled = False
|
|
266
|
+
browser_verify_steps = ""
|
|
267
|
+
browser_tool = "auto"
|
|
268
|
+
|
|
269
|
+
# Environment override
|
|
270
|
+
browser_verify_env = os.environ.get("BROWSER_VERIFY", "").lower()
|
|
271
|
+
if browser_verify_env == "false":
|
|
272
|
+
browser_interaction = None
|
|
273
|
+
|
|
274
|
+
# Extract browser config (same logic as feature pipeline)
|
|
275
|
+
if browser_interaction and isinstance(browser_interaction, bool):
|
|
276
|
+
browser_enabled = True
|
|
277
|
+
browser_tool = "auto"
|
|
278
|
+
browser_verify_steps = " # (no specific verify goals — reproduce the bug and verify it's fixed)"
|
|
279
|
+
elif browser_interaction and isinstance(browser_interaction, dict):
|
|
280
|
+
browser_tool = browser_interaction.get("tool", "auto")
|
|
281
|
+
if browser_tool not in ("playwright-cli", "opencli", "auto"):
|
|
282
|
+
LOGGER.warning("Unknown browser_interaction.tool '%s', defaulting to 'auto'", browser_tool)
|
|
283
|
+
browser_tool = "auto"
|
|
284
|
+
|
|
285
|
+
steps = browser_interaction.get("verify_steps", [])
|
|
286
|
+
if steps:
|
|
287
|
+
browser_enabled = True
|
|
288
|
+
browser_verify_steps = "\n".join(
|
|
289
|
+
" # Step {}: {}".format(i + 1, step)
|
|
290
|
+
for i, step in enumerate(steps)
|
|
291
|
+
)
|
|
292
|
+
elif browser_interaction.get("url") or browser_interaction.get("enabled", True):
|
|
293
|
+
browser_enabled = True
|
|
294
|
+
browser_verify_steps = " # (reproduce bug and verify fix)"
|
|
295
|
+
|
|
263
296
|
replacements = {
|
|
264
297
|
"{{RUN_ID}}": args.run_id,
|
|
265
298
|
"{{SESSION_ID}}": args.session_id,
|
|
@@ -284,13 +317,17 @@ def build_replacements(args, bug, global_context, script_dir):
|
|
|
284
317
|
"{{PROJECT_ROOT}}": project_root,
|
|
285
318
|
"{{FIX_SCOPE}}": fix_scope,
|
|
286
319
|
"{{TIMESTAMP}}": "", # Placeholder, agent fills in the timestamp
|
|
320
|
+
"{{BROWSER_ENABLED}}": "true" if browser_enabled else "false",
|
|
321
|
+
"{{BROWSER_TOOL}}": browser_tool,
|
|
322
|
+
"{{BROWSER_VERIFY_STEPS}}": browser_verify_steps,
|
|
287
323
|
}
|
|
288
324
|
|
|
289
325
|
return replacements
|
|
290
326
|
|
|
291
327
|
|
|
292
328
|
def process_conditional_blocks(content, bug):
|
|
293
|
-
"""Handle conditional blocks based on verification_type."""
|
|
329
|
+
"""Handle conditional blocks based on verification_type and browser_interaction."""
|
|
330
|
+
# Handle verification type blocks
|
|
294
331
|
vtype = bug.get("verification_type", "automated")
|
|
295
332
|
is_manual_or_hybrid = vtype in ("manual", "hybrid")
|
|
296
333
|
|
|
@@ -306,6 +343,64 @@ def process_conditional_blocks(content, bug):
|
|
|
306
343
|
"", content, flags=re.DOTALL,
|
|
307
344
|
)
|
|
308
345
|
|
|
346
|
+
# Handle browser interaction blocks
|
|
347
|
+
browser_interaction = bug.get("browser_interaction")
|
|
348
|
+
browser_enabled = False
|
|
349
|
+
browser_tool = "auto"
|
|
350
|
+
|
|
351
|
+
# Check environment override
|
|
352
|
+
browser_verify_env = os.environ.get("BROWSER_VERIFY", "").lower()
|
|
353
|
+
if browser_verify_env == "false":
|
|
354
|
+
browser_interaction = None
|
|
355
|
+
|
|
356
|
+
# Determine if browser is enabled
|
|
357
|
+
if browser_interaction:
|
|
358
|
+
if isinstance(browser_interaction, bool):
|
|
359
|
+
browser_enabled = True
|
|
360
|
+
elif isinstance(browser_interaction, dict):
|
|
361
|
+
steps = browser_interaction.get("verify_steps", [])
|
|
362
|
+
if steps or browser_interaction.get("url") or browser_interaction.get("enabled", True):
|
|
363
|
+
browser_enabled = True
|
|
364
|
+
browser_tool = browser_interaction.get("tool", "auto")
|
|
365
|
+
|
|
366
|
+
# Process browser interaction blocks
|
|
367
|
+
browser_open = "{{IF_BROWSER_INTERACTION}}"
|
|
368
|
+
browser_close = "{{END_IF_BROWSER_INTERACTION}}"
|
|
369
|
+
|
|
370
|
+
if browser_enabled:
|
|
371
|
+
# Keep content, remove tags
|
|
372
|
+
content = content.replace(browser_open + "\n", "")
|
|
373
|
+
content = content.replace(browser_open, "")
|
|
374
|
+
content = content.replace(browser_close + "\n", "")
|
|
375
|
+
content = content.replace(browser_close, "")
|
|
376
|
+
else:
|
|
377
|
+
# Remove entire block
|
|
378
|
+
pattern = re.escape(browser_open) + r".*?" + re.escape(browser_close) + r"\n?"
|
|
379
|
+
content = re.sub(pattern, "", content, flags=re.DOTALL)
|
|
380
|
+
|
|
381
|
+
# Process browser tool selection blocks (nested inside browser interaction)
|
|
382
|
+
tool_variants = ["PLAYWRIGHT", "OPENCLI", "AUTO"]
|
|
383
|
+
active_variant = {
|
|
384
|
+
"playwright-cli": "PLAYWRIGHT",
|
|
385
|
+
"opencli": "OPENCLI",
|
|
386
|
+
"auto": "AUTO",
|
|
387
|
+
}.get(browser_tool, "AUTO")
|
|
388
|
+
|
|
389
|
+
for variant in tool_variants:
|
|
390
|
+
tool_open = "{{{{IF_BROWSER_TOOL_{}}}}}".format(variant)
|
|
391
|
+
tool_close = "{{{{END_IF_BROWSER_TOOL_{}}}}}".format(variant)
|
|
392
|
+
|
|
393
|
+
if variant == active_variant and browser_enabled:
|
|
394
|
+
# Keep content, remove tags
|
|
395
|
+
content = content.replace(tool_open + "\n", "")
|
|
396
|
+
content = content.replace(tool_open, "")
|
|
397
|
+
content = content.replace(tool_close + "\n", "")
|
|
398
|
+
content = content.replace(tool_close, "")
|
|
399
|
+
else:
|
|
400
|
+
# Remove entire block
|
|
401
|
+
pat = re.escape(tool_open) + r".*?" + re.escape(tool_close) + r"\n?"
|
|
402
|
+
content = re.sub(pat, "", content, flags=re.DOTALL)
|
|
403
|
+
|
|
309
404
|
return content
|
|
310
405
|
|
|
311
406
|
|
|
@@ -529,6 +624,26 @@ def main():
|
|
|
529
624
|
|
|
530
625
|
# Success
|
|
531
626
|
bug_model = bug.get("model", "")
|
|
627
|
+
# Extract browser interaction state for output
|
|
628
|
+
browser_interaction = bug.get("browser_interaction")
|
|
629
|
+
browser_enabled = False
|
|
630
|
+
browser_tool = "auto"
|
|
631
|
+
|
|
632
|
+
browser_verify_env = os.environ.get("BROWSER_VERIFY", "").lower()
|
|
633
|
+
if browser_verify_env == "false":
|
|
634
|
+
browser_interaction = None
|
|
635
|
+
|
|
636
|
+
if browser_interaction:
|
|
637
|
+
if isinstance(browser_interaction, bool):
|
|
638
|
+
browser_enabled = True
|
|
639
|
+
elif isinstance(browser_interaction, dict):
|
|
640
|
+
steps = browser_interaction.get("verify_steps", [])
|
|
641
|
+
if steps or browser_interaction.get("url") or browser_interaction.get("enabled", True):
|
|
642
|
+
browser_enabled = True
|
|
643
|
+
browser_tool = browser_interaction.get("tool", "auto")
|
|
644
|
+
if browser_tool not in ("playwright-cli", "opencli", "auto"):
|
|
645
|
+
browser_tool = "auto"
|
|
646
|
+
|
|
532
647
|
output = {
|
|
533
648
|
"success": True,
|
|
534
649
|
"output_path": os.path.abspath(args.output),
|
|
@@ -537,6 +652,8 @@ def main():
|
|
|
537
652
|
"pipeline_mode": pipeline_mode,
|
|
538
653
|
"agent_count": agent_count,
|
|
539
654
|
"critic_enabled": critic_enabled,
|
|
655
|
+
"browser_enabled": browser_enabled,
|
|
656
|
+
"browser_tool": browser_tool
|
|
540
657
|
}
|
|
541
658
|
print(json.dumps(output, indent=2, ensure_ascii=False))
|
|
542
659
|
sys.exit(0)
|
|
@@ -420,6 +420,39 @@ def build_replacements(args, refactor, refactors, global_context, script_dir):
|
|
|
420
420
|
else:
|
|
421
421
|
new_tests_str = "- (none specified)"
|
|
422
422
|
|
|
423
|
+
# Browser interaction - extract from refactor if present
|
|
424
|
+
browser_interaction = refactor.get("browser_interaction")
|
|
425
|
+
browser_enabled = False
|
|
426
|
+
browser_verify_steps = ""
|
|
427
|
+
browser_tool = "auto"
|
|
428
|
+
|
|
429
|
+
# Environment override
|
|
430
|
+
browser_verify_env = os.environ.get("BROWSER_VERIFY", "").lower()
|
|
431
|
+
if browser_verify_env == "false":
|
|
432
|
+
browser_interaction = None
|
|
433
|
+
|
|
434
|
+
# Extract browser config (same logic as feature and bugfix pipelines)
|
|
435
|
+
if browser_interaction and isinstance(browser_interaction, bool):
|
|
436
|
+
browser_enabled = True
|
|
437
|
+
browser_tool = "auto"
|
|
438
|
+
browser_verify_steps = " # (no specific verify goals — validate UI renders correctly and feature still works)"
|
|
439
|
+
elif browser_interaction and isinstance(browser_interaction, dict):
|
|
440
|
+
browser_tool = browser_interaction.get("tool", "auto")
|
|
441
|
+
if browser_tool not in ("playwright-cli", "opencli", "auto"):
|
|
442
|
+
LOGGER.warning("Unknown browser_interaction.tool '%s', defaulting to 'auto'", browser_tool)
|
|
443
|
+
browser_tool = "auto"
|
|
444
|
+
|
|
445
|
+
steps = browser_interaction.get("verify_steps", [])
|
|
446
|
+
if steps:
|
|
447
|
+
browser_enabled = True
|
|
448
|
+
browser_verify_steps = "\n".join(
|
|
449
|
+
" # Step {}: {}".format(i + 1, step)
|
|
450
|
+
for i, step in enumerate(steps)
|
|
451
|
+
)
|
|
452
|
+
elif browser_interaction.get("url") or browser_interaction.get("enabled", True):
|
|
453
|
+
browser_enabled = True
|
|
454
|
+
browser_verify_steps = " # (validate UI renders correctly and feature still works)"
|
|
455
|
+
|
|
423
456
|
replacements = {
|
|
424
457
|
"{{RUN_ID}}": args.run_id,
|
|
425
458
|
"{{SESSION_ID}}": args.session_id,
|
|
@@ -452,16 +485,17 @@ def build_replacements(args, refactor, refactors, global_context, script_dir):
|
|
|
452
485
|
),
|
|
453
486
|
"{{TIMESTAMP}}": "", # Placeholder — agent fills in timestamp
|
|
454
487
|
"{{PLATFORM_CONVENTIONS}}": read_platform_conventions(project_root),
|
|
488
|
+
"{{BROWSER_ENABLED}}": "true" if browser_enabled else "false",
|
|
489
|
+
"{{BROWSER_TOOL}}": browser_tool,
|
|
490
|
+
"{{BROWSER_VERIFY_STEPS}}": browser_verify_steps,
|
|
455
491
|
}
|
|
456
492
|
|
|
457
493
|
return replacements
|
|
458
494
|
|
|
459
495
|
|
|
460
|
-
def process_conditional_blocks(content, resume_phase):
|
|
461
|
-
"""Handle conditional blocks based on resume_phase.
|
|
462
|
-
|
|
463
|
-
- {{IF_FRESH_START}}...{{END_IF_FRESH_START}} — include only on fresh start (resume_phase == "null")
|
|
464
|
-
"""
|
|
496
|
+
def process_conditional_blocks(content, resume_phase, refactor):
|
|
497
|
+
"""Handle conditional blocks based on resume_phase and browser_interaction."""
|
|
498
|
+
# Handle fresh start blocks
|
|
465
499
|
is_resume = resume_phase != "null"
|
|
466
500
|
|
|
467
501
|
if is_resume:
|
|
@@ -475,13 +509,72 @@ def process_conditional_blocks(content, resume_phase):
|
|
|
475
509
|
content = content.replace("{{END_IF_FRESH_START}}\n", "")
|
|
476
510
|
content = content.replace("{{END_IF_FRESH_START}}", "")
|
|
477
511
|
|
|
512
|
+
# Handle browser interaction blocks
|
|
513
|
+
browser_interaction = refactor.get("browser_interaction")
|
|
514
|
+
browser_enabled = False
|
|
515
|
+
browser_tool = "auto"
|
|
516
|
+
|
|
517
|
+
# Check environment override
|
|
518
|
+
browser_verify_env = os.environ.get("BROWSER_VERIFY", "").lower()
|
|
519
|
+
if browser_verify_env == "false":
|
|
520
|
+
browser_interaction = None
|
|
521
|
+
|
|
522
|
+
# Determine if browser is enabled
|
|
523
|
+
if browser_interaction:
|
|
524
|
+
if isinstance(browser_interaction, bool):
|
|
525
|
+
browser_enabled = True
|
|
526
|
+
elif isinstance(browser_interaction, dict):
|
|
527
|
+
steps = browser_interaction.get("verify_steps", [])
|
|
528
|
+
if steps or browser_interaction.get("url") or browser_interaction.get("enabled", True):
|
|
529
|
+
browser_enabled = True
|
|
530
|
+
browser_tool = browser_interaction.get("tool", "auto")
|
|
531
|
+
|
|
532
|
+
# Process browser interaction blocks
|
|
533
|
+
browser_open = "{{IF_BROWSER_INTERACTION}}"
|
|
534
|
+
browser_close = "{{END_IF_BROWSER_INTERACTION}}"
|
|
535
|
+
|
|
536
|
+
if browser_enabled:
|
|
537
|
+
# Keep content, remove tags
|
|
538
|
+
content = content.replace(browser_open + "\n", "")
|
|
539
|
+
content = content.replace(browser_open, "")
|
|
540
|
+
content = content.replace(browser_close + "\n", "")
|
|
541
|
+
content = content.replace(browser_close, "")
|
|
542
|
+
else:
|
|
543
|
+
# Remove entire block
|
|
544
|
+
pattern = re.escape(browser_open) + r".*?" + re.escape(browser_close) + r"\n?"
|
|
545
|
+
content = re.sub(pattern, "", content, flags=re.DOTALL)
|
|
546
|
+
|
|
547
|
+
# Process browser tool selection blocks (nested inside browser interaction)
|
|
548
|
+
tool_variants = ["PLAYWRIGHT", "OPENCLI", "AUTO"]
|
|
549
|
+
active_variant = {
|
|
550
|
+
"playwright-cli": "PLAYWRIGHT",
|
|
551
|
+
"opencli": "OPENCLI",
|
|
552
|
+
"auto": "AUTO",
|
|
553
|
+
}.get(browser_tool, "AUTO")
|
|
554
|
+
|
|
555
|
+
for variant in tool_variants:
|
|
556
|
+
tool_open = "{{{{IF_BROWSER_TOOL_{}}}}}".format(variant)
|
|
557
|
+
tool_close = "{{{{END_IF_BROWSER_TOOL_{}}}}}".format(variant)
|
|
558
|
+
|
|
559
|
+
if variant == active_variant and browser_enabled:
|
|
560
|
+
# Keep content, remove tags
|
|
561
|
+
content = content.replace(tool_open + "\n", "")
|
|
562
|
+
content = content.replace(tool_open, "")
|
|
563
|
+
content = content.replace(tool_close + "\n", "")
|
|
564
|
+
content = content.replace(tool_close, "")
|
|
565
|
+
else:
|
|
566
|
+
# Remove entire block
|
|
567
|
+
pat = re.escape(tool_open) + r".*?" + re.escape(tool_close) + r"\n?"
|
|
568
|
+
content = re.sub(pat, "", content, flags=re.DOTALL)
|
|
569
|
+
|
|
478
570
|
return content
|
|
479
571
|
|
|
480
572
|
|
|
481
|
-
|
|
573
|
+
|
|
574
|
+
def render_template(template_content, replacements, resume_phase, refactor):
|
|
482
575
|
"""Render the template by processing conditionals and replacing placeholders."""
|
|
483
576
|
# Step 1: Process conditional blocks
|
|
484
|
-
content = process_conditional_blocks(template_content, resume_phase)
|
|
577
|
+
content = process_conditional_blocks(template_content, resume_phase, refactor)
|
|
485
578
|
|
|
486
579
|
# Step 2: Replace all {{PLACEHOLDER}} variables
|
|
487
580
|
for placeholder, value in replacements.items():
|
|
@@ -560,7 +653,7 @@ def main():
|
|
|
560
653
|
replacements = build_replacements(args, refactor, refactors, global_context, script_dir)
|
|
561
654
|
|
|
562
655
|
# Render the template
|
|
563
|
-
rendered = render_template(template_content, replacements, args.resume_phase)
|
|
656
|
+
rendered = render_template(template_content, replacements, args.resume_phase, refactor)
|
|
564
657
|
|
|
565
658
|
# Write the output
|
|
566
659
|
err = write_output(args.output, rendered)
|
|
@@ -610,13 +703,35 @@ def main():
|
|
|
610
703
|
|
|
611
704
|
# Success
|
|
612
705
|
refactor_model = refactor.get("model", "")
|
|
706
|
+
|
|
707
|
+
# Extract browser state for JSON output
|
|
708
|
+
browser_interaction = refactor.get("browser_interaction")
|
|
709
|
+
browser_enabled = False
|
|
710
|
+
browser_tool = "auto"
|
|
711
|
+
|
|
712
|
+
browser_verify_env = os.environ.get("BROWSER_VERIFY", "").lower()
|
|
713
|
+
if browser_verify_env == "false":
|
|
714
|
+
browser_interaction = None
|
|
715
|
+
|
|
716
|
+
if browser_interaction:
|
|
717
|
+
if isinstance(browser_interaction, bool):
|
|
718
|
+
browser_enabled = True
|
|
719
|
+
elif isinstance(browser_interaction, dict):
|
|
720
|
+
steps = browser_interaction.get("verify_steps", [])
|
|
721
|
+
if steps or browser_interaction.get("url") or browser_interaction.get("enabled", True):
|
|
722
|
+
browser_enabled = True
|
|
723
|
+
browser_tool = browser_interaction.get("tool", "auto")
|
|
724
|
+
|
|
613
725
|
output = {
|
|
614
726
|
"success": True,
|
|
615
727
|
"output_path": os.path.abspath(args.output),
|
|
728
|
+
"checkpoint_path": checkpoint_path,
|
|
616
729
|
"model": refactor_model,
|
|
617
730
|
"pipeline_mode": pipeline_mode,
|
|
618
731
|
"agent_count": agent_count,
|
|
619
732
|
"critic_enabled": critic_enabled,
|
|
733
|
+
"browser_enabled": browser_enabled,
|
|
734
|
+
"browser_tool": browser_tool,
|
|
620
735
|
}
|
|
621
736
|
print(json.dumps(output, indent=2, ensure_ascii=False))
|
|
622
737
|
sys.exit(0)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"title": "Dev-Pipeline Bug Fix List",
|
|
4
|
-
"description": "Schema for .prizmkit/plans/bug-fix-list.json
|
|
4
|
+
"description": "Schema for .prizmkit/plans/bug-fix-list.json — standardized input for the Bug Fix Pipeline",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"required": [
|
|
7
7
|
"$schema",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"title": {
|
|
52
52
|
"type": "string",
|
|
53
53
|
"minLength": 1,
|
|
54
|
-
"description": "Bug title
|
|
54
|
+
"description": "Bug title — brief description of the symptom"
|
|
55
55
|
},
|
|
56
56
|
"description": {
|
|
57
57
|
"type": "string",
|
|
@@ -194,6 +194,25 @@
|
|
|
194
194
|
"model": {
|
|
195
195
|
"type": "string",
|
|
196
196
|
"description": "AI model ID for this bug fix. Overrides $MODEL env var."
|
|
197
|
+
},
|
|
198
|
+
"browser_interaction": {
|
|
199
|
+
"type": "object",
|
|
200
|
+
"description": "Browser verification config for bugs reproducible via UI. Supports playwright-cli and opencli. AI auto-detects dev server command, URL, and port from project config at runtime.",
|
|
201
|
+
"properties": {
|
|
202
|
+
"tool": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"enum": ["playwright-cli", "opencli", "auto"],
|
|
205
|
+
"default": "auto",
|
|
206
|
+
"description": "Browser tool to use. 'auto' (default) = AI chooses at runtime. 'playwright-cli' = local dev server verification in isolated browser. 'opencli' = reuses Chrome logged-in session, ideal for verifying bugs related to third-party integrations or OAuth flows."
|
|
207
|
+
},
|
|
208
|
+
"verify_steps": {
|
|
209
|
+
"type": "array",
|
|
210
|
+
"description": "Verification goals describing HOW to reproduce and verify the bug fix (e.g., 'Click login button and verify error message is gone', 'Open dashboard and confirm performance metrics display'). AI decides concrete browser tool actions at runtime. If omitted, AI auto-reproduces from error description.",
|
|
211
|
+
"items": {
|
|
212
|
+
"type": "string"
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
197
216
|
}
|
|
198
217
|
}
|
|
199
218
|
}
|
|
@@ -241,4 +260,4 @@
|
|
|
241
260
|
}
|
|
242
261
|
}
|
|
243
262
|
}
|
|
244
|
-
}
|
|
263
|
+
}
|
|
@@ -82,6 +82,34 @@ You are the **bug fix session agent**. Fix Bug {{BUG_ID}}: "{{BUG_TITLE}}".
|
|
|
82
82
|
mkdir -p .prizmkit/bugfix/{{BUG_ID}}
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
{{IF_BROWSER_INTERACTION}}
|
|
86
|
+
|
|
87
|
+
#### Browser Verification Setup
|
|
88
|
+
|
|
89
|
+
The bug may be reproducible via the UI using browser tools:
|
|
90
|
+
|
|
91
|
+
{{IF_BROWSER_TOOL_AUTO}}
|
|
92
|
+
- **Browser Tool**: Will be auto-selected based on error type and dev server configuration
|
|
93
|
+
{{END_IF_BROWSER_TOOL_AUTO}}
|
|
94
|
+
|
|
95
|
+
{{IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
96
|
+
- **Browser Tool**: playwright-cli (local isolated browser against dev server)
|
|
97
|
+
{{END_IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
98
|
+
|
|
99
|
+
{{IF_BROWSER_TOOL_OPENCLI}}
|
|
100
|
+
- **Browser Tool**: opencli (Chrome session with existing login context — ideal for OAuth/third-party integrations)
|
|
101
|
+
{{END_IF_BROWSER_TOOL_OPENCLI}}
|
|
102
|
+
|
|
103
|
+
**Browser Verification Goals**:
|
|
104
|
+
{{BROWSER_VERIFY_STEPS}}
|
|
105
|
+
|
|
106
|
+
If the bug is related to UI/frontend, you may use these tools to:
|
|
107
|
+
1. Reproduce the bug in a running dev server
|
|
108
|
+
2. Verify the fix after implementation
|
|
109
|
+
3. Smoke-test related UI flows for regression
|
|
110
|
+
|
|
111
|
+
{{END_IF_BROWSER_INTERACTION}}
|
|
112
|
+
|
|
85
113
|
### Phase 1: Diagnose & Plan
|
|
86
114
|
|
|
87
115
|
**Goal**: Identify root cause, build project context, produce spec.md + plan.md.
|
|
@@ -112,6 +140,10 @@ Run `/prizmkit-plan` with `artifact_dir=.prizmkit/bugfix/{{BUG_ID}}/`:
|
|
|
112
140
|
- Subsequent tasks implement the minimal fix to make the test pass (GREEN state)
|
|
113
141
|
- Resolve any `[NEEDS CLARIFICATION]` markers autonomously — do NOT pause
|
|
114
142
|
|
|
143
|
+
{{IF_BROWSER_INTERACTION}}
|
|
144
|
+
- **Browser Verification**: If the bug is UI-reproducible, plan.md should include browser-based reproduction as an optional verification step
|
|
145
|
+
{{END_IF_BROWSER_INTERACTION}}
|
|
146
|
+
|
|
115
147
|
**DECISION GATE — Fast Path Check**:
|
|
116
148
|
- If plan.md has ≤ 2 tasks AND root cause is obvious → mark `FAST_PATH=true`, skip Phase 3 (Review) later
|
|
117
149
|
|
|
@@ -137,6 +169,16 @@ Run `/prizmkit-implement` with `artifact_dir=.prizmkit/bugfix/{{BUG_ID}}/`:
|
|
|
137
169
|
- Runs test suite after each task
|
|
138
170
|
- Uses convergence-based test failure recovery (keep fixing while progress is being made)
|
|
139
171
|
|
|
172
|
+
{{IF_BROWSER_INTERACTION}}
|
|
173
|
+
|
|
174
|
+
**Browser Verification During Implementation**:
|
|
175
|
+
- After each code fix, you may optionally use browser tools to verify the behavior
|
|
176
|
+
- Reproduce the original bug steps and confirm they no longer occur
|
|
177
|
+
- Test related UI flows to ensure no regression
|
|
178
|
+
- Document any manual verification steps in the implementation notes
|
|
179
|
+
|
|
180
|
+
{{END_IF_BROWSER_INTERACTION}}
|
|
181
|
+
|
|
140
182
|
After implement completes, verify:
|
|
141
183
|
1. All tasks in plan.md are `[x]`
|
|
142
184
|
2. Reproduction test passes (GREEN)
|
|
@@ -158,6 +200,15 @@ Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/bugfix/{{BUG_ID}}/`:
|
|
|
158
200
|
- If PASS: proceed
|
|
159
201
|
- If NEEDS_FIXES: the skill exhausted its max rounds; log remaining findings and proceed
|
|
160
202
|
|
|
203
|
+
{{IF_BROWSER_INTERACTION}}
|
|
204
|
+
|
|
205
|
+
**Code Review — Browser Verification Check**:
|
|
206
|
+
- Verify that browser-based reproduction steps (if applicable) are clearly documented
|
|
207
|
+
- Confirm that the fix maintains the expected UI behavior for all affected flows
|
|
208
|
+
- Validate that any manual verification steps have been completed successfully
|
|
209
|
+
|
|
210
|
+
{{END_IF_BROWSER_INTERACTION}}
|
|
211
|
+
|
|
161
212
|
**CP-3**: Code review complete, all tests green.
|
|
162
213
|
|
|
163
214
|
**Checkpoint update**: Set step `prizmkit-code-review` to `"completed"`.
|
|
@@ -206,6 +257,11 @@ The fix-report.md MUST contain:
|
|
|
206
257
|
- **Bug Resolution Summary**: ID, title, status, phases completed
|
|
207
258
|
- **What Was Fixed**: changes made, diff summary, commit hash
|
|
208
259
|
- **Verification Results**: reproduction test before/after, regression tests, review findings
|
|
260
|
+
|
|
261
|
+
{{IF_BROWSER_INTERACTION}}
|
|
262
|
+
- **Browser Verification Results**: UI flows tested, browser tool used (if any), manual verification steps completed
|
|
263
|
+
{{END_IF_BROWSER_INTERACTION}}
|
|
264
|
+
|
|
209
265
|
- **Knowledge Captured**: TRAPS updated (if any), prevention recommendation
|
|
210
266
|
- **Acceptance Criteria Verification**: checklist with pass/fail for each criterion
|
|
211
267
|
|
|
@@ -123,6 +123,37 @@ Run `/prizmkit-plan` with `artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/`:
|
|
|
123
123
|
|
|
124
124
|
Resolve any `[NEEDS CLARIFICATION]` markers using the refactor description — do NOT pause for interactive input.
|
|
125
125
|
|
|
126
|
+
{{IF_BROWSER_INTERACTION}}
|
|
127
|
+
|
|
128
|
+
#### Browser Verification Strategy
|
|
129
|
+
|
|
130
|
+
The refactor may affect UI behavior. Browser verification can validate:
|
|
131
|
+
- **UI Render**: UI components render identically after refactoring
|
|
132
|
+
- **User Interactions**: Navigation, form submissions, and workflows function as before
|
|
133
|
+
- **Feature Coverage**: Refactored features work end-to-end in real browser environment
|
|
134
|
+
|
|
135
|
+
{{IF_BROWSER_TOOL_AUTO}}
|
|
136
|
+
Browser tool will be auto-selected at runtime based on dev server and feature complexity.
|
|
137
|
+
{{END_IF_BROWSER_TOOL_AUTO}}
|
|
138
|
+
|
|
139
|
+
{{IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
140
|
+
**Tool: playwright-cli** — Local isolated browser instance for dev server verification
|
|
141
|
+
{{END_IF_BROWSER_TOOL_PLAYWRIGHT}}
|
|
142
|
+
|
|
143
|
+
{{IF_BROWSER_TOOL_OPENCLI}}
|
|
144
|
+
**Tool: opencli** — Chrome session with existing login for testing OAuth/third-party integrations
|
|
145
|
+
{{END_IF_BROWSER_TOOL_OPENCLI}}
|
|
146
|
+
|
|
147
|
+
**Verification Goals**:
|
|
148
|
+
{{BROWSER_VERIFY_STEPS}}
|
|
149
|
+
|
|
150
|
+
Include browser verification approach in plan.md:
|
|
151
|
+
- Which UI flows should be smoke-tested after refactoring?
|
|
152
|
+
- Any specific user journeys affected by the structural changes?
|
|
153
|
+
- Should verification be part of review phase or implementation phase?
|
|
154
|
+
|
|
155
|
+
{{END_IF_BROWSER_INTERACTION}}
|
|
156
|
+
|
|
126
157
|
- **CP-RF-1**: Both `spec.md` and `plan.md` exist in `.prizmkit/refactor/{{REFACTOR_ID}}/`
|
|
127
158
|
- **Checkpoint update**: set step `prizmkit-plan` to `"completed"` in `{{CHECKPOINT_PATH}}`
|
|
128
159
|
|
|
@@ -144,8 +175,19 @@ Resolve any `[NEEDS CLARIFICATION]` markers using the refactor description — d
|
|
|
144
175
|
- If tests fail: revert the task, analyze why, try alternative approach
|
|
145
176
|
- Writes '## Implementation Log' to context-snapshot.md (or equivalent)
|
|
146
177
|
5. Do NOT change behavior — only improve structure
|
|
147
|
-
|
|
148
|
-
|
|
178
|
+
|
|
179
|
+
{{IF_BROWSER_INTERACTION}}
|
|
180
|
+
|
|
181
|
+
6. **Browser Smoke Tests** (after every major refactor task):
|
|
182
|
+
- Use browser tools to verify UI still renders correctly
|
|
183
|
+
- Test the primary user flows affected by the refactoring
|
|
184
|
+
- Confirm no visual or interactive regressions
|
|
185
|
+
- Document any manual browser verification steps in implementation notes
|
|
186
|
+
|
|
187
|
+
{{END_IF_BROWSER_INTERACTION}}
|
|
188
|
+
|
|
189
|
+
7. If the refactor involves multiple files: run `/compact` after completing half the tasks to free context budget. If `/compact` is unavailable, continue without it.
|
|
190
|
+
8. After all tasks complete, run the full test suite one final time
|
|
149
191
|
"
|
|
150
192
|
- **Wait for Dev to return**
|
|
151
193
|
- If Dev reports test failures that cannot be resolved after 3 attempts: escalate, write status="failed"
|
|
@@ -164,8 +206,19 @@ Resolve any `[NEEDS CLARIFICATION]` markers using the refactor description — d
|
|
|
164
206
|
2. Read `.prizmkit/refactor/{{REFACTOR_ID}}/plan.md` for architecture decisions and completed tasks
|
|
165
207
|
3. Run `/prizmkit-code-review` with artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/. The skill runs an internal review-fix loop (Reviewer → filter → Dev fix, max 3 rounds) and writes review-report.md.
|
|
166
208
|
4. Run full test suite and verify ALL tests pass
|
|
167
|
-
|
|
168
|
-
|
|
209
|
+
|
|
210
|
+
{{IF_BROWSER_INTERACTION}}
|
|
211
|
+
|
|
212
|
+
5. **Browser Verification Review**:
|
|
213
|
+
- Verify that critical user workflows still function end-to-end in browser
|
|
214
|
+
- Confirm UI renders consistently after structural changes
|
|
215
|
+
- Validate any behavior-sensitive components behave identically
|
|
216
|
+
- Document browser verification findings in review-report.md
|
|
217
|
+
|
|
218
|
+
{{END_IF_BROWSER_INTERACTION}}
|
|
219
|
+
|
|
220
|
+
6. review-report.md will be written to .prizmkit/refactor/{{REFACTOR_ID}}/ by prizmkit-code-review
|
|
221
|
+
7. Report: verdict (PASS/NEEDS_FIXES), number of rounds, findings fixed/rejected
|
|
169
222
|
"
|
|
170
223
|
- **Wait for Reviewer to return**
|
|
171
224
|
- Read `review-report.md` — if PASS proceed, if NEEDS_FIXES log remaining findings and proceed.
|
|
@@ -193,6 +246,13 @@ Resolve any `[NEEDS CLARIFICATION]` markers using the refactor description — d
|
|
|
193
246
|
- Refactor Summary (ID, title, type, status, phases completed)
|
|
194
247
|
- What Changed (files modified, structural changes made, diff summary)
|
|
195
248
|
- Behavior Verification (test suite results before/after, specific tests exercised)
|
|
249
|
+
|
|
250
|
+
{{IF_BROWSER_INTERACTION}}
|
|
251
|
+
|
|
252
|
+
- Browser Verification (UI flows tested, tools used, any manual verification performed)
|
|
253
|
+
|
|
254
|
+
{{END_IF_BROWSER_INTERACTION}}
|
|
255
|
+
|
|
196
256
|
- Code Quality Metrics (if measurable: files consolidated, duplication reduced, etc.)
|
|
197
257
|
- Acceptance Criteria Verification (checklist with pass/fail for each criterion)
|
|
198
258
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"title": "Dev-Pipeline Refactor List",
|
|
4
|
-
"description": "Schema for .prizmkit/plans/refactor-list.json
|
|
4
|
+
"description": "Schema for .prizmkit/plans/refactor-list.json — standardized input for the Refactor Pipeline",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"required": [
|
|
7
7
|
"$schema",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"title": {
|
|
55
55
|
"type": "string",
|
|
56
56
|
"minLength": 1,
|
|
57
|
-
"description": "Refactor title
|
|
57
|
+
"description": "Refactor title — brief description of the change"
|
|
58
58
|
},
|
|
59
59
|
"description": {
|
|
60
60
|
"type": "string",
|
|
@@ -201,6 +201,25 @@
|
|
|
201
201
|
1,
|
|
202
202
|
3
|
|
203
203
|
]
|
|
204
|
+
},
|
|
205
|
+
"browser_interaction": {
|
|
206
|
+
"type": "object",
|
|
207
|
+
"description": "Browser verification config for refactors affecting UI behavior. Supports playwright-cli and opencli. AI auto-detects dev server command, URL, and port from project config at runtime.",
|
|
208
|
+
"properties": {
|
|
209
|
+
"tool": {
|
|
210
|
+
"type": "string",
|
|
211
|
+
"enum": ["playwright-cli", "opencli", "auto"],
|
|
212
|
+
"default": "auto",
|
|
213
|
+
"description": "Browser tool to use. 'auto' (default) = AI chooses at runtime. 'playwright-cli' = local dev server verification in isolated browser. 'opencli' = reuses Chrome logged-in session, ideal for verifying refactors involving third-party integrations or OAuth flows."
|
|
214
|
+
},
|
|
215
|
+
"verify_steps": {
|
|
216
|
+
"type": "array",
|
|
217
|
+
"description": "Verification goals describing WHAT to verify after refactoring (e.g., 'Navigation still works', 'Form submission succeeds', 'UI renders identically'). AI decides concrete browser tool actions at runtime. If omitted, AI explores the app and verifies no visual or behavioral regressions.",
|
|
218
|
+
"items": {
|
|
219
|
+
"type": "string"
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
204
223
|
}
|
|
205
224
|
}
|
|
206
225
|
}
|
|
@@ -248,4 +267,4 @@
|
|
|
248
267
|
}
|
|
249
268
|
}
|
|
250
269
|
}
|
|
251
|
-
}
|
|
270
|
+
}
|
|
@@ -50,10 +50,14 @@ Before any action, validate:
|
|
|
50
50
|
1. **bugfix pipeline exists**: Confirm `dev-pipeline/launch-bugfix-daemon.sh` and `dev-pipeline/run-bugfix.sh` are present and executable
|
|
51
51
|
2. **For start**: `.prizmkit/plans/bug-fix-list.json` must exist in `.prizmkit/plans/` (or user-specified path)
|
|
52
52
|
3. **Dependencies**: `jq`, `python3`, AI CLI (`cbc` or `claude`) must be in PATH
|
|
53
|
+
4. **Browser tools** (optional): If any bug has `browser_interaction` field, check the corresponding tool is available. Bugs may specify `tool: "playwright-cli"`, `tool: "opencli"`, or `tool: "auto"` (AI chooses at runtime).
|
|
53
54
|
|
|
54
55
|
Quick check:
|
|
55
56
|
```bash
|
|
56
57
|
command -v jq && command -v python3 && (command -v cbc || command -v claude) && echo "All dependencies OK"
|
|
58
|
+
# Optional: browser interaction support (check both tools — bugs may use either)
|
|
59
|
+
command -v playwright-cli && echo "playwright-cli OK" || echo "playwright-cli not found (playwright browser verification will be skipped)"
|
|
60
|
+
command -v opencli && echo "opencli OK" || echo "opencli not found (opencli browser verification will be skipped)"
|
|
57
61
|
```
|
|
58
62
|
|
|
59
63
|
If `.prizmkit/plans/bug-fix-list.json` is missing, inform user:
|
|
@@ -67,6 +71,8 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
67
71
|
|
|
68
72
|
#### Intent A: Start Bugfix Pipeline
|
|
69
73
|
|
|
74
|
+
> **Execution model**: The pipeline processes bugs **sequentially** (one at a time, in severity/priority order). The `dependencies` field in bug-fix-list.json is reserved for future parallel execution support and does NOT affect current execution order.
|
|
75
|
+
|
|
70
76
|
1. **Check prerequisites**:
|
|
71
77
|
```bash
|
|
72
78
|
ls .prizmkit/plans/bug-fix-list.json 2>/dev/null && echo "Found" || echo "Missing"
|
|
@@ -126,13 +132,27 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
126
132
|
- 1
|
|
127
133
|
- 5
|
|
128
134
|
|
|
129
|
-
**Question 3 —
|
|
135
|
+
**Question 3 — Critic review** (multiSelect: false):
|
|
136
|
+
- Off (default) — Skip adversarial review
|
|
137
|
+
- On — Enable adversarial critic review: an independent AI agent reviews the diagnosis/plan for completeness and the fix for defects, edge cases, and regression risks. Adds ~5-10 min per bug.
|
|
138
|
+
|
|
139
|
+
**Question 4 — Advanced config?** (multiSelect: false):
|
|
140
|
+
- No (default) — Use defaults for session timeout and failure behavior
|
|
141
|
+
- Yes — Configure session timeout and stop-on-failure options
|
|
142
|
+
|
|
143
|
+
Note: Bug filter defaults to all bugs (by severity order). Default Critic to Off unless bugs have `severity: "critical"` or `severity: "high"` (in which case default to On). If the user selects "Other" on any option, handle their custom input.
|
|
144
|
+
|
|
145
|
+
**If user chose "Yes" to Advanced config**, ask a second round of `AskUserQuestion`:
|
|
146
|
+
|
|
147
|
+
**Question 1 — Session timeout** (multiSelect: false):
|
|
130
148
|
- None (default) — No timeout
|
|
131
149
|
- 30 min — `SESSION_TIMEOUT=1800`
|
|
132
150
|
- 1 hour — `SESSION_TIMEOUT=3600`
|
|
133
151
|
- 2 hours — `SESSION_TIMEOUT=7200`
|
|
134
152
|
|
|
135
|
-
|
|
153
|
+
**Question 2 — Stop on failure** (multiSelect: false):
|
|
154
|
+
- Off (default) — Pipeline continues to next task after failure
|
|
155
|
+
- On — Pipeline halts immediately when a task exhausts all retries (`STOP_ON_FAILURE=1`)
|
|
136
156
|
|
|
137
157
|
**Environment variable mapping** (for translating user responses → env vars):
|
|
138
158
|
|
|
@@ -141,8 +161,9 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
141
161
|
| Verbose: Off | `VERBOSE=0` |
|
|
142
162
|
| Verbose: On | `VERBOSE=1` |
|
|
143
163
|
| Max retries: N | `MAX_RETRIES=N` |
|
|
164
|
+
| Critic: On | `ENABLE_CRITIC=true` |
|
|
144
165
|
| Timeout: value | `SESSION_TIMEOUT=<seconds>` |
|
|
145
|
-
|
|
|
166
|
+
| Stop on failure: On | `STOP_ON_FAILURE=1` |
|
|
146
167
|
|
|
147
168
|
**Advanced environment variables** (not exposed in interactive menu, pass via `--env`):
|
|
148
169
|
|
|
@@ -156,7 +177,6 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
156
177
|
| `LOG_CLEANUP_ENABLED` | `1` | Run periodic log cleanup (`0` to disable) |
|
|
157
178
|
| `LOG_RETENTION_DAYS` | `14` | Delete logs older than N days |
|
|
158
179
|
| `LOG_MAX_TOTAL_MB` | `1024` | Keep total logs under N MB via oldest-first cleanup |
|
|
159
|
-
| `STOP_ON_FAILURE` | `0` | Stop pipeline when a task exhausts all retries (`1` to stop immediately) |
|
|
160
180
|
|
|
161
181
|
⚠️ STOP HERE and wait for user response before continuing to step 6.
|
|
162
182
|
|
|
@@ -312,6 +332,8 @@ dev-pipeline/reset-bug.sh B-001 --clean --run .prizmkit/plans/bug-fix-list.json
|
|
|
312
332
|
| PID file stale (process dead) | `launch-bugfix-daemon.sh` auto-cleans, retry start |
|
|
313
333
|
| Launch failed (process died immediately) | Show last 20 lines of log: `tail -20 .prizmkit/state/bugfix/pipeline-daemon.log` |
|
|
314
334
|
| All bugs blocked/failed/needs-info | Show status, suggest retrying or providing more info |
|
|
335
|
+
| `playwright-cli` not installed | Browser verification skipped for playwright bugs (non-blocking). Suggest: `npm install -g @playwright/cli@latest && playwright-cli install --skills` |
|
|
336
|
+
| `opencli` not installed | Browser verification skipped for opencli bugs (non-blocking). Install opencli for Chrome session-based browser verification |
|
|
315
337
|
| Permission denied on script | Run `chmod +x dev-pipeline/launch-bugfix-daemon.sh dev-pipeline/run-bugfix.sh` |
|
|
316
338
|
|
|
317
339
|
### Integration Notes
|
|
@@ -52,13 +52,14 @@ Before any action, validate:
|
|
|
52
52
|
2. **For start**: `.prizmkit/plans/feature-list.json` must exist in `.prizmkit/plans/` (or user-specified path)
|
|
53
53
|
3. **Dependencies**: `jq`, `python3`, AI CLI (`cbc` or `claude`) must be in PATH
|
|
54
54
|
4. **Python version**: Requires Python 3.8+ for dev-pipeline scripts
|
|
55
|
-
5. **
|
|
55
|
+
5. **Browser tools** (optional): If any feature has `browser_interaction` field, check the corresponding tool is available. Features may specify `tool: "playwright-cli"`, `tool: "opencli"`, or `tool: "auto"` (AI chooses at runtime).
|
|
56
56
|
|
|
57
57
|
Quick check:
|
|
58
58
|
```bash
|
|
59
59
|
command -v jq && command -v python3 && (command -v cbc || command -v claude) && echo "All dependencies OK"
|
|
60
|
-
# Optional: browser interaction support
|
|
61
|
-
command -v playwright-cli && echo "playwright-cli OK" || echo "playwright-cli not found (browser verification will be skipped)"
|
|
60
|
+
# Optional: browser interaction support (check both tools — features may use either)
|
|
61
|
+
command -v playwright-cli && echo "playwright-cli OK" || echo "playwright-cli not found (playwright browser verification will be skipped)"
|
|
62
|
+
command -v opencli && echo "opencli OK" || echo "opencli not found (opencli browser verification will be skipped)"
|
|
62
63
|
```
|
|
63
64
|
|
|
64
65
|
If `.prizmkit/plans/feature-list.json` is missing, inform user:
|
|
@@ -72,6 +73,8 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
72
73
|
|
|
73
74
|
#### Intent A: Start Pipeline
|
|
74
75
|
|
|
76
|
+
> **Execution model**: The pipeline processes features **sequentially** (one at a time, in order). The `dependencies` field in feature-list.json is reserved for future parallel execution support and does NOT affect current execution order.
|
|
77
|
+
|
|
75
78
|
1. **Check prerequisites**:
|
|
76
79
|
```bash
|
|
77
80
|
ls .prizmkit/plans/feature-list.json 2>/dev/null && echo "Found" || echo "Missing"
|
|
@@ -139,7 +142,7 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
139
142
|
|
|
140
143
|
**Question 1 — Critic review** (multiSelect: false):
|
|
141
144
|
- Off (default) — Skip adversarial review
|
|
142
|
-
- On — Enable critic review
|
|
145
|
+
- On — Enable adversarial critic review: an independent AI agent reviews the spec/plan for completeness and the implementation for defects, edge cases, and missed requirements. Adds ~5-10 min per feature.
|
|
143
146
|
|
|
144
147
|
**Question 2 — Verbose logging** (multiSelect: false):
|
|
145
148
|
- On (default) — Detailed AI session logs including tool calls and subagent activity
|
|
@@ -150,15 +153,25 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
150
153
|
- 1
|
|
151
154
|
- 5
|
|
152
155
|
|
|
153
|
-
**Question 4 —
|
|
156
|
+
**Question 4 — Advanced config?** (multiSelect: false):
|
|
157
|
+
- No (default) — Use defaults for session timeout and failure behavior
|
|
158
|
+
- Yes — Configure session timeout and stop-on-failure options
|
|
159
|
+
|
|
160
|
+
Note: Due to the 4-question limit per `AskUserQuestion` call, Feature filter and Browser verify use their defaults (all features, auto-detect browser tools). If the user selects "Other" on any option, handle their custom input.
|
|
161
|
+
|
|
162
|
+
Default Critic to Off unless features have `estimated_complexity: "high"` or above (in which case default to On).
|
|
163
|
+
|
|
164
|
+
**If user chose "Yes" to Advanced config**, ask a second round of `AskUserQuestion`:
|
|
165
|
+
|
|
166
|
+
**Question 1 — Session timeout** (multiSelect: false):
|
|
154
167
|
- None (default) — No timeout
|
|
155
168
|
- 30 min — `SESSION_TIMEOUT=1800`
|
|
156
169
|
- 1 hour — `SESSION_TIMEOUT=3600`
|
|
157
170
|
- 2 hours — `SESSION_TIMEOUT=7200`
|
|
158
171
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
172
|
+
**Question 2 — Stop on failure** (multiSelect: false):
|
|
173
|
+
- Off (default) — Pipeline continues to next task after failure
|
|
174
|
+
- On — Pipeline halts immediately when a task exhausts all retries (`STOP_ON_FAILURE=1`)
|
|
162
175
|
|
|
163
176
|
**Environment variable mapping** (for translating user responses → env vars):
|
|
164
177
|
|
|
@@ -169,6 +182,7 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
169
182
|
| Verbose: On | `VERBOSE=1` |
|
|
170
183
|
| Max retries: N | `MAX_RETRIES=N` |
|
|
171
184
|
| Timeout: value | `SESSION_TIMEOUT=<seconds>` |
|
|
185
|
+
| Stop on failure: On | `STOP_ON_FAILURE=1` |
|
|
172
186
|
|
|
173
187
|
**Advanced environment variables** (not exposed in interactive menu, pass via `--env`):
|
|
174
188
|
|
|
@@ -183,7 +197,6 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
183
197
|
| `LOG_CLEANUP_ENABLED` | `1` | Run periodic log cleanup (`0` to disable) |
|
|
184
198
|
| `LOG_RETENTION_DAYS` | `14` | Delete logs older than N days |
|
|
185
199
|
| `LOG_MAX_TOTAL_MB` | `1024` | Keep total logs under N MB via oldest-first cleanup |
|
|
186
|
-
| `STOP_ON_FAILURE` | `0` | Stop pipeline when a task exhausts all retries (`1` to stop immediately) |
|
|
187
200
|
|
|
188
201
|
⚠️ STOP HERE and wait for user response before continuing to step 7.
|
|
189
202
|
|
|
@@ -233,7 +246,7 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
233
246
|
- Summarize results: total features, succeeded, failed, skipped
|
|
234
247
|
- If all succeeded: each feature session has already run `prizmkit-retrospective` internally. Ask user what's next.
|
|
235
248
|
- If some failed: show failed feature IDs and suggest `reset-feature.sh <F-XXX> --clean --run` for a fresh retry
|
|
236
|
-
- **Browser verification**: If any completed features have `browser_interaction` and `playwright-cli` is installed, offer to run browser verification (see
|
|
249
|
+
- **Browser verification**: If any completed features have `browser_interaction` and the corresponding browser tool (`playwright-cli` or `opencli`) is installed, offer to run browser verification (see Post-Pipeline Browser Verification)
|
|
237
250
|
|
|
238
251
|
**If background daemon**:
|
|
239
252
|
1. Verify launch:
|
|
@@ -335,7 +348,7 @@ Notes:
|
|
|
335
348
|
|
|
336
349
|
#### Post-Pipeline Browser Verification
|
|
337
350
|
|
|
338
|
-
After pipeline completion, if features have `browser_interaction` fields and `playwright-cli` is installed:
|
|
351
|
+
After pipeline completion, if features have `browser_interaction` fields and the corresponding browser tool (`playwright-cli` or `opencli`) is installed:
|
|
339
352
|
|
|
340
353
|
1. **Check which features qualify**:
|
|
341
354
|
```bash
|
|
@@ -346,21 +359,25 @@ After pipeline completion, if features have `browser_interaction` fields and `pl
|
|
|
346
359
|
for feat in data.get('features', []):
|
|
347
360
|
bi = feat.get('browser_interaction')
|
|
348
361
|
if bi and feat.get('status') == 'completed':
|
|
349
|
-
|
|
362
|
+
tool = bi.get('tool', 'auto') if isinstance(bi, dict) else 'auto'
|
|
363
|
+
print(f\" {feat['id']}: {feat.get('title','')} (tool: {tool})\")
|
|
350
364
|
" 2>/dev/null
|
|
351
365
|
```
|
|
352
366
|
|
|
353
|
-
2. **Ask user**: "N features have browser verification configured. Run
|
|
367
|
+
2. **Ask user**: "N features have browser verification configured. Run browser verification now? (Y/n)"
|
|
354
368
|
|
|
355
369
|
3. **If yes**, for each qualifying feature:
|
|
356
370
|
- Start dev server if `setup_command` is specified
|
|
357
|
-
-
|
|
371
|
+
- Select browser tool based on `browser_interaction.tool`:
|
|
372
|
+
- `"playwright-cli"` → Use `playwright-cli snapshot` to discover element refs, then verify each goal in `verify_steps`
|
|
373
|
+
- `"opencli"` → Use `opencli browser` to interact with Chrome's logged-in session (ideal for OAuth/third-party verification)
|
|
374
|
+
- `"auto"` → AI chooses the appropriate tool based on context (default: `playwright-cli` for local dev, `opencli` for authenticated flows)
|
|
375
|
+
- Take a screenshot after verification
|
|
358
376
|
- Close browser and stop dev server
|
|
359
377
|
|
|
360
378
|
4. **Report results**:
|
|
361
|
-
- For each feature: URL opened, steps executed, screenshot path
|
|
379
|
+
- For each feature: URL opened, tool used, steps executed, screenshot path
|
|
362
380
|
- If any step fails: flag as verification failure
|
|
363
|
-
- Screenshots are saved to `.playwright-cli/` for user review
|
|
364
381
|
|
|
365
382
|
**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.
|
|
366
383
|
|
|
@@ -378,7 +395,8 @@ After pipeline completion, if features have `browser_interaction` fields and `pl
|
|
|
378
395
|
| Launch failed (process died immediately) | Show last 20 lines of log: `tail -20 .prizmkit/state/features/pipeline-daemon.log` |
|
|
379
396
|
| Feature stuck/blocked | Use `reset-feature.sh <F-XXX> --clean --run` for a fresh retry |
|
|
380
397
|
| All features blocked/failed | Show status, suggest daemon-safe recovery: `dev-pipeline/reset-feature.sh <F-XXX> --clean --run .prizmkit/plans/feature-list.json` |
|
|
381
|
-
| `playwright-cli` not installed | Browser verification skipped (non-blocking). Suggest: `npm install -g @playwright/cli@latest && playwright-cli install --skills` |
|
|
398
|
+
| `playwright-cli` not installed | Browser verification skipped for playwright features (non-blocking). Suggest: `npm install -g @playwright/cli@latest && playwright-cli install --skills` |
|
|
399
|
+
| `opencli` not installed | Browser verification skipped for opencli features (non-blocking). Install opencli for Chrome session-based browser verification |
|
|
382
400
|
| Permission denied on script | Run `chmod +x dev-pipeline/launch-feature-daemon.sh dev-pipeline/run-feature.sh` |
|
|
383
401
|
| Pipeline stop failed (process won't die) | Process may be stuck in I/O wait. Try `kill -9 <PID>` manually. Check for orphaned child processes with `ps aux \| grep claude` |
|
|
384
402
|
| `.env.local` missing or incomplete | Warn: database connection variables not found. Suggest creating env file with required connection variables for the project's database |
|
|
@@ -65,9 +65,13 @@ recovery-workflow
|
|
|
65
65
|
│ ├── Based on artifact presence → infer current phase
|
|
66
66
|
│ └── No match → reject and guide user
|
|
67
67
|
│
|
|
68
|
-
├── Phase 1:
|
|
69
|
-
│ ├──
|
|
68
|
+
├── Phase 1: Diagnose + report + user choice
|
|
69
|
+
│ ├── Check branch and working tree state
|
|
70
|
+
│ ├── Scan all pipelines for failed/in-progress tasks
|
|
71
|
+
│ ├── Find residual dev branches from failed tasks
|
|
72
|
+
│ ├── Display diagnosis + detection results
|
|
70
73
|
│ ├── If code changes exist → run test suite
|
|
74
|
+
│ ├── If multiple failed tasks → ask user which to recover
|
|
71
75
|
│ └── User chooses: run-recovery.sh (recommended) | interactive | start fresh
|
|
72
76
|
│
|
|
73
77
|
└── Phase 2: Execute remaining steps
|
|
@@ -119,9 +123,73 @@ To start a new workflow:
|
|
|
119
123
|
|
|
120
124
|
---
|
|
121
125
|
|
|
122
|
-
## Phase 1: Report + User Confirmation
|
|
123
|
-
|
|
124
|
-
**Goal**:
|
|
126
|
+
## Phase 1: Diagnose + Report + User Confirmation
|
|
127
|
+
|
|
128
|
+
**Goal**: Assess workspace health, identify failed tasks across all pipelines, and present recovery options.
|
|
129
|
+
|
|
130
|
+
### 1.0 Workspace & Failure Diagnosis
|
|
131
|
+
|
|
132
|
+
Before showing the recovery report, run a comprehensive diagnosis:
|
|
133
|
+
|
|
134
|
+
1. **Check current branch and working tree**:
|
|
135
|
+
```bash
|
|
136
|
+
git branch --show-current
|
|
137
|
+
git status --porcelain | head -10
|
|
138
|
+
```
|
|
139
|
+
Report: which branch is active, whether there are uncommitted changes.
|
|
140
|
+
|
|
141
|
+
2. **Scan all pipelines for failed/in-progress tasks**:
|
|
142
|
+
```bash
|
|
143
|
+
# Feature pipeline
|
|
144
|
+
python3 dev-pipeline/scripts/update-feature-status.py \
|
|
145
|
+
--feature-list .prizmkit/plans/feature-list.json \
|
|
146
|
+
--state-dir .prizmkit/state/features \
|
|
147
|
+
--action status 2>/dev/null
|
|
148
|
+
|
|
149
|
+
# Bugfix pipeline
|
|
150
|
+
python3 dev-pipeline/scripts/update-bug-status.py \
|
|
151
|
+
--bug-list .prizmkit/plans/bug-fix-list.json \
|
|
152
|
+
--state-dir .prizmkit/state/bugfix \
|
|
153
|
+
--action status 2>/dev/null
|
|
154
|
+
|
|
155
|
+
# Refactor pipeline
|
|
156
|
+
python3 dev-pipeline/scripts/update-refactor-status.py \
|
|
157
|
+
--refactor-list .prizmkit/plans/refactor-list.json \
|
|
158
|
+
--state-dir .prizmkit/state/refactor \
|
|
159
|
+
--action status 2>/dev/null
|
|
160
|
+
```
|
|
161
|
+
For each pipeline that has state, extract: total tasks, completed, failed, in-progress, pending.
|
|
162
|
+
|
|
163
|
+
3. **Find residual dev branches** from failed/interrupted tasks:
|
|
164
|
+
```bash
|
|
165
|
+
git branch --list 'dev/*' 'feat/*' 'fix/*' 'bugfix/*' 'refactor/*'
|
|
166
|
+
```
|
|
167
|
+
Cross-reference with failed task IDs to identify which branches belong to which failed tasks.
|
|
168
|
+
|
|
169
|
+
4. **Present diagnosis summary** — show all findings before the recovery report:
|
|
170
|
+
```
|
|
171
|
+
═══════════════════════════════════════════════════
|
|
172
|
+
Workspace Diagnosis
|
|
173
|
+
═══════════════════════════════════════════════════
|
|
174
|
+
|
|
175
|
+
Branch: fix/B-001-login-crash
|
|
176
|
+
Working tree: 3 uncommitted changes
|
|
177
|
+
|
|
178
|
+
Feature pipeline: 2 completed, 1 failed (F-003), 2 pending
|
|
179
|
+
Bugfix pipeline: 1 completed, 1 failed (B-002), 0 pending
|
|
180
|
+
Refactor pipeline: (no state found)
|
|
181
|
+
|
|
182
|
+
Residual branches:
|
|
183
|
+
dev/F-003-payment-integration-202604201030
|
|
184
|
+
fix/B-002-encoding-bug
|
|
185
|
+
|
|
186
|
+
Failed tasks:
|
|
187
|
+
F-003: Payment integration [FAILED] → branch: dev/F-003-...
|
|
188
|
+
B-002: CSV encoding bug [FAILED] → branch: fix/B-002-...
|
|
189
|
+
═══════════════════════════════════════════════════
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
If no pipelines have state and no failed tasks are found, skip to 1.1 (standard recovery report).
|
|
125
193
|
|
|
126
194
|
### 1.1 Display Detection Report
|
|
127
195
|
|
|
@@ -160,7 +228,28 @@ Include test results in the report:
|
|
|
160
228
|
- How many tests pass/fail
|
|
161
229
|
- If failures exist — which tests and why
|
|
162
230
|
|
|
163
|
-
### 1.3
|
|
231
|
+
### 1.3 Select Recovery Target (if multiple failed tasks)
|
|
232
|
+
|
|
233
|
+
If the diagnosis in 1.0 found **multiple failed/interrupted tasks** across pipelines, ask the user which one to recover first before proceeding:
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
AskUserQuestion:
|
|
237
|
+
question: "Multiple failed/interrupted tasks found. Which would you like to recover?"
|
|
238
|
+
header: "Target"
|
|
239
|
+
options:
|
|
240
|
+
- label: "F-003: Payment integration"
|
|
241
|
+
description: "Feature pipeline — FAILED — branch: dev/F-003-payment-integration-202604201030"
|
|
242
|
+
- label: "B-002: CSV encoding bug"
|
|
243
|
+
description: "Bugfix pipeline — FAILED — branch: fix/B-002-encoding-bug"
|
|
244
|
+
- label: "Recover all sequentially"
|
|
245
|
+
description: "Recover each failed task one by one in priority order"
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Generate the options dynamically from the diagnosis results. Include task ID, title, pipeline type, status, and branch name.
|
|
249
|
+
|
|
250
|
+
If only one failed/interrupted task is found, skip this step — proceed directly to 1.4 with that task as the recovery target.
|
|
251
|
+
|
|
252
|
+
### 1.4 Ask User to Choose Recovery Approach
|
|
164
253
|
|
|
165
254
|
**User choice required (mandatory)** — Use `AskUserQuestion` to present interactive selectable options. **NEVER skip this step. NEVER choose for the user.**
|
|
166
255
|
|
|
@@ -208,7 +297,7 @@ End this skill.
|
|
|
208
297
|
|
|
209
298
|
**NEVER proceed to Phase 2 without explicit user selection via `AskUserQuestion`. Do NOT render options as plain text — the user must be able to click/select.**
|
|
210
299
|
|
|
211
|
-
**CHECKPOINT CP-REC-1**: User chose recovery approach.
|
|
300
|
+
**CHECKPOINT CP-REC-1**: User chose recovery target and approach.
|
|
212
301
|
|
|
213
302
|
---
|
|
214
303
|
|
|
@@ -49,10 +49,14 @@ Before any action, validate:
|
|
|
49
49
|
2. **For start**: `.prizmkit/plans/refactor-list.json` must exist in `.prizmkit/plans/` (or user-specified path)
|
|
50
50
|
3. **Dependencies**: `jq`, `python3`, AI CLI (`cbc` or `claude`) must be in PATH
|
|
51
51
|
4. **Python version**: Requires Python 3.8+ for dev-pipeline scripts
|
|
52
|
+
5. **Browser tools** (optional): If any refactor has `browser_interaction` field, check the corresponding tool is available. Refactors may specify `tool: "playwright-cli"`, `tool: "opencli"`, or `tool: "auto"` (AI chooses at runtime).
|
|
52
53
|
|
|
53
54
|
Quick check:
|
|
54
55
|
```bash
|
|
55
56
|
command -v jq && command -v python3 && (command -v cbc || command -v claude) && echo "All dependencies OK"
|
|
57
|
+
# Optional: browser interaction support (check both tools — refactors may use either)
|
|
58
|
+
command -v playwright-cli && echo "playwright-cli OK" || echo "playwright-cli not found (playwright browser verification will be skipped)"
|
|
59
|
+
command -v opencli && echo "opencli OK" || echo "opencli not found (opencli browser verification will be skipped)"
|
|
56
60
|
```
|
|
57
61
|
|
|
58
62
|
If `.prizmkit/plans/refactor-list.json` is missing, inform user:
|
|
@@ -66,6 +70,8 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
66
70
|
|
|
67
71
|
#### Intent A: Start Pipeline
|
|
68
72
|
|
|
73
|
+
> **Execution model**: The pipeline processes refactor tasks **sequentially** (one at a time, in priority order). The `dependencies` field in refactor-list.json is reserved for future parallel execution support and does NOT affect current execution order.
|
|
74
|
+
|
|
69
75
|
1. **Check prerequisites**:
|
|
70
76
|
```bash
|
|
71
77
|
ls .prizmkit/plans/refactor-list.json 2>/dev/null && echo "Found" || echo "Missing"
|
|
@@ -144,17 +150,33 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
144
150
|
- 1
|
|
145
151
|
- 5
|
|
146
152
|
|
|
147
|
-
**Question 3 —
|
|
153
|
+
**Question 3 — Strict behavior check** (multiSelect: false):
|
|
154
|
+
- On (default) — Run full test suite after each refactor task to verify behavior preservation
|
|
155
|
+
- Off — Skip post-task test verification (faster but riskier)
|
|
156
|
+
|
|
157
|
+
**Question 4 — Advanced config?** (multiSelect: false):
|
|
158
|
+
- No (default) — Use defaults for critic review, session timeout, and failure behavior
|
|
159
|
+
- Yes — Configure critic review, session timeout, and stop-on-failure options
|
|
160
|
+
|
|
161
|
+
Note: Refactor filter defaults to all refactor items (by priority order). If the user selects "Other" on any option, handle their custom input.
|
|
162
|
+
|
|
163
|
+
**If user chose "Yes" to Advanced config**, ask a second round of `AskUserQuestion`:
|
|
164
|
+
|
|
165
|
+
**Question 1 — Session timeout** (multiSelect: false):
|
|
148
166
|
- None (default) — No timeout
|
|
149
167
|
- 30 min — `SESSION_TIMEOUT=1800`
|
|
150
168
|
- 1 hour — `SESSION_TIMEOUT=3600`
|
|
151
169
|
- 2 hours — `SESSION_TIMEOUT=7200`
|
|
152
170
|
|
|
153
|
-
**Question
|
|
154
|
-
-
|
|
155
|
-
-
|
|
171
|
+
**Question 2 — Stop on failure** (multiSelect: false):
|
|
172
|
+
- Off (default) — Pipeline continues to next task after failure
|
|
173
|
+
- On — Pipeline halts immediately when a task exhausts all retries (`STOP_ON_FAILURE=1`)
|
|
156
174
|
|
|
157
|
-
|
|
175
|
+
**Question 3 — Critic review** (multiSelect: false):
|
|
176
|
+
- Off (default) — Skip adversarial review
|
|
177
|
+
- On — Enable adversarial critic review: an independent AI agent reviews the refactor plan for completeness and the implementation for regressions, missed edge cases, and behavior violations. Adds ~5-10 min per refactor task.
|
|
178
|
+
|
|
179
|
+
Default Critic to Off unless refactor items have `priority: "critical"` (in which case default to On).
|
|
158
180
|
|
|
159
181
|
**Environment variable mapping** (for translating user responses → env vars):
|
|
160
182
|
|
|
@@ -163,9 +185,11 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
163
185
|
| Verbose: On | `VERBOSE=1` |
|
|
164
186
|
| Verbose: Off | `VERBOSE=0` |
|
|
165
187
|
| Max retries: N | `MAX_RETRIES=N` |
|
|
166
|
-
| Timeout: value | `SESSION_TIMEOUT=<seconds>` |
|
|
167
188
|
| Strict behavior: On | `STRICT_BEHAVIOR_CHECK=1` |
|
|
168
189
|
| Strict behavior: Off | `STRICT_BEHAVIOR_CHECK=0` |
|
|
190
|
+
| Critic: On | `ENABLE_CRITIC=true` |
|
|
191
|
+
| Timeout: value | `SESSION_TIMEOUT=<seconds>` |
|
|
192
|
+
| Stop on failure: On | `STOP_ON_FAILURE=1` |
|
|
169
193
|
|
|
170
194
|
**Advanced environment variables** (not exposed in interactive menu, pass via `--env`):
|
|
171
195
|
|
|
@@ -179,7 +203,6 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
179
203
|
| `LOG_CLEANUP_ENABLED` | `1` | Run periodic log cleanup (`0` to disable) |
|
|
180
204
|
| `LOG_RETENTION_DAYS` | `14` | Delete logs older than N days |
|
|
181
205
|
| `LOG_MAX_TOTAL_MB` | `1024` | Keep total logs under N MB via oldest-first cleanup |
|
|
182
|
-
| `STOP_ON_FAILURE` | `0` | Stop pipeline when a task exhausts all retries (`1` to stop immediately) |
|
|
183
206
|
|
|
184
207
|
⚠️ STOP HERE and wait for user response before continuing to step 7.
|
|
185
208
|
|
|
@@ -342,6 +365,8 @@ Notes:
|
|
|
342
365
|
| Launch failed (process died immediately) | Show last 20 lines of log: `tail -20 .prizmkit/state/refactor/pipeline-daemon.log` |
|
|
343
366
|
| Refactor stuck/blocked | Use `reset-refactor.sh <R-XXX> --clean --run` for a fresh retry |
|
|
344
367
|
| All refactors blocked/failed | Show status, suggest recovery: `dev-pipeline/reset-refactor.sh <R-XXX> --clean --run .prizmkit/plans/refactor-list.json` |
|
|
368
|
+
| `playwright-cli` not installed | Browser verification skipped for playwright refactors (non-blocking). Suggest: `npm install -g @playwright/cli@latest && playwright-cli install --skills` |
|
|
369
|
+
| `opencli` not installed | Browser verification skipped for opencli refactors (non-blocking). Install opencli for Chrome session-based browser verification |
|
|
345
370
|
| Permission denied on script | Run `chmod +x dev-pipeline/launch-refactor-daemon.sh dev-pipeline/run-refactor.sh` |
|
|
346
371
|
|
|
347
372
|
### Integration Notes
|