codexapi 0.6.8__tar.gz → 0.7.1__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.
Files changed (27) hide show
  1. {codexapi-0.6.8/src/codexapi.egg-info → codexapi-0.7.1}/PKG-INFO +36 -14
  2. {codexapi-0.6.8 → codexapi-0.7.1}/README.md +35 -13
  3. {codexapi-0.6.8 → codexapi-0.7.1}/pyproject.toml +1 -1
  4. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/__init__.py +3 -3
  5. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/agent.py +15 -6
  6. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/cli.py +62 -19
  7. codexapi-0.7.1/src/codexapi/lead.py +477 -0
  8. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/pushover.py +1 -1
  9. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/ralph.py +17 -2
  10. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/science.py +1 -0
  11. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/task.py +1 -1
  12. {codexapi-0.6.8 → codexapi-0.7.1/src/codexapi.egg-info}/PKG-INFO +36 -14
  13. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi.egg-info/SOURCES.txt +1 -1
  14. codexapi-0.6.8/src/codexapi/watch.py +0 -302
  15. {codexapi-0.6.8 → codexapi-0.7.1}/LICENSE +0 -0
  16. {codexapi-0.6.8 → codexapi-0.7.1}/setup.cfg +0 -0
  17. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/__main__.py +0 -0
  18. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/foreach.py +0 -0
  19. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/gh_integration.py +0 -0
  20. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/rate_limits.py +0 -0
  21. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/taskfile.py +0 -0
  22. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/welfare.py +0 -0
  23. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi.egg-info/dependency_links.txt +0 -0
  24. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi.egg-info/entry_points.txt +0 -0
  25. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi.egg-info/requires.txt +0 -0
  26. {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi.egg-info/top_level.txt +0 -0
  27. {codexapi-0.6.8 → codexapi-0.7.1}/tests/test_task_progress.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codexapi
3
- Version: 0.6.8
3
+ Version: 0.7.1
4
4
  Summary: Minimal Python API for running the Codex CLI.
5
5
  License: MIT
6
6
  Keywords: codex,agent,cli,openai
@@ -130,17 +130,32 @@ codexapi run --thread-id THREAD_ID --print-thread-id "Continue where we left off
130
130
  ```
131
131
 
132
132
  Use `--no-yolo` to run Codex with `--full-auto` instead.
133
+ Use `--include-thinking` to return all agent messages joined together for `codexapi run`.
133
134
 
134
- Watch mode periodically ticks a long-running agent session with the current time
135
- and prints JSON status updates. The agent controls the loop by setting
136
- `continue` to true/false in its JSON response. Each tick expects JSON keys:
135
+ Lead mode periodically checks in on a long-running agent session with the
136
+ current time and prints JSON status updates. The agent controls the loop by
137
+ setting `continue` to true/false in its JSON response. Each check-in expects
138
+ JSON keys:
137
139
  `status` (one line), `continue` (bool), and optional `comments` (string). If the
138
- JSON is invalid, watch asks the agent once to retry before stopping with an
139
- error. When `~/.pushover` is configured, watch sends a notification when it
140
+ JSON is invalid, lead asks the agent once to retry before stopping with an
141
+ error. When `~/.pushover` is configured, lead sends a notification when it
140
142
  stops.
141
143
 
144
+ Lead mode also uses a leadbook file as the agent's working page. By default this
145
+ is `LEADBOOK.md` in the working directory. The leadbook content is injected into
146
+ each check-in prompt and must be updated before the agent responds. Use
147
+ `--leadbook PATH` to point at a different file, or `--no-leadbook` to disable.
148
+ Use `-f/--prompt-file` to read the prompt from a file.
149
+ If the leadbook does not exist, lead creates it with a template.
150
+
151
+ ```bash
152
+ codexapi lead 5 "Run the benchmark and wait for results."
153
+
154
+ Run without waiting between check-ins:
155
+
142
156
  ```bash
143
- codexapi watch 5 "Run the benchmark and wait for results."
157
+ codexapi lead 0 "Do a rapid triage pass and report."
158
+ ```
144
159
  ```
145
160
 
146
161
  Ralph loop mode repeats the same prompt until a completion promise or a max
@@ -171,7 +186,7 @@ Optional Pushover notifications: create `~/.pushover` with two non-empty lines.
171
186
  Line 1 is your user or group key, line 2 is the app API token. When this file
172
187
  exists, Science will send a notification whenever it detects a new best result,
173
188
  including the metric values and percent improvement. Task runs will also send a
174
- ✅/❌ notification with the task summary. Watch runs send a notification when the
189
+ ✅/❌ notification with the task summary. Lead runs send a notification when the
175
190
  loop stops.
176
191
 
177
192
  Run a task file across a list file:
@@ -185,7 +200,7 @@ codexapi foreach list.txt task.yaml --retry-all
185
200
 
186
201
  ## API
187
202
 
188
- ### `agent(prompt, cwd=None, yolo=True, flags=None) -> str`
203
+ ### `agent(prompt, cwd=None, yolo=True, flags=None, include_thinking=False) -> str`
189
204
 
190
205
  Runs a single Codex turn and returns only the agent's message. Any reasoning
191
206
  items are filtered out.
@@ -194,8 +209,9 @@ items are filtered out.
194
209
  - `cwd` (str | PathLike | None): working directory for the Codex session.
195
210
  - `yolo` (bool): pass `--yolo` to Codex when true (defaults to true).
196
211
  - `flags` (str | None): extra CLI flags to pass to Codex.
212
+ - `include_thinking` (bool): when true, return all agent messages joined.
197
213
 
198
- ### `Agent(cwd=None, yolo=True, thread_id=None, flags=None, welfare=False)`
214
+ ### `Agent(cwd=None, yolo=True, thread_id=None, flags=None, welfare=False, include_thinking=False)`
199
215
 
200
216
  Creates a stateful session wrapper. Calling the instance sends the prompt into
201
217
  the same conversation and returns only the agent's message.
@@ -206,15 +222,20 @@ the same conversation and returns only the agent's message.
206
222
  - `flags` (str | None): extra CLI flags to pass to Codex.
207
223
  - `welfare` (bool): when true, append welfare stop instructions to each prompt
208
224
  and raise `WelfareStop` if the agent outputs `MAKE IT STOP`.
225
+ - `include_thinking` (bool): when true, return all agent messages joined.
209
226
 
210
- ### `watch(minutes, prompt, cwd=None, yolo=True, flags=None) -> dict`
227
+ ### `lead(minutes, prompt, cwd=None, yolo=True, flags=None, leadbook=None) -> dict`
211
228
 
212
- Runs a long-lived agent session and periodically "ticks" it with the current
213
- local time and a reminder of `prompt`. Each tick expects JSON with keys:
229
+ Runs a long-lived agent session and periodically checks in with the current
230
+ local time and a reminder of `prompt`. Each check-in expects JSON with keys:
214
231
  `status` (one line), `continue` (bool), and optional `comments` (string). If the
215
- JSON is invalid, watch asks the agent once to retry. The loop stops when
232
+ JSON is invalid, lead asks the agent once to retry. The loop stops when
216
233
  `continue` is false and sends a Pushover notification (when configured).
217
234
 
235
+ Lead also injects the leadbook content into each prompt. By default it uses
236
+ `LEADBOOK.md` in the working directory. Pass `leadbook=False` to disable or a
237
+ path string to override the location.
238
+
218
239
  ### `task(prompt, check=None, max_iterations=10, cwd=None, yolo=True, flags=None, progress=False, set_up=None, tear_down=None, on_success=None, on_failure=None) -> str`
219
240
 
220
241
  Runs a task with checker-driven retries and returns the success summary.
@@ -287,6 +308,7 @@ Simple result object returned by `foreach()`.
287
308
  ## Behavior notes
288
309
 
289
310
  - Uses `codex exec --json` and parses JSONL events for `agent_message` items.
311
+ - Returns the last `agent_message` by default; set `include_thinking=True` to join all messages.
290
312
  - Automatically passes `--skip-git-repo-check` so it can run outside a git repo.
291
313
  - Passes `--yolo` by default (use `--no-yolo` or `yolo=False` for `--full-auto`).
292
314
  - Raises `RuntimeError` if Codex exits non-zero or returns no agent message.
@@ -115,17 +115,32 @@ codexapi run --thread-id THREAD_ID --print-thread-id "Continue where we left off
115
115
  ```
116
116
 
117
117
  Use `--no-yolo` to run Codex with `--full-auto` instead.
118
+ Use `--include-thinking` to return all agent messages joined together for `codexapi run`.
118
119
 
119
- Watch mode periodically ticks a long-running agent session with the current time
120
- and prints JSON status updates. The agent controls the loop by setting
121
- `continue` to true/false in its JSON response. Each tick expects JSON keys:
120
+ Lead mode periodically checks in on a long-running agent session with the
121
+ current time and prints JSON status updates. The agent controls the loop by
122
+ setting `continue` to true/false in its JSON response. Each check-in expects
123
+ JSON keys:
122
124
  `status` (one line), `continue` (bool), and optional `comments` (string). If the
123
- JSON is invalid, watch asks the agent once to retry before stopping with an
124
- error. When `~/.pushover` is configured, watch sends a notification when it
125
+ JSON is invalid, lead asks the agent once to retry before stopping with an
126
+ error. When `~/.pushover` is configured, lead sends a notification when it
125
127
  stops.
126
128
 
129
+ Lead mode also uses a leadbook file as the agent's working page. By default this
130
+ is `LEADBOOK.md` in the working directory. The leadbook content is injected into
131
+ each check-in prompt and must be updated before the agent responds. Use
132
+ `--leadbook PATH` to point at a different file, or `--no-leadbook` to disable.
133
+ Use `-f/--prompt-file` to read the prompt from a file.
134
+ If the leadbook does not exist, lead creates it with a template.
135
+
136
+ ```bash
137
+ codexapi lead 5 "Run the benchmark and wait for results."
138
+
139
+ Run without waiting between check-ins:
140
+
127
141
  ```bash
128
- codexapi watch 5 "Run the benchmark and wait for results."
142
+ codexapi lead 0 "Do a rapid triage pass and report."
143
+ ```
129
144
  ```
130
145
 
131
146
  Ralph loop mode repeats the same prompt until a completion promise or a max
@@ -156,7 +171,7 @@ Optional Pushover notifications: create `~/.pushover` with two non-empty lines.
156
171
  Line 1 is your user or group key, line 2 is the app API token. When this file
157
172
  exists, Science will send a notification whenever it detects a new best result,
158
173
  including the metric values and percent improvement. Task runs will also send a
159
- ✅/❌ notification with the task summary. Watch runs send a notification when the
174
+ ✅/❌ notification with the task summary. Lead runs send a notification when the
160
175
  loop stops.
161
176
 
162
177
  Run a task file across a list file:
@@ -170,7 +185,7 @@ codexapi foreach list.txt task.yaml --retry-all
170
185
 
171
186
  ## API
172
187
 
173
- ### `agent(prompt, cwd=None, yolo=True, flags=None) -> str`
188
+ ### `agent(prompt, cwd=None, yolo=True, flags=None, include_thinking=False) -> str`
174
189
 
175
190
  Runs a single Codex turn and returns only the agent's message. Any reasoning
176
191
  items are filtered out.
@@ -179,8 +194,9 @@ items are filtered out.
179
194
  - `cwd` (str | PathLike | None): working directory for the Codex session.
180
195
  - `yolo` (bool): pass `--yolo` to Codex when true (defaults to true).
181
196
  - `flags` (str | None): extra CLI flags to pass to Codex.
197
+ - `include_thinking` (bool): when true, return all agent messages joined.
182
198
 
183
- ### `Agent(cwd=None, yolo=True, thread_id=None, flags=None, welfare=False)`
199
+ ### `Agent(cwd=None, yolo=True, thread_id=None, flags=None, welfare=False, include_thinking=False)`
184
200
 
185
201
  Creates a stateful session wrapper. Calling the instance sends the prompt into
186
202
  the same conversation and returns only the agent's message.
@@ -191,15 +207,20 @@ the same conversation and returns only the agent's message.
191
207
  - `flags` (str | None): extra CLI flags to pass to Codex.
192
208
  - `welfare` (bool): when true, append welfare stop instructions to each prompt
193
209
  and raise `WelfareStop` if the agent outputs `MAKE IT STOP`.
210
+ - `include_thinking` (bool): when true, return all agent messages joined.
194
211
 
195
- ### `watch(minutes, prompt, cwd=None, yolo=True, flags=None) -> dict`
212
+ ### `lead(minutes, prompt, cwd=None, yolo=True, flags=None, leadbook=None) -> dict`
196
213
 
197
- Runs a long-lived agent session and periodically "ticks" it with the current
198
- local time and a reminder of `prompt`. Each tick expects JSON with keys:
214
+ Runs a long-lived agent session and periodically checks in with the current
215
+ local time and a reminder of `prompt`. Each check-in expects JSON with keys:
199
216
  `status` (one line), `continue` (bool), and optional `comments` (string). If the
200
- JSON is invalid, watch asks the agent once to retry. The loop stops when
217
+ JSON is invalid, lead asks the agent once to retry. The loop stops when
201
218
  `continue` is false and sends a Pushover notification (when configured).
202
219
 
220
+ Lead also injects the leadbook content into each prompt. By default it uses
221
+ `LEADBOOK.md` in the working directory. Pass `leadbook=False` to disable or a
222
+ path string to override the location.
223
+
203
224
  ### `task(prompt, check=None, max_iterations=10, cwd=None, yolo=True, flags=None, progress=False, set_up=None, tear_down=None, on_success=None, on_failure=None) -> str`
204
225
 
205
226
  Runs a task with checker-driven retries and returns the success summary.
@@ -272,6 +293,7 @@ Simple result object returned by `foreach()`.
272
293
  ## Behavior notes
273
294
 
274
295
  - Uses `codex exec --json` and parses JSONL events for `agent_message` items.
296
+ - Returns the last `agent_message` by default; set `include_thinking=True` to join all messages.
275
297
  - Automatically passes `--skip-git-repo-check` so it can run outside a git repo.
276
298
  - Passes `--yolo` by default (use `--no-yolo` or `yolo=False` for `--full-auto`).
277
299
  - Raises `RuntimeError` if Codex exits non-zero or returns no agent message.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "codexapi"
7
- version = "0.6.8"
7
+ version = "0.7.1"
8
8
  description = "Minimal Python API for running the Codex CLI."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -7,7 +7,7 @@ from .rate_limits import quota_line, rate_limits
7
7
  from .ralph import Ralph
8
8
  from .science import Science
9
9
  from .task import Task, TaskFailed, TaskResult, task, task_result
10
- from .watch import watch
10
+ from .lead import lead
11
11
 
12
12
  __all__ = [
13
13
  "Agent",
@@ -25,6 +25,6 @@ __all__ = [
25
25
  "foreach",
26
26
  "task",
27
27
  "task_result",
28
- "watch",
28
+ "lead",
29
29
  ]
30
- __version__ = "0.6.8"
30
+ __version__ = "0.7.1"
@@ -10,7 +10,7 @@ from . import welfare
10
10
  _CODEX_BIN = os.environ.get("CODEX_BIN", "codex")
11
11
 
12
12
 
13
- def agent(prompt, cwd=None, yolo=True, flags=None):
13
+ def agent(prompt, cwd=None, yolo=True, flags=None, include_thinking=False):
14
14
  """Run a single Codex turn and return only the agent's message.
15
15
 
16
16
  Args:
@@ -18,11 +18,14 @@ def agent(prompt, cwd=None, yolo=True, flags=None):
18
18
  cwd: Optional working directory for the Codex session.
19
19
  yolo: Whether to pass --yolo to Codex.
20
20
  flags: Additional raw CLI flags to pass to Codex.
21
+ include_thinking: When true, return all agent messages joined together.
21
22
 
22
23
  Returns:
23
24
  The agent's visible response text with reasoning traces removed.
24
25
  """
25
- message, _thread_id = _run_codex(prompt, cwd, None, yolo, flags)
26
+ message, _thread_id = _run_codex(
27
+ prompt, cwd, None, yolo, flags, include_thinking
28
+ )
26
29
  return message
27
30
 
28
31
 
@@ -51,6 +54,7 @@ class Agent:
51
54
  thread_id=None,
52
55
  flags=None,
53
56
  welfare=False,
57
+ include_thinking=False,
54
58
  ):
55
59
  """Create a new session wrapper.
56
60
 
@@ -62,11 +66,13 @@ class Agent:
62
66
  flags: Additional raw CLI flags to pass to Codex.
63
67
  welfare: When true, append welfare stop instructions to each prompt
64
68
  and raise WelfareStop if the agent outputs MAKE IT STOP.
69
+ include_thinking: When true, return all agent messages joined together.
65
70
  """
66
71
  self.cwd = cwd
67
72
  self._yolo = yolo
68
73
  self._flags = flags
69
74
  self._welfare = welfare
75
+ self._include_thinking = include_thinking
70
76
  self.thread_id = thread_id
71
77
 
72
78
  def __call__(self, prompt):
@@ -79,6 +85,7 @@ class Agent:
79
85
  self.thread_id,
80
86
  self._yolo,
81
87
  self._flags,
88
+ self._include_thinking,
82
89
  )
