|
40 | 40 | review_memory, |
41 | 41 | write_memory_config, |
42 | 42 | ) |
| 43 | +from .doctor import format_doctor_text, run_doctor |
| 44 | +from .pilot import SUPPORTED_TOOLS as PILOT_SUPPORTED_TOOLS, format_pilot_text, run_pilot |
43 | 45 | from .pr_template import write_pr_template |
44 | 46 | from .session import ( |
45 | 47 | SessionStatusResult, |
|
82 | 84 | KNOWLEDGE_BACKENDS_WITH_NONE = ["none", *KNOWLEDGE_BACKENDS] |
83 | 85 |
|
84 | 86 |
|
| 87 | +TOP_LEVEL_DESCRIPTION = """\ |
| 88 | +Local-first scaffold for AI-assisted coding teams. Generates reviewable |
| 89 | +project-local guidance for hardware, providers, model selection, tool adapters, |
| 90 | +skills, knowledge, policy, and sessions. |
| 91 | +
|
| 92 | +START HERE |
| 93 | + coding-scaffold doctor see what's set up + what's next |
| 94 | + coding-scaffold pilot --target . --tool opencode print the 10-minute happy path |
| 95 | + coding-scaffold setup run --mode beginner guided full setup |
| 96 | +
|
| 97 | +10-MINUTE PILOT (printed by `pilot` above; or run by hand) |
| 98 | + coding-scaffold setup run --target . --tool opencode --mode beginner |
| 99 | + coding-scaffold pr-template init --target . |
| 100 | + opencode # inside the agent: /first-session, then /agentic-change |
| 101 | +
|
| 102 | +DAILY WORKFLOW |
| 103 | + coding-scaffold session init --task "..." reversible session trace |
| 104 | + coding-scaffold context lint --target . check agent-context files |
| 105 | + coding-scaffold eval run --target . readiness benchmark |
| 106 | +
|
| 107 | +ADVANCED / GOVERNANCE (safe to ignore until your team needs them) |
| 108 | + policy, mcp, skills, memory, team, permissions, tools, knowledge distill |
| 109 | +
|
| 110 | +The full command list is below. Every command supports --help. |
| 111 | +""" |
| 112 | + |
| 113 | + |
85 | 114 | def build_parser() -> argparse.ArgumentParser: |
86 | 115 | parser = argparse.ArgumentParser( |
87 | 116 | prog="coding-scaffold", |
88 | | - description="Prepare a local-first AI coding scaffold for a project.", |
| 117 | + description=TOP_LEVEL_DESCRIPTION, |
| 118 | + formatter_class=argparse.RawDescriptionHelpFormatter, |
89 | 119 | ) |
90 | 120 | sub = parser.add_subparsers(dest="command", required=True, metavar="command") |
91 | 121 |
|
@@ -634,7 +664,25 @@ def build_parser() -> argparse.ArgumentParser: |
634 | 664 | update.add_argument("--target", type=Path, default=Path.cwd(), help="Project directory.") |
635 | 665 | update.add_argument("--json", action="store_true", help="Print machine-readable JSON.") |
636 | 666 |
|
637 | | - sub.add_parser("doctor", help="Print setup recommendations.") |
| 667 | + doctor = sub.add_parser( |
| 668 | + "doctor", |
| 669 | + help="Survey scaffold artifacts and recommend the next 1-3 commands.", |
| 670 | + ) |
| 671 | + doctor.add_argument("--target", type=Path, default=Path.cwd(), help="Project directory.") |
| 672 | + doctor.add_argument("--json", action="store_true", help="Print machine-readable JSON.") |
| 673 | + |
| 674 | + pilot = sub.add_parser( |
| 675 | + "pilot", |
| 676 | + help="Print the safe 10-minute happy path tailored to this project.", |
| 677 | + ) |
| 678 | + pilot.add_argument("--target", type=Path, default=Path.cwd(), help="Project directory.") |
| 679 | + pilot.add_argument( |
| 680 | + "--tool", |
| 681 | + choices=list(PILOT_SUPPORTED_TOOLS), |
| 682 | + default="opencode", |
| 683 | + help="Coding tool to weave into the recipe (default: opencode).", |
| 684 | + ) |
| 685 | + pilot.add_argument("--json", action="store_true", help="Print machine-readable JSON.") |
638 | 686 | _hide_suppressed_subcommands(sub) |
639 | 687 | return parser |
640 | 688 |
|
@@ -880,7 +928,26 @@ def main(argv: list[str] | None = None) -> int: |
880 | 928 | return 0 |
881 | 929 |
|
882 | 930 | if args.command == "doctor": |
883 | | - _print_doctor() |
| 931 | + target = getattr(args, "target", None) or Path.cwd() |
| 932 | + report = run_doctor(target) |
| 933 | + if getattr(args, "json", False): |
| 934 | + print(json.dumps(report.to_dict(), indent=2, sort_keys=True)) |
| 935 | + else: |
| 936 | + print(format_doctor_text(report)) |
| 937 | + # Keep the original system snapshot at the end for continuity. |
| 938 | + _print_doctor() |
| 939 | + return 0 |
| 940 | + |
| 941 | + if args.command == "pilot": |
| 942 | + try: |
| 943 | + report = run_pilot(args.target, tool=args.tool) |
| 944 | + except ValueError as exc: |
| 945 | + print(f"Error: {exc}", file=sys.stderr) |
| 946 | + return 1 |
| 947 | + if args.json: |
| 948 | + print(json.dumps(report.to_dict(), indent=2, sort_keys=True)) |
| 949 | + else: |
| 950 | + print(format_pilot_text(report)) |
884 | 951 | return 0 |
885 | 952 |
|
886 | 953 | if args.command == "credentials": |
|
0 commit comments