parallel-codex-tui 0.2.2 → 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
|
-
|
|
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
|
-
#
|
|
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}"]
|
|
@@ -75,8 +77,8 @@ fallback = "new"
|
|
|
75
77
|
|
|
76
78
|
[workers.claude]
|
|
77
79
|
command = "claude"
|
|
78
|
-
#
|
|
79
|
-
args = ["--print", "--permission-mode", "
|
|
80
|
+
# Main uses Claude auto mode for non-interactive tools. Isolated roles are still clamped to acceptEdits.
|
|
81
|
+
args = ["--print", "--permission-mode", "auto", "--output-format", "text"]
|
|
80
82
|
# timeoutMs is the hard ceiling; first output owns silent startup and idle starts after actual output.
|
|
81
83
|
# timeoutMs = 2700000
|
|
82
84
|
# idleTimeoutMs = 300000
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Built with Codex-assisted development.
|
|
|
6
6
|
|
|
7
7
|
## Current Release
|
|
8
8
|
|
|
9
|
-
`v0.2.
|
|
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
|
|
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"
|
|
@@ -350,7 +350,7 @@ forkArgs = ["fork", "{sessionId}"]
|
|
|
350
350
|
|
|
351
351
|
[workers.claude]
|
|
352
352
|
command = "claude"
|
|
353
|
-
args = ["--print", "--permission-mode", "
|
|
353
|
+
args = ["--print", "--permission-mode", "auto", "--output-format", "text"]
|
|
354
354
|
|
|
355
355
|
[workers.claude.capabilities]
|
|
356
356
|
profile = "claude"
|
|
@@ -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`.
|
|
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.
|
|
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.
|
|
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
|
|
package/dist/core/config.js
CHANGED
|
@@ -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
|
},
|
|
@@ -214,7 +216,7 @@ export function defaultConfig(projectRoot) {
|
|
|
214
216
|
},
|
|
215
217
|
claude: {
|
|
216
218
|
command: "claude",
|
|
217
|
-
args: ["--print", "--permission-mode", "
|
|
219
|
+
args: ["--print", "--permission-mode", "auto", "--output-format", "text"],
|
|
218
220
|
assignable: true,
|
|
219
221
|
timeoutMs: 45 * 60 * 1000,
|
|
220
222
|
idleTimeoutMs: 5 * 60 * 1000,
|
|
@@ -232,7 +234,7 @@ export function defaultConfig(projectRoot) {
|
|
|
232
234
|
},
|
|
233
235
|
nativeSession: {
|
|
234
236
|
enabled: true,
|
|
235
|
-
resumeArgs: ["--print", "--resume", "{sessionId}", "--permission-mode", "
|
|
237
|
+
resumeArgs: ["--print", "--resume", "{sessionId}", "--permission-mode", "auto", "--output-format", "text"],
|
|
236
238
|
detectSessionId: true,
|
|
237
239
|
fallback: "new"
|
|
238
240
|
},
|
|
@@ -6,6 +6,13 @@ export function buildMainPrompt(input) {
|
|
|
6
6
|
`# Role: ${role.title}`,
|
|
7
7
|
"",
|
|
8
8
|
...instructionLines(role.instructions),
|
|
9
|
+
"",
|
|
10
|
+
"# Non-interactive execution",
|
|
11
|
+
"",
|
|
12
|
+
"- Use available tools directly when the current permission mode allows them.",
|
|
13
|
+
"- Chat replies cannot grant CLI tool permissions. Never ask the user to approve a command by replying in chat.",
|
|
14
|
+
"- Never claim that a system permission dialog was shown unless a tool result explicitly confirms it.",
|
|
15
|
+
"- If a tool is denied because interactive approval is required, state that it was not run and direct the user to press Ctrl+O to continue in the native agent.",
|
|
9
16
|
...(input.context?.trim()
|
|
10
17
|
? ["", "# Active task context", "", input.context.trim()]
|
|
11
18
|
: []),
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "0.2.
|
|
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
|
|
580
|
+
const normalizedExecIndex = result.indexOf("exec");
|
|
570
581
|
const promptIndex = result.lastIndexOf("-");
|
|
571
|
-
const insertAt =
|
|
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;
|