(argv: list[str] | None = None)
| 382 | |
| 383 | |
| 384 | def main(argv: list[str] | None = None) -> int: |
| 385 | parser = build_parser() |
| 386 | args = parser.parse_args(argv) |
| 387 | |
| 388 | # Install the JSON-lines file logger before anything that might fail. |
| 389 | # Every main() invocation is a fresh short-lived process (hook, scheduler, |
| 390 | # or a user-typed command), so reconfiguring on entry is cheap and keeps |
| 391 | # test isolation tight — configure() also acts as a reset. |
| 392 | configure_logging() |
| 393 | logger = get_logger() |
| 394 | |
| 395 | # Hydrate ~/.codex-self-evolution/.env.provider into os.environ so that |
| 396 | # subprocesses (pi/opencode for compile, urllib for the HTTP reviewer) |
| 397 | # can find their API keys even when we're launched by launchd with a |
| 398 | # minimal PATH+HOME-only environment. |
| 399 | hydrated = hydrate_env_for_subprocesses() |
| 400 | if hydrated: |
| 401 | # Values are NEVER logged; only the key names that just entered scope. |
| 402 | logger.info("env provider hydrated", extra={"kind": "env_hydrate", "keys": sorted(hydrated)}) |
| 403 | |
| 404 | started = time.monotonic() |
| 405 | |
| 406 | try: |
| 407 | if args.command == "session-start": |
| 408 | if args.from_stdin: |
| 409 | exit_code = _handle_session_start_from_stdin(args) |
| 410 | _log_command(logger, args.command, started, exit_code=exit_code) |
| 411 | return exit_code |
| 412 | if not args.cwd: |
| 413 | parser.error("session-start requires --cwd or --from-stdin") |
| 414 | result = session_start(cwd=args.cwd, state_dir=args.state_dir) |
| 415 | elif args.command == "stop-review": |
| 416 | if args.from_stdin: |
| 417 | exit_code = _handle_stop_from_stdin(args) |
| 418 | _log_command(logger, args.command, started, exit_code=exit_code, mode="from_stdin") |
| 419 | return exit_code |
| 420 | if not args.hook_payload: |
| 421 | parser.error("stop-review requires --hook-payload or --from-stdin") |
| 422 | result = _run_stop_review(args) |
| 423 | elif args.command == "compile": |
| 424 | allow_fallback, compile_options = _compile_runtime_options() |
| 425 | result = run_compile( |
| 426 | repo_root=args.repo_root, |
| 427 | state_dir=args.state_dir, |
| 428 | backend=args.backend, |
| 429 | allow_fallback=allow_fallback, |
| 430 | compile_options=compile_options, |
| 431 | ) |
| 432 | elif args.command == "compile-preflight": |
| 433 | result = preflight_compile(repo_root=args.repo_root, state_dir=args.state_dir) |
| 434 | elif args.command == "scan": |
| 435 | allow_fallback, compile_options = _compile_runtime_options(args.home) |
| 436 | result = scan_all_projects( |
| 437 | home=args.home, |
| 438 | backend=args.backend, |
| 439 | allow_fallback=allow_fallback, |
| 440 | compile_options=compile_options, |
| 441 | max_runs_per_project=args.max_runs_per_project, |
no test coverage detected