codexapi 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codexapi
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Minimal Python API for running the Codex CLI.
5
5
  License: MIT
6
6
  Keywords: codex,agent,cli,openai
@@ -61,12 +61,16 @@ print(result.success, result.summary)
61
61
  After installing, use the `codexapi` command:
62
62
 
63
63
  ```bash
64
- codexapi "Summarize this repo."
65
- codexapi --cwd /path/to/project "Fix the failing tests."
66
- echo "Say hello." | codexapi
64
+ codexapi run "Summarize this repo."
65
+ codexapi run --cwd /path/to/project "Fix the failing tests."
66
+ echo "Say hello." | codexapi run
67
67
  ```
68
68
 
69
- Task mode exits with code 0 on success and 1 on failure, printing the summary.
69
+ `codexapi task` exits with code 0 on success and 1 on failure, printing the summary.
70
+
71
+ ```bash
72
+ codexapi task "Fix the failing tests." --max-iterations 5
73
+ ```
70
74
 
71
75
  Show running sessions and their latest activity:
72
76
 
@@ -78,17 +82,17 @@ Press `h` for keys.
78
82
  Resume a session and print the thread id to stderr:
79
83
 
80
84
  ```bash
81
- codexapi --thread-id THREAD_ID --print-thread-id "Continue where we left off."
85
+ codexapi run --thread-id THREAD_ID --print-thread-id "Continue where we left off."
82
86
  ```
83
87
 
84
88
  Ralph loop mode repeats the same prompt until a completion promise or a max
85
89
  iteration cap is hit (0 means unlimited). Cancel by deleting
86
- `.codexapi/ralph-loop.local.md` or running `codexapi --ralph-cancel`.
90
+ `.codexapi/ralph-loop.local.md` or running `codexapi ralph --cancel`.
87
91
 
88
92
  ```bash
89
- codexapi --ralph "Fix the bug." --completion-promise DONE --max-iterations 5
90
- codexapi --ralph --ralph-fresh "Try again from scratch." --max-iterations 3
91
- codexapi --ralph-cancel --cwd /path/to/project
93
+ codexapi ralph "Fix the bug." --completion-promise DONE --max-iterations 5
94
+ codexapi ralph --ralph-fresh "Try again from scratch." --max-iterations 3
95
+ codexapi ralph --cancel --cwd /path/to/project
92
96
  ```
93
97
 
94
98
  ## API
@@ -49,12 +49,16 @@ print(result.success, result.summary)
49
49
  After installing, use the `codexapi` command:
50
50
 
51
51
  ```bash
52
- codexapi "Summarize this repo."
53
- codexapi --cwd /path/to/project "Fix the failing tests."
54
- echo "Say hello." | codexapi
52
+ codexapi run "Summarize this repo."
53
+ codexapi run --cwd /path/to/project "Fix the failing tests."
54
+ echo "Say hello." | codexapi run
55
55
  ```
56
56
 
57
- Task mode exits with code 0 on success and 1 on failure, printing the summary.
57
+ `codexapi task` exits with code 0 on success and 1 on failure, printing the summary.
58
+
59
+ ```bash
60
+ codexapi task "Fix the failing tests." --max-iterations 5
61
+ ```
58
62
 
59
63
  Show running sessions and their latest activity:
60
64
 
@@ -66,17 +70,17 @@ Press `h` for keys.
66
70
  Resume a session and print the thread id to stderr:
67
71
 
68
72
  ```bash
69
- codexapi --thread-id THREAD_ID --print-thread-id "Continue where we left off."
73
+ codexapi run --thread-id THREAD_ID --print-thread-id "Continue where we left off."
70
74
  ```
71
75
 
72
76
  Ralph loop mode repeats the same prompt until a completion promise or a max
73
77
  iteration cap is hit (0 means unlimited). Cancel by deleting
74
- `.codexapi/ralph-loop.local.md` or running `codexapi --ralph-cancel`.
78
+ `.codexapi/ralph-loop.local.md` or running `codexapi ralph --cancel`.
75
79
 
76
80
  ```bash
77
- codexapi --ralph "Fix the bug." --completion-promise DONE --max-iterations 5
78
- codexapi --ralph --ralph-fresh "Try again from scratch." --max-iterations 3
79
- codexapi --ralph-cancel --cwd /path/to/project
81
+ codexapi ralph "Fix the bug." --completion-promise DONE --max-iterations 5
82
+ codexapi ralph --ralph-fresh "Try again from scratch." --max-iterations 3
83
+ codexapi ralph --cancel --cwd /path/to/project
80
84
  ```
81
85
 
