71 lines
2.4 KiB
Python
71 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
import argparse
|
|
import shlex
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
|
|
def run(cmd, cwd=None):
|
|
p = subprocess.run(cmd, cwd=cwd, text=True, capture_output=True)
|
|
if p.stdout:
|
|
print(p.stdout.strip())
|
|
if p.returncode != 0:
|
|
if p.stderr:
|
|
print(p.stderr.strip())
|
|
raise SystemExit(p.returncode)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Execute a gate prompt with selected coding agent")
|
|
parser.add_argument("--root", default=".", help="Project root")
|
|
parser.add_argument("--agent", required=True, choices=["codex", "claude", "opencode", "pi"])
|
|
parser.add_argument("--prompt-file", required=True, help="Prompt file path")
|
|
parser.add_argument("--spec-ref", default="", help="Spec reference for dispatch safety checks")
|
|
parser.add_argument(
|
|
"--enforce-spec-ref",
|
|
action="store_true",
|
|
help="Fail dispatch if --spec-ref is missing (use for implementation gates)",
|
|
)
|
|
parser.add_argument("--full-auto", action="store_true", help="Use full-auto mode where supported")
|
|
parser.add_argument("--dry-run", action="store_true", help="Print command without executing")
|
|
args = parser.parse_args()
|
|
|
|
root = Path(args.root).resolve()
|
|
prompt = Path(args.prompt_file).resolve()
|
|
if not prompt.exists():
|
|
raise SystemExit(f"Prompt file not found: {prompt}")
|
|
|
|
if args.enforce_spec_ref and not args.spec_ref.strip():
|
|
raise SystemExit("Dispatch blocked: --spec-ref is required for this run.")
|
|
|
|
text = prompt.read_text(encoding="utf-8")
|
|
|
|
# Additional dispatch-time guard: do not launch if prompt itself indicates missing spec.
|
|
if args.enforce_spec_ref and "Spec Reference: (not provided for this gate)" in text:
|
|
raise SystemExit("Dispatch blocked: prompt indicates missing spec reference.")
|
|
|
|
if args.agent == "codex":
|
|
cmd = ["codex", "exec"]
|
|
if args.full_auto:
|
|
cmd.append("--full-auto")
|
|
cmd.append(text)
|
|
elif args.agent == "claude":
|
|
# Claude CLI generally accepts task text directly
|
|
cmd = ["claude", text]
|
|
elif args.agent == "opencode":
|
|
cmd = ["opencode", "run", text]
|
|
else: # pi
|
|
cmd = ["pi", "-p", text]
|
|
|
|
print("Agent command:")
|
|
print(" ".join(shlex.quote(c) for c in cmd))
|
|
|
|
if args.dry_run:
|
|
return
|
|
|
|
run(cmd, cwd=str(root))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|