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>
This commit is contained in:
AirCoding
2026-06-12 17:12:29 +08:00
parent 8f55c962bb
commit ae44be31d5
364 changed files with 46779 additions and 2812 deletions

View File

@@ -0,0 +1,318 @@
#!/usr/bin/env python3
"""Bootstrap AirSDB static-analysis context and cppcheck tooling."""
from __future__ import annotations
import argparse
import json
import os
import platform
import shutil
import subprocess
from datetime import datetime, timezone
from pathlib import Path
from typing import Dict, Optional, Tuple
MARKER_BEGIN = "<!-- AIRSDB:BEGIN -->"
MARKER_END = "<!-- AIRSDB:END -->"
def now_iso() -> str:
return datetime.now(timezone.utc).isoformat()
def stamp() -> str:
return datetime.now().strftime("%Y%m%d-%H%M%S")
def read_env(path: Path) -> Dict[str, str]:
vals: Dict[str, str] = {}
if path.exists():
for raw in path.read_text(encoding="utf-8-sig").splitlines():
line = raw.strip()
if line and not line.startswith("#") and "=" in line:
key, value = line.split("=", 1)
vals[key.strip()] = value.strip().strip('"').strip("'")
for key in ["AIRSDB_CPPCHECK", "AIRSDB_CPPCHECK_OPTIONS"]:
if os.environ.get(key):
vals[key] = os.environ[key]
return vals
def write_env(path: Path, updates: Dict[str, str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
old = path.read_text(encoding="utf-8") if path.exists() else ""
keys = set(updates)
lines = []
for raw in old.splitlines():
key = raw.split("=", 1)[0].strip() if "=" in raw and not raw.strip().startswith("#") else None
if key not in keys:
lines.append(raw)
if lines and lines[-1].strip():
lines.append("")
for key, value in updates.items():
if value:
lines.append(f"{key}={value}")
path.write_text("\n".join(lines).rstrip() + "\n", encoding="utf-8", newline="\n")
def ensure_files(project: Path) -> None:
air = project / "AirPlan" / "state" / "airsdb"
air.mkdir(parents=True, exist_ok=True)
example = air / "tool.env.example"
if not example.exists():
example.write_text(
"# AirSDB local cppcheck configuration\n"
"AIRSDB_CPPCHECK=cppcheck\n"
"AIRSDB_CPPCHECK_OPTIONS=\n"
"# AirSDB defaults to --check-level=exhaustive for maximum branch analysis detail.\n",
encoding="utf-8",
newline="\n",
)
gitignore = air / ".gitignore"
old = gitignore.read_text(encoding="utf-8") if gitignore.exists() else ""
for item in ["tool.env", "remote-device.env", "reports/", "cppcheck-build/"]:
if item not in old.splitlines():
old = (old.rstrip() + f"\n{item}\n").lstrip()
gitignore.write_text(old, encoding="utf-8", newline="\n")
static = project / "AirPlan" / "docs" / "staticanalysis.md"
if not static.exists():
static.write_text(
"# Static Analysis\n\n"
"Short AI-context reports for AirSDB cppcheck runs. Keep entries concise.\n\n"
"## Entry Template\n\n"
"### YYYY-MM-DD HH:MM:SS: AirSDB cppcheck\n\n"
"- Target: TODO\n"
"- Tool: TODO\n"
"- Command: TODO\n"
"- Result: TODO\n"
"- Counts: TODO\n"
"- Reports: TODO\n"
"- Top findings: TODO\n"
"- AirDbg/AirDo handoff: TODO\n"
"- Residual risk: TODO\n",
encoding="utf-8",
newline="\n",
)
def airsdb_agents_block() -> str:
return f"""{MARKER_BEGIN}
## AirSDB Static Analysis Workflow
1. Use AirSDB for `/airsdb` sessions that run cppcheck static analysis for C/C++ code quality, security-relevant defects, and debugging evidence.
2. On first entry, detect cppcheck; if missing, auto-configure it with the best available package manager or stop with install instructions.
3. Maintain `AirPlan/docs/staticanalysis.md` as the short AI-context report for AirDbg and AirDo. Keep detailed XML/JSON artifacts under `AirPlan/state/airsdb/reports/`.
4. Prefer `compile_commands.json` when available; otherwise scan the narrowest useful source tree with common generated/vendor directories excluded.
5. Default local and remote cppcheck scans to `--check-level=exhaustive` so AirSDB provides the most detailed branch-analysis evidence it can.
6. For local analysis, use `airsdb_cppcheck.py`; for remote targets over SSH, use `airsdb_remote_device.py` before local analysis.
7. When remote cppcheck is missing, the remote helper may auto-configure it with non-interactive package-manager commands; if sudo/password or unsupported OS blocks it, stop and record the blocker.
8. Record command, target, report paths, counts, top findings, AirDbg/AirDo handoff, and residual risk in `AirPlan/docs/staticanalysis.md`.
9. Update ADR/C4 only when static analysis tooling becomes a durable project boundary or changes implementation decisions.
{MARKER_END}
"""
def upsert_agents_md(path: Path) -> str:
block = airsdb_agents_block().rstrip() + "\n"
if path.exists():
original = path.read_text(encoding="utf-8")
existed = True
else:
original = "# AGENTS.md\n\n"
existed = False
begin = original.find(MARKER_BEGIN)
end = original.find(MARKER_END)
if begin >= 0 and end > begin:
end += len(MARKER_END)
updated = original[:begin].rstrip() + "\n\n" + block + original[end:].lstrip()
status = "updated"
else:
updated = original.rstrip() + "\n\n" + block
status = "updated" if existed else "created"
path.write_text(updated, encoding="utf-8", newline="\n")
return status
def run_args(args: list[str], timeout: int = 600) -> subprocess.CompletedProcess[str]:
return subprocess.run(args, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout)
def run_shell(cmd: str, timeout: int = 600) -> subprocess.CompletedProcess[str]:
return subprocess.run(cmd, shell=True, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout)
def cppcheck_version(tool: str) -> str:
try:
result = run_args([tool, "--version"], timeout=20)
except Exception:
return ""
text = (result.stdout or result.stderr).strip()
return text.splitlines()[0] if text else ""
def detect_cppcheck(project: Path) -> Tuple[Optional[str], str]:
env = read_env(project / "AirPlan" / "state" / "airsdb" / "tool.env")
candidates = []
configured = env.get("AIRSDB_CPPCHECK", "").strip()
if configured:
candidates.append(configured)
candidates.append("cppcheck")
if platform.system().lower() == "windows":
candidates.extend(
[
r"C:\Program Files\Cppcheck\cppcheck.exe",
r"C:\Program Files (x86)\Cppcheck\cppcheck.exe",
]
)
for candidate in candidates:
path = shutil.which(candidate) or candidate
if Path(path).exists() or shutil.which(path):
version = cppcheck_version(path)
if version:
return path, version
return None, ""
def install_cppcheck(project: Path) -> Dict[str, str]:
system = platform.system().lower()
attempts = []
if system == "windows":
package_commands = [
["winget", "install", "--id", "Cppcheck.Cppcheck", "-e", "--accept-source-agreements", "--accept-package-agreements", "--silent"],
["choco", "install", "cppcheck", "-y"],
["scoop", "install", "cppcheck"],
]
for cmd in package_commands:
exe = shutil.which(cmd[0])
if not exe:
continue
run = run_args([exe] + cmd[1:], timeout=1200)
attempts.append({"command": " ".join(cmd), "returncode": str(run.returncode)})
tool, version = detect_cppcheck(project)
if tool:
write_env(project / "AirPlan" / "state" / "airsdb" / "tool.env", {"AIRSDB_CPPCHECK": tool})
return {"status": "ok", "tool": tool, "version": version, "installer": cmd[0], "attempts": json.dumps(attempts)}
return {
"status": "blocked",
"reason": "cppcheck_not_found",
"hint": "Install Cppcheck from https://cppcheck.sourceforge.io/ or configure AIRSDB_CPPCHECK.",
"attempts": json.dumps(attempts),
}
commands = [
"if command -v apt-get >/dev/null 2>&1; then sudo -n apt-get update && sudo -n apt-get install -y cppcheck; "
"elif command -v dnf >/dev/null 2>&1; then sudo -n dnf install -y cppcheck; "
"elif command -v yum >/dev/null 2>&1; then sudo -n yum install -y cppcheck; "
"elif command -v apk >/dev/null 2>&1; then sudo -n apk add cppcheck; "
"elif command -v pacman >/dev/null 2>&1; then sudo -n pacman -Sy --noconfirm cppcheck; "
"elif command -v brew >/dev/null 2>&1; then brew install cppcheck; "
"elif command -v port >/dev/null 2>&1; then sudo -n port install cppcheck; "
"else exit 42; fi"
]
run = run_shell(commands[0], timeout=1200)
attempts.append({"command": "system-package-manager", "returncode": str(run.returncode)})
tool, version = detect_cppcheck(project)
if tool:
write_env(project / "AirPlan" / "state" / "airsdb" / "tool.env", {"AIRSDB_CPPCHECK": tool})
return {"status": "ok", "tool": tool, "version": version, "installer": "system-package-manager", "attempts": json.dumps(attempts)}
return {
"status": "blocked",
"reason": "cppcheck_not_found",
"hint": "Install cppcheck with the OS package manager or configure AIRSDB_CPPCHECK.",
"attempts": json.dumps(attempts),
}
def setup_cppcheck(project: Path, auto: bool = True) -> Dict[str, str]:
ensure_files(project)
tool, version = detect_cppcheck(project)
if tool:
write_env(project / "AirPlan" / "state" / "airsdb" / "tool.env", {"AIRSDB_CPPCHECK": tool})
return {"status": "ok", "tool": tool, "version": version, "autoConfigure": "skipped"}
if not auto:
return {"status": "blocked", "reason": "cppcheck_not_found", "example": str(project / "AirPlan" / "state" / "airsdb" / "tool.env.example")}
return install_cppcheck(project)
def artifact_map(project: Path) -> Dict[str, Path]:
return {
"AGENTS.md": project / "AirPlan" / "AGENTS.md",
"staticanalysis": project / "AirPlan" / "docs" / "staticanalysis.md",
"state": project / "AirPlan" / "state" / "airsdb" / "state.json",
"tool_env": project / "AirPlan" / "state" / "airsdb" / "tool.env",
}
def write_state(path: Path, enabled: bool, project: Path, tool_info: Dict[str, str]) -> None:
artifacts = artifact_map(project)
payload = {
"enabled": enabled,
"updatedAt": now_iso(),
"projectRoot": str(project),
"cppcheck": tool_info,
"artifactHealth": {name: p.exists() for name, p in artifacts.items() if name != "state"},
}
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8", newline="\n")
def enter_mode(project: Path, auto: bool = True) -> Tuple[str, Dict[str, str]]:
ensure_files(project)
results = {"AGENTS.md": upsert_agents_md(project / "AirPlan" / "AGENTS.md"), "staticanalysis": "exists"}
tool_info = setup_cppcheck(project, auto=auto)
for key, value in tool_info.items():
results[f"cppcheck_{key}"] = value
write_state(project / "AirPlan" / "state" / "airsdb" / "state.json", True, project, tool_info)
return "enabled", results
def exit_mode(project: Path) -> Tuple[str, Dict[str, str]]:
ensure_files(project)
tool_info = setup_cppcheck(project, auto=False)
write_state(project / "AirPlan" / "state" / "airsdb" / "state.json", False, project, tool_info)
return "disabled", {}
def status_mode(project: Path) -> Tuple[str, Dict[str, str]]:
ensure_files(project)
state = project / "AirPlan" / "state" / "airsdb" / "state.json"
enabled = False
if state.exists():
try:
enabled = bool(json.loads(state.read_text(encoding="utf-8")).get("enabled"))
except json.JSONDecodeError:
enabled = False
tool_info = setup_cppcheck(project, auto=False)
results = {name: ("ok" if path.exists() else "missing") for name, path in artifact_map(project).items() if name != "state"}
for key, value in tool_info.items():
results[f"cppcheck_{key}"] = value
return ("enabled" if enabled else "disabled"), results
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Manage AirSDB static-analysis artifacts.")
parser.add_argument("--mode", choices=["enter", "setup", "exit", "status"], default="enter")
parser.add_argument("--project", default=".")
parser.add_argument("--no-auto-configure", action="store_true")
return parser.parse_args()
def main() -> None:
args = parse_args()
project = Path(args.project).expanduser().resolve()
if args.mode in ["enter", "setup"]:
mode_state, result = enter_mode(project, auto=not args.no_auto_configure)
elif args.mode == "exit":
mode_state, result = exit_mode(project)
else:
mode_state, result = status_mode(project)
print(f"airsdb_mode={mode_state}")
print(f"project_root={project}")
for key, value in result.items():
print(f"{key}={value}")
if __name__ == "__main__":
main()