82
86
  ## API
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "codexapi"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  description = "Minimal Python API for running the Codex CLI."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -12,4 +12,4 @@ __all__ = [
12
12
  "task",
13
13
  "task_result",
14
14
  ]
15
- __version__ = "0.2.0"
15
+ __version__ = "0.3.0"
@@ -870,146 +870,164 @@ def _run_top(argv):
870
870
 
871
871
  def main(argv=None):
872
872
  argv = sys.argv[1:] if argv is None else list(argv)
873
- if argv and argv[0] == "top":
874
- _run_top(argv[1:])
875
- return
876
873
  ralph_help = (
877
- "Ralph loop mode (--ralph):\n"
874
+ "Ralph loop mode (ralph command):\n"
878
875
  " Repeats the exact same prompt each iteration until a completion promise\n"
879
876
  " is detected or --max-iterations is reached (0 means unlimited).\n"
880
877
  " Completion promise: output <promise>TEXT</promise> where TEXT matches\n"
881
878
  " --completion-promise after trimming/collapsing whitespace. CRITICAL RULE:\n"
882
879
  " Only output the promise when it is completely and unequivocally TRUE.\n"
883
- " Cancel by deleting .codexapi/ralph-loop.local.md or running --ralph-cancel.\n"
880
+ " Cancel by deleting .codexapi/ralph-loop.local.md or running codexapi ralph --cancel.\n"
884
881
  " Default reuses a single Codex thread; use --ralph-fresh for a new Agent\n"
885
882
  " each iteration (no shared context).\n"
886
883
  )
887
884
  parser = argparse.ArgumentParser(
888
885
  prog="codexapi",
889
886
  description="Run Codex via the codexapi wrapper.",
890
- epilog=ralph_help,
891
- formatter_class=argparse.RawDescriptionHelpFormatter,
892
887
  )