83
90
  if thread_id:
84
91
  self.thread_id = thread_id
@@ -87,7 +94,7 @@ class Agent:
87
94
  return message
88
95
 
89
96
 
90
- def _run_codex(prompt, cwd, thread_id, yolo, flags):
97
+ def _run_codex(prompt, cwd, thread_id, yolo, flags, include_thinking):
91
98
  """Invoke the Codex CLI and return the message plus thread id (if any)."""
92
99
  command = [
93
100
  _CODEX_BIN,
@@ -124,10 +131,10 @@ def _run_codex(prompt, cwd, thread_id, yolo, flags):
124
131
  msg = f"{msg}\n{stderr}"
125
132
  raise RuntimeError(msg)
126
133
 
127
- return _parse_jsonl(result.stdout)
134
+ return _parse_jsonl(result.stdout, include_thinking)
128
135
 
129
136
 
130
- def _parse_jsonl(output):
137
+ def _parse_jsonl(output, include_thinking):
131
138
  """Extract agent messages and the latest thread id from Codex JSONL output."""
132
139
  thread_id = None
133
140
  messages = []
@@ -161,4 +168,6 @@ def _parse_jsonl(output):
161
168
  "Codex returned no agent message. Raw output:\n" + fallback
162
169
  )
163
170
 
