@parall/codex-agent 1.18.2 → 1.19.0

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.
package/dist/config.d.ts CHANGED
@@ -10,7 +10,21 @@ export type CodexAgentConfig = {
10
10
  workspaceDir: string;
11
11
  model?: string;
12
12
  reasoningEffort?: string;
13
- sandbox: string;
13
+ /**
14
+ * Only set when the user explicitly specified `PRLL_CODEX_SANDBOX`.
15
+ * When undefined, the bridge deliberately does NOT pass `sandbox` on
16
+ * `thread/{start,resume}` so codex reads whatever the user configured
17
+ * in `~/.codex/config.toml` (`sandbox_mode`). This matches the self-
18
+ * hosted philosophy: user's codex setup is authoritative; bridge only
19
+ * overrides when the user asks it to.
20
+ */
21
+ sandbox?: string;
22
+ /**
23
+ * Approval policy is forced to `"never"` by default (not configurable
24
+ * via config.toml override): Parall's HITL contract routes approvals
25
+ * through the app, not codex's own stdin-prompt mechanism, which the
26
+ * long-running app-server subprocess has no way to answer.
27
+ */
14
28
  approvalPolicy: string;
15
29
  runtimeKey?: string;
16
30
  };
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAcF,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,gBAAgB,CA6B9F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAMlG;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAG3F;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGrF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAcF,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,gBAAgB,CAwC9F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAMlG;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAG3F;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGrF"}
package/dist/config.js CHANGED
@@ -14,11 +14,20 @@ export function resolveCodexAgentConfig(env = process.env) {
14
14
  const apiUrl = requireEnv(env, "PRLL_API_URL");
15
15
  const apiKey = requireEnv(env, "PRLL_API_KEY");
16
16
  const orgId = requireEnv(env, "PRLL_ORG_ID");
17
+ // CODEX_HOME is where codex looks for `auth.json` / `config.toml`. Its
18
+ // own default is `$HOME/.codex`; falling back to `$HOME` here was wrong
19
+ // — it made the spawned app-server subprocess look for
20
+ // `$HOME/auth.json`, which silently doesn't exist, so every
21
+ // `thread/start` failed with `401 Unauthorized` against the OpenAI
22
+ // WebSocket endpoint. Default to `$HOME/.codex` so `codex login`'s
23
+ // credentials are picked up transparently.
17
24
  const codexHome = resolvePath(env.PRLL_CODEX_HOME?.trim()
18
25
  || env.CODEX_HOME?.trim()
19
- || env.HOME
20
- || os.homedir());
21
- const stateDir = resolvePath(env.PRLL_CODEX_STATE_DIR?.trim() || path.join(codexHome, ".parall-agent"));
26
+ || path.join(env.HOME || os.homedir(), ".codex"));
27
+ // Bridge state lives outside CODEX_HOME to avoid polluting codex's own
28
+ // directory with non-codex files.
29
+ const stateDir = resolvePath(env.PRLL_CODEX_STATE_DIR?.trim()
30
+ || path.join(env.HOME || os.homedir(), ".parall-agent"));
22
31
  const workspaceDir = resolvePath(env.PRLL_CODEX_WORKSPACE_DIR?.trim() || path.join(stateDir, "workspace"));
