codexapi 0.1.9__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.1.9
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.1.9"
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.1.8"
15
+ __version__ = "0.3.0"
@@ -87,9 +87,12 @@ def _parse_timestamp(value):
87
87
  if value.endswith("Z"):
88
88
  value = value[:-1] + "+00:00"
89
89
  try:
90
- return datetime.fromisoformat(value)
90
+ parsed = datetime.fromisoformat(value)
91
91
  except ValueError:
92
92
  return None
93
+ if parsed.tzinfo is None:
94
+ return parsed
95
+ return parsed.astimezone().replace(tzinfo=None)
93
96
 
94
97
 
95
98
  def _tail_lines(path):
@@ -867,146 +870,164 @@ def _run_top(argv):
867
870
 
868
871
  def main(argv=None):
869
872
  argv = sys.argv[1:] if argv is None else list(argv)
870
- if argv and argv[0] == "top":
871
- _run_top(argv[1:])
872
- return
873
873
  ralph_help = (
874
- "Ralph loop mode (--ralph):\n"
874
+ "Ralph loop mode (ralph command):\n"
875
875
  " Repeats the exact same prompt each iteration until a completion promise\n"
876
876
  " is detected or --max-iterations is reached (0 means unlimited).\n"
877
877
  " Completion promise: output <promise>TEXT</promise> where TEXT matches\n"
878
878
  " --completion-promise after trimming/collapsing whitespace. CRITICAL RULE:\n"
879
879
  " Only output the promise when it is completely and unequivocally TRUE.\n"
880
- " 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"
881
881
  " Default reuses a single Codex thread; use --ralph-fresh for a new Agent\n"
882
882
  " each iteration (no shared context).\n"
883
883
  )
884
884
  parser = argparse.ArgumentParser(
885
885
  prog="codexapi",
886
886
  description="Run Codex via the codexapi wrapper.",
887
- epilog=ralph_help,
888
- formatter_class=argparse.RawDescriptionHelpFormatter,
889
887
  )
890
- 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(
891
895
  "prompt",
892
896
  nargs="?",
893
897
  help="Prompt to send. Use '-' or omit to read from stdin.",
894
898
  )
895
- parser.add_argument(
896
- "--task",
897
- action="store_true",
898
- help="Run in task mode with verification retries.",
899
- )
900
- parser.add_argument(
901
- "--check",
902
- help="Optional check prompt for --task. Defaults to the task prompt.",
903
- )
904
- parser.add_argument("--cwd", help="Working directory for the Codex session.")
905
- parser.add_argument("--yolo", action="store_true", help="Pass --yolo to Codex.")
906
- 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(
907
902
  "--flags",
908
903
  help="Additional raw CLI flags to pass to Codex (quoted as needed).",
909
904
  )
910
- parser.add_argument(
905
+ run_parser.add_argument(
911
906
  "--thread-id",
912
907
  help="Resume an existing Codex thread id.",
913
908
  )
914
- parser.add_argument(
909
+ run_parser.add_argument(
915
910
  "--print-thread-id",
916
911
  action="store_true",
917
912
  help="Print the current thread id to stderr after running.",
918
913
  )
919
- parser.add_argument(
920
- "--ralph",
921
- action="store_true",
922
- 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.",
923
951
  )
924
- parser.add_argument(
952
+ ralph_parser.add_argument(
925
953
  "--max-iterations",
926
954
  type=int,
927
- default=None,
928
- 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.",
929
962
  )
930
- parser.add_argument(
963
+ ralph_parser.add_argument(
931
964
  "--completion-promise",
932
- help="Promise text for --ralph to match in <promise>...</promise>.",
965
+ help="Promise text to match in <promise>...</promise>.",
933
966
  )
934
- parser.add_argument(
967
+ ralph_parser.add_argument(
935
968
  "--ralph-fresh",
936
969
  action="store_true",
937
- help="With --ralph, start each iteration with a fresh Agent context.",
970
+ help="Start each iteration with a fresh Agent context.",
938
971
  )
939
- parser.add_argument(
940
- "--ralph-cancel",
941
- action="store_true",
942
- help=(
943
- "Cancel a Ralph loop by removing .codexapi/ralph-loop.local.md "
944
- "(respects --cwd)."
945
- ),
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.",
946
982
  )
947
983
 
948
984
  args = parser.parse_args(argv)
949
- if args.ralph_cancel:
950
- if (
951
- args.ralph
952
- or args.task
953
- or args.thread_id
954
- or args.print_thread_id
955
- or args.max_iterations is not None
956
- or args.completion_promise is not None
957
- or args.ralph_fresh
958
- or args.check is not None
959
- or args.prompt
960
- ):
961
- raise SystemExit(
962
- "--ralph-cancel cannot be combined with prompts or other modes."
963
- )
964
- 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([])
965
990
  return
966
- if args.check is not None and not args.task:
967
- raise SystemExit("--check requires --task.")
968
- if not args.ralph and (
969
- args.max_iterations is not None
970
- or args.completion_promise is not None
971
- or args.ralph_fresh
972
- ):
973
- raise SystemExit(
974
- "--max-iterations/--completion-promise/--ralph-fresh require --ralph."
975
- )
976
- if args.ralph and (args.task or args.thread_id or args.print_thread_id):
977
- raise SystemExit(
978
- "--task/--thread-id/--print-thread-id are not supported with --ralph."
979
- )
980
- if args.task and (args.thread_id or args.print_thread_id):
981
- raise SystemExit("--thread-id/--print-thread-id are not supported with --task.")
982
991
 
983
- 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
984
1002
 
1003
+ prompt = _read_prompt(args.prompt)
985
1004
  exit_code = 0
986
1005
 
987
- if args.ralph:
988
- max_iterations = args.max_iterations if args.max_iterations is not None else 0
989
- if max_iterations < 0:
1006
+ if args.command == "ralph":
1007
+ if args.max_iterations < 0:
990
1008
  raise SystemExit("--max-iterations must be >= 0.")
991
1009
  run_ralph_loop(
992
1010
  prompt,
993
1011
  args.cwd,
994
1012
  args.yolo,
995
1013
  args.flags,
996
- max_iterations,
1014
+ args.max_iterations,
997
1015
  args.completion_promise,
998
1016
  args.ralph_fresh,
999
1017
  )
1000
1018
  return
1001
- if args.task:
1019
+ if args.command == "task":
1020
+ if args.max_iterations < 0:
1021
+ raise SystemExit("--max-iterations must be >= 0.")
1002
1022
  check = args.check if args.check is not None else prompt
1003
1023
  try:
1004
1024
  message = task(
1005
1025
  prompt,
1006
1026
  check,
1007
- cwd=args.cwd,
1008
- yolo=args.yolo,
1009
- flags=args.flags,
1027
+ args.max_iterations,
1028
+ args.cwd,
1029
+ args.yolo,
1030
+ args.flags,
1010
1031
  )
1011
1032
  except TaskFailed as exc:
1012
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.1.9
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