164
- return "\n\n".join(messages), thread_id
171
+ if include_thinking:
172
+ return "\n\n".join(messages), thread_id
173
+ return messages[-1], thread_id
@@ -19,7 +19,7 @@ from .science import Science
19
19
  from .task import DEFAULT_MAX_ITERATIONS, TaskFailed, task
20
20
  from .taskfile import TaskFile, load_task_file, task_def_uses_item
21
21
  from .rate_limits import quota_line
22
- from .watch import watch
22
+ from .lead import lead
23
23
 
24
24
  _SESSION_ID_RE = re.compile(
25
25
  r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
@@ -92,6 +92,19 @@ def _read_prompt(prompt):
92
92
  return data
93
93
 
94
94
 
95
+ def _read_prompt_file(path):
96
+ if not path or not str(path).strip():
97
+ raise SystemExit("Prompt file path is empty.")
98
+ try:
99
+ with open(path, "r", encoding="utf-8") as handle:
100
+ data = handle.read()
101
+ except FileNotFoundError:
102
+ raise SystemExit(f"Prompt file not found: {path}") from None
103
+ if not data.strip():
104
+ raise SystemExit(f"Prompt file is empty: {path}")
105
+ return data
106
+
107
+
95
108
  def _single_line(text):
96
109
  if not text:
97
110
  return ""
@@ -1040,29 +1053,48 @@ def main(argv=None):
1040
1053
  "--flags",
1041
1054
  help="Additional raw CLI flags to pass to Codex (quoted as needed).",
1042
1055
  )
