// Command harness is the MOPAC harness CLI. v0 surface: `harness once`. package main import ( "context" "errors" "flag" "fmt" "os" "os/signal" "syscall" "git.knownelement.com/reachableceo/MOPAC/harness/internal/config" "git.knownelement.com/reachableceo/MOPAC/harness/internal/loop" ) const usage = `MOPAC harness (v0) Usage: harness once [-config PATH] [-dry-run] [-demo] [-task-id ID] once runs ONE conductor iteration and exits (chain by re-invoking; no daemon): intake (Redmine scope, or the [demo] issue) -> plan/model routing -> bounded turn via LiteLLM -> REPORT file writeback. Flags: -config PATH config file (default $HARNESS_CONFIG or ./harness.toml) -dry-run intake + plan only; no LLM call, no REPORT -demo run the [demo] issue instead of Redmine intake -task-id ID run only the task/issue with this id Exit codes: 0 ok (including "no tasks in scope") 1 usage / config / routing / writeback error 2 intake error 4 llm / turn error ` func main() { os.Exit(run(os.Args[1:])) } func run(args []string) int { if len(args) == 0 { fmt.Fprint(os.Stderr, usage) return 1 } switch args[0] { case "help", "-h", "--help": fmt.Print(usage) return 0 case "once": return runOnce(args[1:]) default: fmt.Fprintf(os.Stderr, "harness: unknown command %q\n\n%s", args[0], usage) return 1 } } func runOnce(args []string) int { fs := flag.NewFlagSet("once", flag.ContinueOnError) cfgPath := fs.String("config", "", "config file path") dryRun := fs.Bool("dry-run", false, "intake + plan only, no LLM call") demo := fs.Bool("demo", false, "use the [demo] issue instead of Redmine") taskID := fs.String("task-id", "", "run only this task id") if err := fs.Parse(args); err != nil { return 1 } if fs.NArg() > 0 { fmt.Fprintf(os.Stderr, "harness: unexpected argument %q\n", fs.Arg(0)) return 1 } if *cfgPath == "" { *cfgPath = os.Getenv("HARNESS_CONFIG") } if *cfgPath == "" { *cfgPath = "harness.toml" } cfg, err := config.Load(*cfgPath) if err != nil { fmt.Fprintf(os.Stderr, "harness: %v\n", err) return 1 } conductor, err := loop.New(cfg, os.Stdout) if err != nil { fmt.Fprintf(os.Stderr, "harness: %v\n", err) return 1 } ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() _, err = conductor.Once(ctx, loop.OnceOpts{ DryRun: *dryRun, Demo: *demo, TaskID: *taskID, }) if err != nil { fmt.Fprintf(os.Stderr, "harness: %v\n", err) switch { case errors.Is(err, loop.ErrIntake): return 2 case errors.Is(err, loop.ErrLLM): return 4 default: return 1 } } return 0 }