parallel-codex-tui 0.2.3 → 0.2.4

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.
@@ -3,7 +3,8 @@ defaultMode = "auto"
3
3
 
4
4
  [router.codex]
5
5
  command = "codex"
6
- args = ["exec", "--ephemeral", "--ignore-rules", "-c", "model_reasoning_effort=low", "--skip-git-repo-check", "--sandbox", "read-only", "--color", "never", "-"]
6
+ # Codex approval policy is a root option and must appear before `exec`.
7
+ args = ["-a", "never", "exec", "--ephemeral", "--ignore-rules", "-c", "model_reasoning_effort=low", "--skip-git-repo-check", "--sandbox", "read-only", "--color", "never", "-"]
7
8
  timeoutMs = 60000
8
9
  # Stop a silent Router before the total ceiling so one transient retry stays bounded.
9
10
  firstOutputTimeoutMs = 30000
@@ -37,8 +38,8 @@ maxConflictReplans = 2
37
38
 
38
39
  [workers.codex]
39
40
  command = "codex"
40
- # Automated Judge/Actor/Critic runs enforce workspace-write even if private args request a broader sandbox.
41
- args = ["exec", "--skip-git-repo-check", "--sandbox", "workspace-write", "--color", "never", "-"]
41
+ # Non-interactive runs never wait for an approval UI. Isolated coding roles also enforce workspace-write.
42
+ args = ["-a", "never", "exec", "--skip-git-repo-check", "--sandbox", "workspace-write", "--color", "never", "-"]
42
43
  # timeoutMs is the hard ceiling; first output owns silent startup and idle starts after actual output.
43
44
  # timeoutMs = 2700000
44
45
  # idleTimeoutMs = 300000
@@ -66,6 +67,7 @@ freshSessionArgs = []
66
67
 
67
68
  [workers.codex.interactive]
68
69
  command = "codex"
70
+ # Native attach stays interactive; do not add `-a never` here.
69
71
  args = ["resume", "{sessionId}"]
70
72
  # Used by the Task session detail view when branching from a recorded native session.
71
73
  forkArgs = ["fork", "{sessionId}"]
package/README.md CHANGED
@@ -6,7 +6,7 @@ Built with Codex-assisted development.
6
6
 
7
7
  ## Current Release
8
8
 