1056
+ run_parser.add_argument(
1057
+ "--include-thinking",
1058
+ action="store_true",
1059
+ help="Return all agent messages joined together.",
1060
+ )
1043
1061
 
1044
- watch_parser = subparsers.add_parser(
1045
- "watch",
1046
- help="Periodically tick an agent for long-running work.",
1062
+ lead_parser = subparsers.add_parser(
1063
+ "lead",
1064
+ help="Periodically check in to lead long-running work.",
1047
1065
  )
1048
- watch_parser.add_argument(
1066
+ lead_parser.add_argument(
1049
1067
  "minutes",
1050
1068
  type=int,
1051
- help="Tick interval in minutes (integer, >= 1).",
1069
+ help="Check-in interval in minutes (integer, >= 0).",
1052
1070
  )
1053
- watch_parser.add_argument(
1071
+ lead_parser.add_argument(
1054
1072
  "prompt",
1055
1073
  nargs="?",
1056
1074
  help="Prompt to send. Use '-' or omit to read from stdin.",
1057
1075
  )
1058
- watch_parser.add_argument("--cwd", help="Working directory for the Codex session.")
1059
- watch_parser.add_argument(
1076
+ lead_parser.add_argument(
1077
+ "-f",
1078
+ "--prompt-file",
1079
+ help="Read the lead prompt from a file.",
1080
+ )
1081
+ lead_parser.add_argument("--cwd", help="Working directory for the Codex session.")
1082
+ lead_parser.add_argument(
1083
+ "--leadbook",
1084
+ help="Path to the leadbook file (default: LEADBOOK.md in cwd).",
1085
+ )
1086
+ lead_parser.add_argument(
1087
+ "--no-leadbook",
1088
+ action="store_true",
1089
+ help="Disable leadbook injection and checks.",
1090
+ )
1091
+ lead_parser.add_argument(
1060
1092
  "--no-yolo",
1061
1093
  action="store_false",
1062
1094
  dest="yolo",
1063
1095
  help="Disable --yolo and use --full-auto.",
1064
1096
  )
1065
- watch_parser.add_argument(
1097
+ lead_parser.add_argument(
1066
1098
  "--flags",
1067
1099
  help="Additional raw CLI flags to pass to Codex (quoted as needed).",
1068
1100
  )
@@ -1517,11 +1549,16 @@ def main(argv=None):
1517
1549
 
1518
1550
  prompt_source = None
1519
1551
  prompt = None
1520
- if args.command in ("run", "ralph", "watch"):
1521
- prompt_source = args.prompt
1552
+ if args.command in ("run", "ralph", "lead"):
1553
+ if args.command == "lead" and args.prompt_file:
1554
+ if args.prompt is not None:
1555
+ raise SystemExit("lead --prompt-file cannot be used with a prompt arg.")
1556
+ prompt = _read_prompt_file(args.prompt_file)
1557
+ else:
1558
+ prompt_source = args.prompt
1522
1559
  elif args.command == "science":
1523
1560
  prompt_source = args.task
1524
- if args.command != "task":
1561
+ if args.command != "task" and prompt is None:
1525
1562
  prompt = _read_prompt(prompt_source)
1526
1563
  exit_code = 0
1527
1564
  message = None
@@ -1552,15 +1589,18 @@ def main(argv=None):
1552
1589
  args.ralph_fresh,
1553
1590
  )()
1554
1591
  return
1555
- if args.command == "watch":
1556
- if args.minutes < 1:
1557
- raise SystemExit("watch minutes must be >= 1.")
1592
+ if args.command == "lead":
1593
+ if args.minutes < 0:
1594
+ raise SystemExit("lead minutes must be >= 0.")
1558
1595
  try:
1559
- watch(args.minutes, prompt, args.cwd, args.yolo, args.flags)
1596
+ if args.no_leadbook and args.leadbook:
1597
+ raise SystemExit("--leadbook and --no-leadbook are mutually exclusive.")
1598
+ leadbook = False if args.no_leadbook else args.leadbook
1599
+ lead(args.minutes, prompt, args.cwd, args.yolo, args.flags, leadbook)
1560
1600
  except KeyboardInterrupt:
1561
1601
  raise SystemExit(130)
1562
1602
  except Exception as exc:
1563
- raise SystemExit(str(exc) or "watch failed") from None
1603
+ raise SystemExit(str(exc) or "lead failed") from None
1564
1604
  return
1565
1605
  if args.command == "task":
1566
1606
  if args.project:
@@ -1602,12 +1642,15 @@ def main(argv=None):
1602
1642
  args.yolo,
1603
1643
  args.thread_id,
1604
1644
  args.flags,
1645
+ include_thinking=args.include_thinking,
1605
1646
  )
1606
1647
  message = session(prompt)
1607
1648
  if args.print_thread_id:
1608
1649
  print(f"thread_id={session.thread_id}", file=sys.stderr)
1609
1650
  else:
1610
- message = agent(prompt, args.cwd, args.yolo, args.flags)
1651
+ message = agent(
1652
+ prompt, args.cwd, args.yolo, args.flags, args.include_thinking
1653
+ )
1611
1654
 
1612
1655
  if message is not None:
1613
1656
  print(message)