23
32
  return {
24
33
  apiUrl,
@@ -32,7 +41,7 @@ export function resolveCodexAgentConfig(env = process.env) {
32
41
  workspaceDir,
33
42
  model: env.PRLL_CODEX_MODEL?.trim() || undefined,
34
43
  reasoningEffort: env.PRLL_CODEX_REASONING_EFFORT?.trim() || undefined,
35
- sandbox: env.PRLL_CODEX_SANDBOX?.trim() || "workspace-write",
44
+ sandbox: env.PRLL_CODEX_SANDBOX?.trim() || undefined,
36
45
  approvalPolicy: env.PRLL_CODEX_APPROVAL?.trim() || "never",
37
46
  runtimeKey: env.PRLL_CODEX_RUNTIME_KEY?.trim() || undefined,
38
47
  };
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,aAAa,EACb,YAAY,EACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,KAAK,4BAA4B,GAAG,IAAI,CACtC,gBAAgB,EACd,gBAAgB,GAChB,UAAU,GACV,WAAW,GACX,OAAO,GACP,iBAAiB,GACjB,SAAS,GACT,cAAc,CACjB,GAAG;IACF,cAAc,EAAE,mBAAmB,CAAC;IACpC,GAAG,CAAC,EAAE,aAAa,CAAC;CACrB,CAAC;AAOF;;;;;;;;;;;;;GAaG;AACH,qBAAa,qBAAsB,YAAW,eAAe;IA6B/C,OAAO,CAAC,QAAQ,CAAC,IAAI;IA5BjC,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,IAAI,CAA+C;IAC3D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;gBAYQ,IAAI,EAAE,4BAA4B;IAExD,QAAQ,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC;IA0J3F,WAAW,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAuBhG,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe;IAIrC,OAAO,CAAC,cAAc;IAKhB,IAAI;YAaI,aAAa;YAcb,OAAO;IA2DrB,OAAO,CAAC,qBAAqB;YAiCf,UAAU;IAwCxB,OAAO,CAAC,iBAAiB;CA2B1B"}
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,aAAa,EACb,YAAY,EACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,KAAK,4BAA4B,GAAG,IAAI,CACtC,gBAAgB,EACd,gBAAgB,GAChB,UAAU,GACV,WAAW,GACX,OAAO,GACP,iBAAiB,GACjB,SAAS,GACT,cAAc,CACjB,GAAG;IACF,cAAc,EAAE,mBAAmB,CAAC;IACpC,GAAG,CAAC,EAAE,aAAa,CAAC;CACrB,CAAC;AAOF;;;;;;;;;;;;;GAaG;AACH,qBAAa,qBAAsB,YAAW,eAAe;IA6B/C,OAAO,CAAC,QAAQ,CAAC,IAAI;IA5BjC,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,IAAI,CAA+C;IAC3D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;gBAYQ,IAAI,EAAE,4BAA4B;IAExD,QAAQ,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC;IA0J3F,WAAW,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAuBhG,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe;IAIrC,OAAO,CAAC,cAAc;IAKhB,IAAI;YAaI,aAAa;YAcb,OAAO;IA2DrB,OAAO,CAAC,qBAAqB;YAiCf,UAAU;IAgDxB,OAAO,CAAC,iBAAiB;CA2B1B"}
package/dist/dispatch.js CHANGED
@@ -359,8 +359,16 @@ export class CodexAppServerAdapter {
359
359
  // either kebab or camel and we always emit kebab.
360
360
  const commonParams = {
361
361
  approvalPolicy: normalizeApprovalPolicy(this.opts.approvalPolicy),
362
- sandbox: normalizeSandbox(this.opts.sandbox),
363
362
  };
363
+ // Only override sandbox when the user explicitly set PRLL_CODEX_SANDBOX.
364
+ // Otherwise let codex read `sandbox_mode` from ~/.codex/config.toml — the
365
+ // user's own configuration is authoritative for a self-hosted bridge,
366
+ // and codex 0.120.0's workspace-write mode has a write_stdin bug that
367
+ // our previous `workspace-write` default tripped for users whose config
368
+ // had danger-full-access.
369
+ if (this.opts.sandbox) {
370
+ commonParams.sandbox = normalizeSandbox(this.opts.sandbox);
371
+ }
364
372
  if (this.opts.model)
365
373
  commonParams.model = this.opts.model;
366
374
  if (this.opts.reasoningEffort) {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import * as os from "node:os";
3
- import { ParallAgentGateway } from "@parall/agent-core";
3
+ import { ParallAgentGateway, parseShutdownDeadlineMs } from "@parall/agent-core";
4
4
  import { ParallClient, ParallWs } from "@parall/sdk";
5
5
  import { buildCodexRuntimeKey, resolveCodexAgentConfig, resolveWsUrl, sessionStateFilePathForRuntime, stepIdFilePathForSession, } from "./config.js";
6
6
  import { CodexAppServerAdapter } from "./dispatch.js";
@@ -65,6 +65,7 @@ async function main() {
65
65
  },
66
66
  dispatchAdapter: adapter,
67
67
  log,
68
+ shutdownDeadlineMs: parseShutdownDeadlineMs(process.env.PRLL_SHUTDOWN_DEADLINE_MS),
68
69
  stepIdFilePathForSession: (sessionKey) => stepIdFilePathForSession(config.stateDir, sessionKey),
69
70
  });
70
71
  const abortController = new AbortController();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/codex-agent",
3
- "version": "1.18.2",
3
+ "version": "1.19.0",
4
4
  "description": "Codex CLI bridge runtime for self-hosted Parall agents",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -25,9 +25,9 @@
25
25
  "src"
26
26
  ],