9
- `v0.2.3` is available from [npm](https://www.npmjs.com/package/parallel-codex-tui/v/0.2.3) and as a [GitHub Release](https://github.com/allendred/parallel-codex-tui/releases/tag/v0.2.3). Claude Main now uses non-interactive `auto` permissions so safe tool calls can run instead of asking for an approval that the chat cannot deliver. Isolated coding Workers remain clamped to `acceptEdits`; the macOS system-proxy and Up/Down history fixes from `v0.2.2` remain included.
9
+ `v0.2.4` is available from [npm](https://www.npmjs.com/package/parallel-codex-tui/v/0.2.4) and as a [GitHub Release](https://github.com/allendred/parallel-codex-tui/releases/tag/v0.2.4). Codex Router, Main, and automated Workers now place the non-interactive approval policy at the required root position as `-a never ... exec`, while retaining `read-only` routing and `workspace-write` coding sandboxes. Isolated Codex roles also replace unsafe or interactive approval arguments; native attach remains interactive. The Claude Main permission fix from `v0.2.3` remains included.
10
10
 
11
11
  The release keeps terminal scrolling and copying available at the same time without requiring Shift. Ordinary left-drag selection remains owned by the terminal while alternate-scroll delivers the wheel to chat, Worker logs, and structured views. `Ctrl+Y` copies the visible view as a fallback. It preserves the embedded native Agent scrollback across status-detail round trips and real PTY resizes.
12
12
 
@@ -20,7 +20,7 @@ Highlights:
20
20
  - Named Worker Providers support Codex-compatible, Claude-compatible, OpenAI-compatible, Anthropic-compatible, and custom generic commands with independent role, model, environment, permission, resume, and interactive settings.
21
21
  - Worker overview, Feature board, collaboration timeline, Task center, status details, rendered Markdown/Diff/error logs, Unicode search, keyboard navigation, mouse scrolling, and configurable themes share one terminal UI system.
22
22
 
23
- Release acceptance includes a real three-Feature Tetris task with parallel Actor/Critic waves and final integration review. Real Codex and Claude probes both proved fresh and same-session resume calls, and a Claude Main session executed safe Bash tools before and after resume with `auto` permissions. The semantic Router completed a live classification, and one TUI completed Main calls in two workspaces before restoring the first workspace without leaking chat state. PTY coverage runs in Apple Terminal, tmux, and Zellij profiles at narrow and wide sizes, including status/log equivalence and preserving the native output tail across status-detail round trips. The deterministic repository suite passed 1,264 tests across 123 files; one quota-consuming real-Agent test is skipped by default and passes through `npm run test:real-agents`.
23
+ Release acceptance includes a real three-Feature Tetris task with parallel Actor/Critic waves and final integration review. Real Codex and Claude probes both proved fresh and same-session resume calls; Codex fresh and resume runs executed workspace writes with root-level `-a never`, and a Claude Main session executed safe Bash tools before and after resume with `auto` permissions. The semantic Router completed a live classification, and one TUI completed Main calls in two workspaces before restoring the first workspace without leaking chat state. PTY coverage runs in Apple Terminal, tmux, and Zellij profiles at narrow and wide sizes, including status/log equivalence and preserving the native output tail across status-detail round trips. The deterministic repository suite passed 1,265 tests across 123 files; one quota-consuming real-Agent test is skipped by default and passes through `npm run test:real-agents`.
24
24
 
25
25
  Real Provider probes depend on valid local CLI credentials. In particular, authenticate the Claude CLI before selecting a Claude-compatible Worker, then run `parallel-codex-tui --doctor --probe-agents` to prove fresh and resumed calls on that machine.
26
26
 
@@ -236,7 +236,7 @@ The doctor output includes `preview:` and `semantic:` ANSI swatch rows so you ca
236
236
  - Every numbered turn keeps its own immutable Judge, Actor, and Critic worker directories. Later turns use suffixed ids such as `judge-codex-0002`; the log viewer retains earlier workers, cycles them in turn order, and restores the same order after restart. The new worker record may reuse the prior native session id without overwriting the prior turn's prompt, status, log, or native-session metadata.
237
237
  - `Ctrl+N` leaves the active complex task intact on disk while clearing its live context, worker selection, retry state, and status so the next complex request creates an independent task from turn `0001`.
238
238
  - Single-feature follow-ups reuse the same Actor/Critic native sessions when available while moving them to the new turn's isolated workspace; prompts include up to five prior turn summaries as file-backed memory. A failed follow-up retry reuses a complete saved Judge plan, or restores Judge first when the earlier Judge run never produced one.
239
- - Automated Judge, Actor, Critic, Wave Actor, and Wave Critic runs enforce process-level isolation: Codex is clamped to `workspace-write`, and Claude is clamped to `acceptEdits`, even when private command arguments contain a broader bypass mode. Native attach remains an explicit interactive path.
239
+ - Automated Judge, Actor, Critic, Wave Actor, and Wave Critic runs enforce process-level isolation: Codex is clamped to root-level `-a never` plus `workspace-write`, and Claude is clamped to `acceptEdits`, even when private command arguments request interactive approval or contain a broader bypass mode. Native attach remains an explicit interactive path.
240
240
  - Pressing `Esc` while a request is running stops the router or active worker and records an interrupted complex task as `cancelled`; exiting the outer TUI also terminates the active run.
241
241
  - Failed and cancelled tasks expose `Ctrl+R` retry. Retry keeps the same task and turn, reuses recorded native worker sessions, preserves prior output behind a retry separator, does not route the request again, and reuses the persisted feature dependency plan. A complete Judge snapshot and fully integrated waves are skipped; an unchanged in-progress wave reuses successful Actor and Critic checkpoints and runs only unfinished workers. If the live workspace no longer matches the saved baseline, the stale wave checkpoint is rejected and rebuilt from the current project before workers continue.
242
242
  - The shared Main chat holds its own `sessions/main/run-owner.json` lease across prompt initialization, native-session reuse, and Worker completion. A second TUI is rejected before it can clear or overwrite the active Main prompt, log, status, or native session, and startup native-session reconciliation skips a Main session owned by another live TUI. After a hard exit, startup atomically claims the stale Main lease, terminates every verifiable orphan process group, marks active Main Workers `cancelled`, preserves native session ids, and records recovery before exposing the runtime. An unverifiable or still-running Main process blocks startup without changing its status or checkpoints.
@@ -263,7 +263,7 @@ defaultMode = "auto"
263
263
 
264
264
  [router.codex]
265
265
  command = "codex"
266
- args = ["exec", "--ephemeral", "--ignore-rules", "-c", "model_reasoning_effort=low", "--skip-git-repo-check", "--sandbox", "read-only", "--color", "never", "-"]
266
+ args = ["-a", "never", "exec", "--ephemeral", "--ignore-rules", "-c", "model_reasoning_effort=low", "--skip-git-repo-check", "--sandbox", "read-only", "--color", "never", "-"]
267
267
  timeoutMs = 60000
268
268
  firstOutputTimeoutMs = 30000
269
269
  idleTimeoutMs = 30000
@@ -328,7 +328,7 @@ Configure Codex and Claude commands in `.parallel-codex/config.toml`:
328
328
  ```toml
329
329
  [workers.codex]
330
330
  command = "codex"
331
- args = ["exec", "--skip-git-repo-check", "--sandbox", "workspace-write", "--color", "never", "-"]
331
+ args = ["-a", "never", "exec", "--skip-git-repo-check", "--sandbox", "workspace-write", "--color", "never", "-"]
332
332
 
333
333
  [workers.codex.model]
334
334
  name = "gpt-5"
@@ -363,7 +363,7 @@ args = ["--resume", "{sessionId}"]
363
363
  forkArgs = ["--resume", "{sessionId}", "--fork-session"]
364
364
  ```
365
365
 
366
- `model.args` and `model.env` apply to both automated worker runs and embedded native attach sessions. Native attach appends the rendered model arguments after `interactive.args`, so third-party `{model}` and `{provider}` selections remain active when you press `Ctrl+O`. Claude Main uses `auto` so safe tool calls can complete in print mode; isolated Claude coding roles are still clamped to `acceptEdits`. When a command genuinely needs interactive approval, Main points to `Ctrl+O` instead of claiming that a chat reply can grant permission.
366
+ `model.args` and `model.env` apply to both automated worker runs and embedded native attach sessions. Native attach appends the rendered model arguments after `interactive.args`, so third-party `{model}` and `{provider}` selections remain active when you press `Ctrl+O`. Codex Router and non-interactive Codex Workers use the root option `-a never` before `exec`, so they cannot stall on an approval UI the outer TUI cannot deliver; Router remains `read-only`, while coding Workers stay inside `workspace-write`. Isolated Codex roles remove broader bypass flags and replace any configured approval mode with this bounded policy. The dangerous `--dangerously-bypass-approvals-and-sandbox` mode is never required. Native Codex attach remains interactive. Claude Main uses `auto` so safe tool calls can complete in print mode; isolated Claude coding roles are still clamped to `acceptEdits`. When a command genuinely needs interactive approval, Main points to `Ctrl+O` instead of claiming that a chat reply can grant permission.
367
367
 
368
368
  `model.provider` names the remote model service; `capabilities.profile` describes the local CLI protocol. Worker Provider IDs are lowercase names using letters, digits, or `_`; excluding `-` keeps generated Worker directory names unambiguous. Existing `codex`, `claude`, and `mock` IDs remain compatible, while additional profiles can inherit `codex`, `claude`, another named profile, or conservative `generic` defaults.
369
369
 
@@ -516,12 +516,12 @@ The release job installs npm `^11.5.1`, runs on Node `24.15.x`, publishes the pr
516
516
  To publish a release, update `package.json` and `src/version.ts` to the same version, then push a matching tag:
517
517
 
518
518
  ```bash
519
- VERSION=0.2.3
519
+ VERSION=0.2.4
520
520
  git tag "v$VERSION"
521
521
  git push origin "v$VERSION"
522
522
  ```
523
523
 
524
- You can also run the Release workflow manually and enter the same tag value. The release tag must match `package.json`; for example, package version `0.2.3` requires tag `v0.2.3`. Published tags such as `v0.2.2` are immutable and must not be moved or reused.
524
+ You can also run the Release workflow manually and enter the same tag value. The release tag must match `package.json`; for example, package version `0.2.4` requires tag `v0.2.4`. Published tags such as `v0.2.3` are immutable and must not be moved or reused.
525
525
 
526
526
  ## Publishing Hygiene
527
527
 
@@ -153,6 +153,8 @@ export function defaultConfig(projectRoot) {
153
153
  codex: {
154
154
  command: "codex",
155
155
  args: [
156
+ "-a",
157
+ "never",
156
158
  "exec",
157
159
  "--ephemeral",
158
160
  "--ignore-rules",
@@ -184,7 +186,7 @@ export function defaultConfig(projectRoot) {
184
186
  workers: {
185
187
  codex: {
186
188
  command: "codex",
187
- args: ["exec", "--skip-git-repo-check", "--sandbox", "workspace-write", "--color", "never", "-"],
189
+ args: ["-a", "never", "exec", "--skip-git-repo-check", "--sandbox", "workspace-write", "--color", "never", "-"],
188
190
  assignable: true,
189
191
  timeoutMs: 45 * 60 * 1000,
190
192
  idleTimeoutMs: 5 * 60 * 1000,
@@ -202,7 +204,7 @@ export function defaultConfig(projectRoot) {
202
204
  },
203
205
  nativeSession: {
204
206
  enabled: true,
205
- resumeArgs: ["exec", "resume", "{sessionId}", "--skip-git-repo-check", "-"],
207
+ resumeArgs: ["-a", "never", "exec", "resume", "{sessionId}", "--skip-git-repo-check", "-"],
206
208
  detectSessionId: true,
207
209
  fallback: "new"
208
210
  },
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = "0.2.3";
1
+ export const version = "0.2.4";
@@ -114,6 +114,12 @@ function capabilityProbeSpecs(target) {
114
114
  }
115
115
  const specs = [];
116
116
  if (target.surfaces.has("automated")) {
117
+ specs.push({
118
+ args: ["--help"],
119
+ label: "approval policy",
120
+ requiredOptions: ["--ask-for-approval"],
121
+ usagePattern: /Usage:\s+codex\b/i
122
+ });
117
123
  specs.push({
118
124
  args: ["exec", "--help"],
119
125
  label: "exec sandbox/add-dir",
@@ -552,6 +552,13 @@ function enforceCodexWorkspaceSandbox(args) {
552
552
  if (arg === "--dangerously-bypass-approvals-and-sandbox") {
553
553
  continue;
554
554
  }
555
+ if (arg === "-a" || arg === "--ask-for-approval") {
556
+ index += 1;
557
+ continue;
558
+ }
559
+ if (arg.startsWith("-a=") || arg.startsWith("--ask-for-approval=")) {
560
+ continue;
561
+ }
555
562
  if (arg === "--sandbox" || arg === "-s") {
556
563
  result.push(arg, "workspace-write");
557
564
  hasSandbox = true;
@@ -565,10 +572,16 @@ function enforceCodexWorkspaceSandbox(args) {
565
572
  }
566
573
  result.push(arg);
567
574
  }
575
+ const execIndex = result.indexOf("exec");
576
+ if (execIndex >= 0) {
577
+ result.splice(execIndex, 0, "-a", "never");
578
+ }
568
579
  if (!hasSandbox) {
569
- const execIndex = result.indexOf("exec");
580
+ const normalizedExecIndex = result.indexOf("exec");
570
581
  const promptIndex = result.lastIndexOf("-");
571
- const insertAt = execIndex >= 0 ? execIndex + 1 : promptIndex >= 0 ? promptIndex : result.length;
582
+ const insertAt = normalizedExecIndex >= 0
583
+ ? normalizedExecIndex + 1
584
+ : promptIndex >= 0 ? promptIndex : result.length;
572
585
  result.splice(insertAt, 0, "--sandbox", "workspace-write");
573
586
  }
574
587
  return result;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "parallel-codex-tui",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "A TypeScript TUI wrapper for routed parallel coding with Codex and Claude workers.",
5
5
  "license": "MIT",
6
6
  "type": "module",