893
- parser.add_argument(
888
+ subparsers = parser.add_subparsers(dest="command")
889
+
890
+ run_parser = subparsers.add_parser(
891
+ "run",
892
+ help="Run a Codex prompt.",
893
+ )
894
+ run_parser.add_argument(
894
895
  "prompt",
895
896
  nargs="?",
896
897
  help="Prompt to send. Use '-' or omit to read from stdin.",
897
898
  )
898
- parser.add_argument(
899
- "--task",
900
- action="store_true",
901
- help="Run in task mode with verification retries.",
902
- )
903
- parser.add_argument(
904
- "--check",
905
- help="Optional check prompt for --task. Defaults to the task prompt.",
906
- )
907
- parser.add_argument("--cwd", help="Working directory for the Codex session.")
908
- parser.add_argument("--yolo", action="store_true", help="Pass --yolo to Codex.")
909
- parser.add_argument(
899
+ run_parser.add_argument("--cwd", help="Working directory for the Codex session.")
900
+ run_parser.add_argument("--yolo", action="store_true", help="Pass --yolo to Codex.")
901
+ run_parser.add_argument(
910
902
  "--flags",
911
903
  help="Additional raw CLI flags to pass to Codex (quoted as needed).",
912
904
  )
913
- parser.add_argument(
905
+ run_parser.add_argument(
914
906
  "--thread-id",
915
907
  help="Resume an existing Codex thread id.",
916
908
  )
917
- parser.add_argument(
909
+ run_parser.add_argument(
918
910
  "--print-thread-id",
919
911
  action="store_true",
920
912
  help="Print the current thread id to stderr after running.",
921
913
  )
922
- parser.add_argument(
923
- "--ralph",
924
- action="store_true",
925
- help="Run a Ralph loop that repeats the same prompt each iteration.",
914
+
915
+ task_parser = subparsers.add_parser(
916
+ "task",
917
+ help="Run a task with verification retries.",
918
+ )
919
+ task_parser.add_argument(
920
+ "prompt",
921
+ nargs="?",
922
+ help="Prompt to send. Use '-' or omit to read from stdin.",
923
+ )
924
+ task_parser.add_argument(
925
+ "--check",
926
+ help="Optional check prompt. Defaults to the task prompt.",
927
+ )
928
+ task_parser.add_argument(
929
+ "--max-iterations",
930
+ type=int,
931
+ default=10,
932
+ help="Max verification retries after a failed check (0 means no retries).",
933
+ )
934
+ task_parser.add_argument("--cwd", help="Working directory for the Codex session.")
935
+ task_parser.add_argument("--yolo", action="store_true", help="Pass --yolo to Codex.")
936
+ task_parser.add_argument(
937
+ "--flags",
938
+ help="Additional raw CLI flags to pass to Codex (quoted as needed).",
939
+ )
940
+
941
+ ralph_parser = subparsers.add_parser(
942
+ "ralph",
943
+ help="Run a Ralph loop.",
944
+ epilog=ralph_help,
945
+ formatter_class=argparse.RawDescriptionHelpFormatter,
946
+ )
947
+ ralph_parser.add_argument(
948
+ "prompt",
949
+ nargs="?",
950
+ help="Prompt to send. Use '-' or omit to read from stdin.",
926
951
  )
927
- parser.add_argument(
952
+ ralph_parser.add_argument(
928
953
  "--max-iterations",
929
954
  type=int,
930
- default=None,
931
- help="Max iterations for --ralph (0 means unlimited).",
955
+ default=0,
956
+ help="Max iterations for the loop (0 means unlimited).",
957
+ )
958
+ ralph_parser.add_argument(
959
+ "--cancel",
960
+ action="store_true",
961
+ help="Cancel the Ralph loop state in the target cwd.",
932
962
  )
933
- parser.add_argument(
963
+ ralph_parser.add_argument(
934
964
  "--completion-promise",
935
- help="Promise text for --ralph to match in <promise>...</promise>.",
965
+ help="Promise text to match in <promise>...</promise>.",
936
966
  )
937
- parser.add_argument(
967
+ ralph_parser.add_argument(
938
968
  "--ralph-fresh",
939
969
  action="store_true",
940
- help="With --ralph, start each iteration with a fresh Agent context.",
970
+ help="Start each iteration with a fresh Agent context.",
941
971
  )
942
- parser.add_argument(
943
- "--ralph-cancel",
944
- action="store_true",
945
- help=(
946
- "Cancel a Ralph loop by removing .codexapi/ralph-loop.local.md "
947
- "(respects --cwd)."
948
- ),
972
+ ralph_parser.add_argument("--cwd", help="Working directory for the Codex session.")
973
+ ralph_parser.add_argument("--yolo", action="store_true", help="Pass --yolo to Codex.")
974
+ ralph_parser.add_argument(
975
+ "--flags",
976
+ help="Additional raw CLI flags to pass to Codex (quoted as needed).",
977
+ )
978
+
979
+ subparsers.add_parser(
980
+ "top",
981
+ help="Show running Codex sessions.",
949
982
  )
950
983
 
951
984
  args = parser.parse_args(argv)
952
- if args.ralph_cancel:
953
- if (
954
- args.ralph
955
- or args.task
956
- or args.thread_id
957
- or args.print_thread_id
958
- or args.max_iterations is not None
959
- or args.completion_promise is not None
960
- or args.ralph_fresh
961
- or args.check is not None
962
- or args.prompt
963
- ):
964
- raise SystemExit(
965
- "--ralph-cancel cannot be combined with prompts or other modes."
966
- )
967
- print(cancel_ralph_loop(args.cwd))
985
+ if args.command is None:
986
+ parser.print_help()
987
+ raise SystemExit(2)
988
+ if args.command == "top":
989
+ _run_top([])
968
990
  return
969
- if args.check is not None and not args.task:
970
- raise SystemExit("--check requires --task.")
971
- if not args.ralph and (
972
- args.max_iterations is not None
973
- or args.completion_promise is not None
974
- or args.ralph_fresh
975
- ):
976
- raise SystemExit(
977
- "--max-iterations/--completion-promise/--ralph-fresh require --ralph."
978
- )
979
- if args.ralph and (args.task or args.thread_id or args.print_thread_id):
980
- raise SystemExit(
981
- "--task/--thread-id/--print-thread-id are not supported with --ralph."
982
- )
983
- if args.task and (args.thread_id or args.print_thread_id):
984
- raise SystemExit("--thread-id/--print-thread-id are not supported with --task.")
985
991
 
986
- prompt = _read_prompt(args.prompt)
992
+ if args.command == "ralph":
993
+ if args.cancel:
994
+ if args.prompt:
995
+ raise SystemExit("ralph --cancel takes no prompt.")
996
+ if args.completion_promise or args.ralph_fresh:
997
+ raise SystemExit("--completion-promise/--ralph-fresh are not allowed with --cancel.")
998
+ if args.max_iterations != 0:
999
+ raise SystemExit("--max-iterations is not allowed with --cancel.")
1000
+ print(cancel_ralph_loop(args.cwd))
1001
+ return
987
1002
 
1003
+ prompt = _read_prompt(args.prompt)
988
1004
  exit_code = 0
989
1005
 
990
- if args.ralph:
991
- max_iterations = args.max_iterations if args.max_iterations is not None else 0
992
- if max_iterations < 0:
1006
+ if args.command == "ralph":
1007
+ if args.max_iterations < 0:
993
1008
  raise SystemExit("--max-iterations must be >= 0.")
994
1009
  run_ralph_loop(
995
1010
  prompt,
996
1011
  args.cwd,
997
1012
  args.yolo,
998
1013
  args.flags,
999
- max_iterations,
1014
+ args.max_iterations,
1000
1015
  args.completion_promise,
1001
1016
  args.ralph_fresh,
1002
1017
  )
1003
1018
  return
1004
- if args.task:
1019
+ if args.command == "task":
1020
+ if args.max_iterations < 0:
1021
+ raise SystemExit("--max-iterations must be >= 0.")
1005
1022
  check = args.check if args.check is not None else prompt
1006
1023
  try:
1007
1024
  message = task(
1008
1025
  prompt,
1009
1026
  check,
1010
- cwd=args.cwd,
1011
- yolo=args.yolo,
1012
- flags=args.flags,
1027
+ args.max_iterations,
1028
+ args.cwd,
1029
+ args.yolo,
1030
+ args.flags,
1013
1031
  )
1014
1032
  except TaskFailed as exc:
1015
1033
  message = exc.summary
@@ -39,7 +39,7 @@ def run_ralph_loop(
39
39
 
40
40
  By default a single Agent instance is reused for shared context. Set
41
41
  `fresh=True` to create a new Agent each iteration for a clean context.
42
- Cancel by deleting the state file or running `codexapi --ralph-cancel`.
42
+ Cancel by deleting the state file or running `codexapi ralph --cancel`.
43
43
  """
44
44
  if not isinstance(prompt, str) or not prompt.strip():
45
45
  raise ValueError("prompt must be a non-empty string")
@@ -81,7 +81,7 @@ def run_ralph_loop(
81
81
  "",
82
82
  "The loop will resend the SAME PROMPT each iteration.",
83
83
  "Cancel by deleting .codexapi/ralph-loop.local.md or running",
84
- "codexapi --ralph-cancel.",
84
+ "codexapi ralph --cancel.",
85
85
  "No manual stop beyond max iterations or completion promise.",
86
86
  "",
87
87
  "To monitor: head -10 .codexapi/ralph-loop.local.md",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codexapi
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Minimal Python API for running the Codex CLI.
5
5
  License: MIT
6
6
  Keywords: codex,agent,cli,openai
@@ -61,12 +61,16 @@ print(result.success, result.summary)
61
61
  After installing, use the `codexapi` command:
62
62
 
63
63
  ```bash
64
- codexapi "Summarize this repo."
65
- codexapi --cwd /path/to/project "Fix the failing tests."
66
- echo "Say hello." | codexapi
64
+ codexapi run "Summarize this repo."
65
+ codexapi run --cwd /path/to/project "Fix the failing tests."
66
+ echo "Say hello." | codexapi run
67
67
  ```
68
68
 
69
- Task mode exits with code 0 on success and 1 on failure, printing the summary.
69
+ `codexapi task` exits with code 0 on success and 1 on failure, printing the summary.
70
+
71
+ ```bash
72
+ codexapi task "Fix the failing tests." --max-iterations 5
73
+ ```
70
74
 
71
75
  Show running sessions and their latest activity:
72
76
 
@@ -78,17 +82,17 @@ Press `h` for keys.
78
82
  Resume a session and print the thread id to stderr:
79
83
 
80
84
  ```bash
81
- codexapi --thread-id THREAD_ID --print-thread-id "Continue where we left off."
85
+ codexapi run --thread-id THREAD_ID --print-thread-id "Continue where we left off."
82
86
  ```
83
87
 
84
88
  Ralph loop mode repeats the same prompt until a completion promise or a max
85
89
  iteration cap is hit (0 means unlimited). Cancel by deleting
86
- `.codexapi/ralph-loop.local.md` or running `codexapi --ralph-cancel`.
90
+ `.codexapi/ralph-loop.local.md` or running `codexapi ralph --cancel`.
87
91
 
88
92
  ```bash
89
- codexapi --ralph "Fix the bug." --completion-promise DONE --max-iterations 5
90
- codexapi --ralph --ralph-fresh "Try again from scratch." --max-iterations 3
91
- codexapi --ralph-cancel --cwd /path/to/project
93
+ codexapi ralph "Fix the bug." --completion-promise DONE --max-iterations 5
94
+ codexapi ralph --ralph-fresh "Try again from scratch." --max-iterations 3
95
+ codexapi ralph --cancel --cwd /path/to/project
92
96
  ```
93
97
 
94
98
  ## API
File without changes
File without changes
File without changes
File without changes