27
27
  "dependencies": {
28
- "@parall/agent-core": "1.18.1",
29
- "@parall/cli": "1.18.0",
30
- "@parall/sdk": "1.18.0"
28
+ "@parall/agent-core": "1.19.0",
29
+ "@parall/sdk": "1.19.0",
30
+ "@parall/cli": "1.19.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^22.0.0",
package/src/config.ts CHANGED
@@ -13,7 +13,21 @@ export type CodexAgentConfig = {
13
13
  workspaceDir: string;
14
14
  model?: string;
15
15
  reasoningEffort?: string;
16
- sandbox: string;
16
+ /**
17
+ * Only set when the user explicitly specified `PRLL_CODEX_SANDBOX`.
18
+ * When undefined, the bridge deliberately does NOT pass `sandbox` on
19
+ * `thread/{start,resume}` so codex reads whatever the user configured
20
+ * in `~/.codex/config.toml` (`sandbox_mode`). This matches the self-
21
+ * hosted philosophy: user's codex setup is authoritative; bridge only
22
+ * overrides when the user asks it to.
23
+ */
24
+ sandbox?: string;
25
+ /**
26
+ * Approval policy is forced to `"never"` by default (not configurable
27
+ * via config.toml override): Parall's HITL contract routes approvals
28
+ * through the app, not codex's own stdin-prompt mechanism, which the
29
+ * long-running app-server subprocess has no way to answer.
30
+ */
17
31
  approvalPolicy: string;
18
32
  runtimeKey?: string;
19
33
  };
@@ -34,13 +48,24 @@ export function resolveCodexAgentConfig(env: NodeJS.ProcessEnv = process.env): C
34
48
  const apiUrl = requireEnv(env, "PRLL_API_URL");
35
49
  const apiKey = requireEnv(env, "PRLL_API_KEY");
36
50
  const orgId = requireEnv(env, "PRLL_ORG_ID");
51
+ // CODEX_HOME is where codex looks for `auth.json` / `config.toml`. Its
52
+ // own default is `$HOME/.codex`; falling back to `$HOME` here was wrong
53
+ // — it made the spawned app-server subprocess look for
54
+ // `$HOME/auth.json`, which silently doesn't exist, so every
55
+ // `thread/start` failed with `401 Unauthorized` against the OpenAI
56
+ // WebSocket endpoint. Default to `$HOME/.codex` so `codex login`'s
57
+ // credentials are picked up transparently.
37
58
  const codexHome = resolvePath(
38
59
  env.PRLL_CODEX_HOME?.trim()
39
60
  || env.CODEX_HOME?.trim()
40
- || env.HOME
41
- || os.homedir(),
61
+ || path.join(env.HOME || os.homedir(), ".codex"),
62
+ );
63
+ // Bridge state lives outside CODEX_HOME to avoid polluting codex's own
64
+ // directory with non-codex files.
65
+ const stateDir = resolvePath(
66
+ env.PRLL_CODEX_STATE_DIR?.trim()
67
+ || path.join(env.HOME || os.homedir(), ".parall-agent"),
42
68
  );
43
- const stateDir = resolvePath(env.PRLL_CODEX_STATE_DIR?.trim() || path.join(codexHome, ".parall-agent"));
44
69
  const workspaceDir = resolvePath(env.PRLL_CODEX_WORKSPACE_DIR?.trim() || path.join(stateDir, "workspace"));
45
70
 
46
71
  return {
@@ -55,7 +80,7 @@ export function resolveCodexAgentConfig(env: NodeJS.ProcessEnv = process.env): C
55
80
  workspaceDir,
56
81
  model: env.PRLL_CODEX_MODEL?.trim() || undefined,
57
82
  reasoningEffort: env.PRLL_CODEX_REASONING_EFFORT?.trim() || undefined,
58
- sandbox: env.PRLL_CODEX_SANDBOX?.trim() || "workspace-write",
83
+ sandbox: env.PRLL_CODEX_SANDBOX?.trim() || undefined,
59
84
  approvalPolicy: env.PRLL_CODEX_APPROVAL?.trim() || "never",
60
85
  runtimeKey: env.PRLL_CODEX_RUNTIME_KEY?.trim() || undefined,
61
86
  };
package/src/dispatch.ts CHANGED
@@ -402,8 +402,16 @@ export class CodexAppServerAdapter implements DispatchAdapter {
402
402
  // either kebab or camel and we always emit kebab.
403
403
  const commonParams: Record<string, unknown> = {
404
404
  approvalPolicy: normalizeApprovalPolicy(this.opts.approvalPolicy),
405
- sandbox: normalizeSandbox(this.opts.sandbox),
406
405
  };
406
+ // Only override sandbox when the user explicitly set PRLL_CODEX_SANDBOX.
407
+ // Otherwise let codex read `sandbox_mode` from ~/.codex/config.toml — the
408
+ // user's own configuration is authoritative for a self-hosted bridge,
409
+ // and codex 0.120.0's workspace-write mode has a write_stdin bug that
410
+ // our previous `workspace-write` default tripped for users whose config
411
+ // had danger-full-access.
412
+ if (this.opts.sandbox) {
413
+ commonParams.sandbox = normalizeSandbox(this.opts.sandbox);
414
+ }
407
415
  if (this.opts.model) commonParams.model = this.opts.model;
408
416
  if (this.opts.reasoningEffort) {
409
417
  // The app-server JSON-RPC surface uses camelCase for overrides —
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import * as os from "node:os";
4
- import { ParallAgentGateway } from "@parall/agent-core";
4
+ import { ParallAgentGateway, parseShutdownDeadlineMs } from "@parall/agent-core";
5
5
  import { ParallClient, ParallWs } from "@parall/sdk";
6
6
  import {
7
7
  buildCodexRuntimeKey,
@@ -83,6 +83,7 @@ async function main() {
83
83
  },
84
84
  dispatchAdapter: adapter,
85
85
  log,
86
+ shutdownDeadlineMs: parseShutdownDeadlineMs(process.env.PRLL_SHUTDOWN_DEADLINE_MS),
86
87
  stepIdFilePathForSession: (sessionKey) => stepIdFilePathForSession(config.stateDir, sessionKey),
87
88
  });
88
89