|
22 | 22 | import yaml |
23 | 23 | import requests |
24 | 24 | import time |
| 25 | +import subprocess |
25 | 26 | from pathlib import Path |
26 | 27 | from typing import Dict, Any, Optional |
27 | 28 | from difflib import unified_diff |
@@ -508,15 +509,87 @@ async def step_7_generate_validation(self): |
508 | 509 | validation_file = f"{snapshot_dir}/verify.js" |
509 | 510 |
|
510 | 511 | print("Options:") |
511 | | - print("1. Wait for Claude Code to create verify.js (recommended)") |
512 | | - print("2. Enter validation JavaScript manually") |
| 512 | + print("1. Auto-run Claude Code subprocess (recommended)") |
| 513 | + print("2. Wait for Claude Code manually (you run it)") |
| 514 | + print("3. Enter validation JavaScript manually") |
513 | 515 | print() |
514 | 516 |
|
515 | | - choice = input("Choice (1/2): ").strip() |
| 517 | + choice = input("Choice (1/2/3): ").strip() |
516 | 518 |
|
517 | 519 | lines = [] |
518 | 520 |
|
519 | 521 | if choice == '1': |
| 522 | + # Automatically spawn Claude Code subprocess |
| 523 | + print(f"\n🤖 Launching Claude Code subprocess...") |
| 524 | + print() |
| 525 | + |
| 526 | + # Construct the prompt for Claude Code |
| 527 | + claude_prompt = f"Read @{marker_file} and complete the task described there. Generate the validation JavaScript and save it to {validation_file}. Test it on both tabs as instructed." |
| 528 | + |
| 529 | + try: |
| 530 | + # Call Claude Code CLI with --dangerously-skip-permissions for auto-accept |
| 531 | + result = subprocess.run( |
| 532 | + ['claude', '--dangerously-skip-permissions', claude_prompt], |
| 533 | + cwd=os.getcwd(), |
| 534 | + capture_output=True, |
| 535 | + text=True, |
| 536 | + timeout=300 # 5 minute timeout |
| 537 | + ) |
| 538 | + |
| 539 | + print("Claude Code output:") |
| 540 | + print("─" * 60) |
| 541 | + print(result.stdout) |
| 542 | + if result.stderr: |
| 543 | + print("Errors:") |
| 544 | + print(result.stderr) |
| 545 | + print("─" * 60) |
| 546 | + print() |
| 547 | + |
| 548 | + # Check if verify.js was created |
| 549 | + if os.path.exists(validation_file): |
| 550 | + print("✅ Validation file detected!") |
| 551 | + with open(validation_file, 'r') as f: |
| 552 | + js_code = f.read().strip() |
| 553 | + |
| 554 | + # Clean up if it has markdown code blocks |
| 555 | + if js_code.startswith('```'): |
| 556 | + lines_raw = js_code.split('\n') |
| 557 | + if lines_raw[0].startswith('```'): |
| 558 | + lines_raw = lines_raw[1:] |
| 559 | + if lines_raw[-1].startswith('```'): |
| 560 | + lines_raw = lines_raw[:-1] |
| 561 | + js_code = '\n'.join(lines_raw).strip() |
| 562 | + |
| 563 | + print() |
| 564 | + print("📝 Loaded validation code:") |
| 565 | + print("─" * 60) |
| 566 | + print(js_code[:300] + "..." if len(js_code) > 300 else js_code) |
| 567 | + print("─" * 60) |
| 568 | + |
| 569 | + lines = js_code.split('\n') |
| 570 | + else: |
| 571 | + print(f"⚠️ Claude Code ran but {validation_file} was not created") |
| 572 | + print("Falling back to manual entry...") |
| 573 | + choice = '3' |
| 574 | + lines = [] |
| 575 | + |
| 576 | + except subprocess.TimeoutExpired: |
| 577 | + print("⏱️ Claude Code subprocess timed out (5 minutes)") |
| 578 | + print("Falling back to manual entry...") |
| 579 | + choice = '3' |
| 580 | + lines = [] |
| 581 | + except FileNotFoundError: |
| 582 | + print("❌ 'claude' command not found. Is Claude Code installed?") |
| 583 | + print("Falling back to manual entry...") |
| 584 | + choice = '3' |
| 585 | + lines = [] |
| 586 | + except Exception as e: |
| 587 | + print(f"❌ Error running Claude Code: {e}") |
| 588 | + print("Falling back to manual entry...") |
| 589 | + choice = '3' |
| 590 | + lines = [] |
| 591 | + |
| 592 | + elif choice == '2': |
520 | 593 | print(f"\n⏳ Waiting for {validation_file} to be created...") |
521 | 594 | print(" (Claude Code will create this file)") |
522 | 595 | print() |
@@ -557,9 +630,9 @@ async def step_7_generate_validation(self): |
557 | 630 | if not lines: |
558 | 631 | print("⏱️ Timeout waiting for validation file") |
559 | 632 | print(" Falling back to manual entry...") |
560 | | - choice = '2' |
| 633 | + choice = '3' |
561 | 634 |
|
562 | | - if choice == '2': |
| 635 | + if choice == '3': |
563 | 636 | print("\nEnter validation JavaScript (type 'END' on new line when done):\n") |
564 | 637 | while True: |
565 | 638 | line = input() |
|
0 commit comments