Files
AirCoding ae44be31d5 chore: push all design docs, V2 plan specs, and current working state
Includes AirPlan design documents, AircOding-alpha1-plan, AirPlanV2,
AirPlan-ParaV2, AirPlan-Para V1 reference docs, and all working code
changes across packages.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 17:12:29 +08:00

194 lines
6.9 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
AirPlan V2 — 统一 CLI 入口。
V1 的 8 个独立插件合并为一个命令,通过 --mode 参数路由到对应子模式。
用法:
airplan --mode arc --project <project-root> [--todo <todo-md>]
airplan --mode eng --project <project-root> [--sub enter|status|plan|dispatch|monitor|merge|run|intervene]
airplan --mode do --project <project-root> --task-id <id>
airplan --mode dbg --project <project-root> [--task-id <id>]
airplan --mode sdb --project <project-root> [--backend cppcheck|clang-tidy|clippy|go-vet|tsc] [--target <path>]
airplan --mode ctx --project <project-root> [--sub now|status|pause|init]
airplan --mode dep --project <project-root> --task-id <id> --host <host> [--binary <path>]
airplan --mode tst --project <project-root> --task-id <id> [--framework <name>]
airplan --mode sec --project <project-root> --task-id <id> [--scan-path <path>]
airplan --mode rvr --project <project-root> --task-id <id>
"""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
def _add_lib_path() -> None:
root = Path(__file__).resolve().parents[1]
lib_path = root / "lib"
if str(lib_path) not in sys.path:
sys.path.insert(0, str(lib_path))
_add_lib_path()
from air_runtime.project_bootstrap import ensure_project_bootstrap
def _run_arc(args) -> None:
from air_runtime.modes.arc_mode import main as arc_main
arc_main(args)
def _run_eng(args) -> None:
from air_runtime.modes.eng_mode import main as eng_main
eng_main(args)
def _run_do(args) -> None:
from air_runtime.modes.do_mode import main as do_main
do_main(args)
def _run_dbg(args) -> None:
from air_runtime.modes.dbg_mode import main as dbg_main
dbg_main(args)
def _run_xdb(args) -> None:
from air_runtime.modes.xdb_mode import main as xdb_main
xdb_main(args)
def _run_sdb(args) -> None:
from air_runtime.modes.sdb_mode import main as sdb_main
sdb_main(args)
def _run_ndb(args) -> None:
from air_runtime.modes.ndb_mode import main as ndb_main
ndb_main(args)
def _run_ctx(args) -> None:
from air_runtime.modes.ctx_mode import main as ctx_main
ctx_main(args)
def _run_dep(args) -> None:
from air_runtime.modes.dep_mode import main as dep_main
dep_main(args)
def _run_tst(args) -> None:
from air_runtime.modes.tst_mode import main as tst_main
tst_main(args)
def _run_sec(args) -> None:
from air_runtime.modes.sec_mode import main as sec_main
sec_main(args)
def _run_rvr(args) -> None:
from air_runtime.modes.rvr_mode import main as rvr_main
rvr_main(args)
def _run_eng_orchestrator(args) -> None:
from air_runtime.modes.eng_orchestrator import main as eng_orch_main
eng_orch_main(args)
MODE_ROUTER = {
"arc": _run_arc,
"eng": _run_eng,
"do": _run_do,
"dbg": _run_dbg,
"xdb": _run_xdb,
"sdb": _run_sdb,
"ndb": _run_ndb,
"ctx": _run_ctx,
"dep": _run_dep,
"tst": _run_tst,
"sec": _run_sec,
"rvr": _run_rvr,
"eng_orchestrator": _run_eng_orchestrator,
}
MODE_HELP = {
"arc": "架构规划器 — 分析依赖、写集冲突、产出执行计划",
"eng": "调度引擎 — 波次派发、监控、合并、修复编排",
"do": "任务执行器 — 单任务切片执行与结果生成",
"dbg": "调试器 — 7步调试工作流、根因分析、修复回滚",
"xdb": "GUI验证器 — 截图取证、GUI操作验证",
"sdb": "静态分析器 — 多语言静态分析、diff模式",
"ndb": "网络调试器 — 抓包分析、TLS解密",
"ctx": "上下文管理器 — 压缩、Token估算、锁检测",
"dep": "部署器 — SSH远程构建、部署、systemd管理",
"tst": "测试运行器 — 统一测试执行与结果报告",
"sec": "安全扫描器 — 敏感数据检测与脱敏",
"rvr": "需求审查器 — 交付物与需求一致性验证",
}
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="AirPlan V2 — 统一制品驱动开发调度器",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="\n".join(f" {k:6s} {v}" for k, v in MODE_HELP.items()),
)
parser.add_argument("--mode", choices=list(MODE_ROUTER.keys()), required=True,
help="子模式选择")
parser.add_argument("--project", default=".",
help="项目根目录 (默认: .)")
parser.add_argument("--sub", default="",
help="子模式内的二级操作(如 eng 的 enter|status|plan 等)")
parser.add_argument("--todo", default="",
help="todo.md 路径arc/eng 使用)")
parser.add_argument("--task-id", default="",
help="任务 IDdo/dbg/xdb/sdb/ndb/dep/tst/sec/rvr 使用)")
parser.add_argument("--result", default="",
help="Worker result.json 路径eng merge 使用)")
parser.add_argument("--dispatch-group", default="",
help="派发组名eng dispatch 使用)")
parser.add_argument("--host", default="",
help="远程主机dep 使用)")
parser.add_argument("--binary", default="",
help="本地二进制路径dep 使用)")
parser.add_argument("--framework", default="",
help="测试框架tst 使用)")
parser.add_argument("--scan-path", default="",
help="扫描路径sec 使用)")
parser.add_argument("--sec-mode", default="blocking", choices=["advisory", "blocking"],
help="安全扫描模式sec 使用): advisory只报告/ blocking阻止合并")
parser.add_argument("--backend", default="",
help="静态分析后端sdb 使用): cppcheck|clang-tidy|clippy|go-vet|tsc")
parser.add_argument("--target", default="",
help="分析目标路径sdb 使用)")
parser.add_argument("--prefer", default="auto",
help="截图后端偏好xdb 使用): kms|xvfb|fallback|auto")
parser.add_argument("--output", default="",
help="截图输出文件名xdb 使用,默认 screenshot.png")
parser.add_argument("--task-text", default="",
help="任务描述文本do 使用,用于 UI 任务检测和路由)")
return parser.parse_args(argv)
def main(argv: list[str] | None = None) -> None:
args = parse_args(argv)
project_root = Path(args.project).expanduser().resolve()
ensure_project_bootstrap(project_root)
handler = MODE_ROUTER.get(args.mode)
if handler is None:
print(f"Unknown mode: {args.mode}", file=sys.stderr)
print(f"Available modes: {', '.join(MODE_ROUTER.keys())}", file=sys.stderr)
sys.exit(1)
handler(args)
if __name__ == "__main__":
main()