patchwork-os 1.1.0-beta.4.canary.441 → 1.1.0-beta.4.canary.442

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.
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Shape of a parsed NDJSON event from `codex exec --json`.
3
+ *
4
+ * Event types confirmed via OpenAI's developer docs (developers.openai.com/
5
+ * codex/noninteractive, redirects to learn.chatgpt.com/docs/non-interactive-mode):
6
+ * thread.started, turn.started, turn.completed, turn.failed, item.started,
7
+ * item.completed, error. The final agent response text lives in an
8
+ * item.completed event whose item.type === "agent_message" — NOT at the
9
+ * top level of the event, unlike Claude's stream-json "result" event.
10
+ *
11
+ * The exact field shape of the `error` and `turn.failed` event types is not
12
+ * documented on the pages fetched — parseStreamLine defensively checks a few
13
+ * plausible field names (`message`, `error`) for both and falls back to
14
+ * stringifying the event so an error is never silently dropped even if the
15
+ * real field name differs.
16
+ */
17
+ export interface CodexEvent {
18
+ type: "thread.started" | "turn.started" | "turn.completed" | "turn.failed" | "item.started" | "item.completed" | "error" | string;
19
+ /** Present on type === "thread.started". */
20
+ thread_id?: string;
21
+ /** Present on type === "turn.completed". */
22
+ usage?: {
23
+ input_tokens?: number;
24
+ cached_input_tokens?: number;
25
+ output_tokens?: number;
26
+ reasoning_output_tokens?: number;
27
+ };
28
+ /** Present on type === "item.started" / "item.completed". */
29
+ item?: {
30
+ id?: string;
31
+ type?: string;
32
+ command?: string;
33
+ status?: string;
34
+ /** Present when item.type === "agent_message" on a completed item. */
35
+ text?: string;
36
+ };
37
+ /** Field name unconfirmed for type === "error" — checked defensively. */
38
+ message?: string;
39
+ error?: string;
40
+ }
41
+ export interface ParsedLine {
42
+ kind: "event";
43
+ event: CodexEvent;
44
+ /** Extracted response/error text for this event, "" if the event carries none. */
45
+ text: string;
46
+ }
47
+ export interface RawLine {
48
+ kind: "raw";
49
+ text: string;
50
+ }
51
+ export type ParsedStreamLine = ParsedLine | RawLine;
52
+ /**
53
+ * Parse a single NDJSON line from `codex exec --json`. Returns a raw line
54
+ * entry for non-JSON lines (defensive — mirrors the Claude parser's
55
+ * backward-compat handling for unexpected output).
56
+ */
57
+ export declare function parseStreamLine(line: string): ParsedStreamLine;
58
+ /** Split a chunk into complete lines + a leftover partial. Identical logic to
59
+ * the Claude driver's splitLines (pure, format-agnostic) — kept as a local
60
+ * copy rather than a cross-driver import so codex/ has no dependency on
61
+ * claude/ internals. */
62
+ export declare function splitLines(buf: string, chunk: string): {
63
+ lines: string[];
64
+ remainder: string;
65
+ };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Parse a single NDJSON line from `codex exec --json`. Returns a raw line
3
+ * entry for non-JSON lines (defensive — mirrors the Claude parser's
4
+ * backward-compat handling for unexpected output).
5
+ */
6
+ export function parseStreamLine(line) {
7
+ try {
8
+ const event = JSON.parse(line);
9
+ let text = "";
10
+ if (event.type === "item.completed" &&
11
+ event.item?.type === "agent_message") {
12
+ text = typeof event.item.text === "string" ? event.item.text : "";
13
+ }
14
+ else if (event.type === "error" || event.type === "turn.failed") {
15
+ text =
16
+ typeof event.message === "string"
17
+ ? event.message
18
+ : typeof event.error === "string"
19
+ ? event.error
20
+ : JSON.stringify(event);
21
+ }
22
+ return { kind: "event", event, text };
23
+ }
24
+ catch {
25
+ return { kind: "raw", text: `${line}\n` };
26
+ }
27
+ }
28
+ /** Split a chunk into complete lines + a leftover partial. Identical logic to
29
+ * the Claude driver's splitLines (pure, format-agnostic) — kept as a local
30
+ * copy rather than a cross-driver import so codex/ has no dependency on
31
+ * claude/ internals. */
32
+ export function splitLines(buf, chunk) {
33
+ const combined = buf + chunk;
34
+ const parts = combined.split("\n");
35
+ const remainder = parts.pop() ?? "";
36
+ return { lines: parts, remainder };
37
+ }
38
+ //# sourceMappingURL=streamParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streamParser.js","sourceRoot":"","sources":["../../../src/drivers/codex/streamParser.ts"],"names":[],"mappings":"AA+DA;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;QAC7C,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IACE,KAAK,CAAC,IAAI,KAAK,gBAAgB;YAC/B,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,eAAe,EACpC,CAAC;YACD,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAClE,IAAI;gBACF,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;oBAC/B,CAAC,CAAC,KAAK,CAAC,OAAO;oBACf,CAAC,CAAC,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;wBAC/B,CAAC,CAAC,KAAK,CAAC,KAAK;wBACb,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;wBAGwB;AACxB,MAAM,UAAU,UAAU,CACxB,GAAW,EACX,KAAa;IAEb,MAAM,QAAQ,GAAG,GAAG,GAAG,KAAK,CAAC;IAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IACpC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { ProviderDriver, ProviderTaskInput, ProviderTaskResult } from "../types.js";
2
+ /**
3
+ * Scrub secrets from a string before storing or surfacing it. Same patterns
4
+ * as the Claude driver's scrubSecrets, plus an OpenAI-shaped API key pattern
5
+ * (sk-proj-.../sk-...) in case a user has OPENAI_API_KEY-based auth rather
6
+ * than the default ChatGPT-subscription login.
7
+ */
8
+ export declare function scrubSecrets(text: string): string;
9
+ /**
10
+ * Codex subprocess driver — spawns `codex exec` with ChatGPT-subscription
11
+ * auth (whatever `codex login` already established; no API key handling
12
+ * here, mirroring how the Claude subprocess driver relies on `claude`'s own
13
+ * stored subscription auth rather than passing a credential itself).
14
+ *
15
+ * FAIL-CLOSED BY DEFAULT — this is a deliberate divergence from the Claude
16
+ * subprocess driver, whose default (no sandbox opt-in) is
17
+ * `--dangerously-skip-permissions` (fail-OPEN: full native tool access).
18
+ * Codex CLI's own non-interactive docs explicitly warn that `codex exec`
19
+ * does NOT default to something safe for unattended callers — every
20
+ * restrictive flag below is passed unconditionally unless a caller
21
+ * explicitly escalates via providerOptions:
22
+ *
23
+ * sandboxMode: "read-only" (default) | "workspace-write" | "danger-full-access"
24
+ * approvalMode: "never" (default) | "on-request" | "untrusted"
25
+ * networkAccess: false (default) — passed as `-c sandbox.network_access=false`
26
+ * webSearch: false (default) — omitting --search leaves Codex's own
27
+ * default ("cached"); NOT the same as fully disabled, but
28
+ * there is no documented flag to disable it outright as of
29
+ * this writing. Flagged here rather than silently assumed.
30
+ *
31
+ * Codex CLI's own cancellation has confirmed upstream bugs (orphaned MCP
32
+ * stdio subprocesses, shell-wrapper children surviving interrupt — see
33
+ * openai/codex issues #4337, #7985, #12491, #15379, #20869) — treeKill
34
+ * (process-group kill, not a direct-child-only kill()) is used from the
35
+ * start, not added later.
36
+ */
37
+ export declare class CodexDriver implements ProviderDriver {
38
+ private readonly binary;
39
+ private readonly log;
40
+ readonly name = "codex";
41
+ constructor(binary: string, log: (msg: string) => void);
42
+ run(input: ProviderTaskInput): Promise<ProviderTaskResult>;
43
+ runOutcome(input: ProviderTaskInput): Promise<import("../types.js").ProviderTaskOutcome>;
44
+ }
@@ -0,0 +1,261 @@
1
+ import { spawn } from "node:child_process";
2
+ import { treeKill } from "../../processTree.js";
3
+ import { ensureCmdShim } from "../../winShim.js";
4
+ import { sanitizeEnv } from "../claude/envSanitizer.js";
5
+ import { truncateToBytes, truncateUtf8Bytes } from "../outputCap.js";
6
+ import { toProviderTaskOutcome } from "../types.js";
7
+ import { parseStreamLine, splitLines } from "./streamParser.js";
8
+ const OUTPUT_CAP = 50 * 1024; // 50KB — matches the Claude subprocess driver's cap
9
+ /**
10
+ * Scrub secrets from a string before storing or surfacing it. Same patterns
11
+ * as the Claude driver's scrubSecrets, plus an OpenAI-shaped API key pattern
12
+ * (sk-proj-.../sk-...) in case a user has OPENAI_API_KEY-based auth rather
13
+ * than the default ChatGPT-subscription login.
14
+ */
15
+ export function scrubSecrets(text) {
16
+ return text
17
+ .replace(/sk-(proj-)?[A-Za-z0-9_-]{20,}/g, "[REDACTED_API_KEY]")
18
+ .replace(/Bearer\s+[A-Za-z0-9._-]{16,}/gi, "Bearer [REDACTED]")
19
+ .replace(/\btoken[=:]\s*[A-Za-z0-9._-]{16,}/gi, "token=[REDACTED]");
20
+ }
21
+ /**
22
+ * Codex subprocess driver — spawns `codex exec` with ChatGPT-subscription
23
+ * auth (whatever `codex login` already established; no API key handling
24
+ * here, mirroring how the Claude subprocess driver relies on `claude`'s own
25
+ * stored subscription auth rather than passing a credential itself).
26
+ *
27
+ * FAIL-CLOSED BY DEFAULT — this is a deliberate divergence from the Claude
28
+ * subprocess driver, whose default (no sandbox opt-in) is
29
+ * `--dangerously-skip-permissions` (fail-OPEN: full native tool access).
30
+ * Codex CLI's own non-interactive docs explicitly warn that `codex exec`
31
+ * does NOT default to something safe for unattended callers — every
32
+ * restrictive flag below is passed unconditionally unless a caller
33
+ * explicitly escalates via providerOptions:
34
+ *
35
+ * sandboxMode: "read-only" (default) | "workspace-write" | "danger-full-access"
36
+ * approvalMode: "never" (default) | "on-request" | "untrusted"
37
+ * networkAccess: false (default) — passed as `-c sandbox.network_access=false`
38
+ * webSearch: false (default) — omitting --search leaves Codex's own
39
+ * default ("cached"); NOT the same as fully disabled, but
40
+ * there is no documented flag to disable it outright as of
41
+ * this writing. Flagged here rather than silently assumed.
42
+ *
43
+ * Codex CLI's own cancellation has confirmed upstream bugs (orphaned MCP
44
+ * stdio subprocesses, shell-wrapper children surviving interrupt — see
45
+ * openai/codex issues #4337, #7985, #12491, #15379, #20869) — treeKill
46
+ * (process-group kill, not a direct-child-only kill()) is used from the
47
+ * start, not added later.
48
+ */
49
+ export class CodexDriver {
50
+ binary;
51
+ log;
52
+ name = "codex";
53
+ constructor(binary, log) {
54
+ this.binary = binary;
55
+ this.log = log;
56
+ }
57
+ async run(input) {
58
+ const opts = input.providerOptions ?? {};
59
+ // Defense-in-depth: reject argv-confusable user-controlled strings.
60
+ // Spawn is called with an array (no shell), so this is argv defense for
61
+ // the child's flag parser, not shell-injection defense. Mirrors the
62
+ // Claude driver's identical guard.
63
+ if (input.prompt.startsWith("-")) {
64
+ throw new Error("[CodexDriver] prompt cannot start with '-' (argv injection guard)");
65
+ }
66
+ const effectiveBinary = ensureCmdShim(this.binary);
67
+ const sandboxMode = opts.sandboxMode === "workspace-write" ||
68
+ opts.sandboxMode === "danger-full-access"
69
+ ? opts.sandboxMode
70
+ : "read-only";
71
+ const approvalMode = opts.approvalMode === "on-request" || opts.approvalMode === "untrusted"
72
+ ? opts.approvalMode
73
+ : "never";
74
+ const networkAccess = opts.networkAccess === true;
75
+ const webSearch = opts.webSearch === true;
76
+ const args = [
77
+ "exec",
78
+ input.prompt,
79
+ "--json",
80
+ "--sandbox",
81
+ sandboxMode,
82
+ "--ask-for-approval",
83
+ approvalMode,
84
+ "--ignore-user-config",
85
+ "--ignore-rules",
86
+ "--skip-git-repo-check",
87
+ "--ephemeral",
88
+ "-c",
89
+ `sandbox.network_access=${networkAccess ? "true" : "false"}`,
90
+ ];
91
+ if (webSearch)
92
+ args.push("--search");
93
+ // env sanitization: reuse the Claude driver's sanitizeEnv as-is (a
94
+ // generic cross-provider-secret strip with no Claude-specific coupling —
95
+ // see envSanitizer.ts's own doc comment). Codex's subscription auth
96
+ // lives in codex's own config/auth file, not an env var, so no
97
+ // `preserve` entry is needed for the default (subscription) auth path.
98
+ const env = sanitizeEnv(process.env);
99
+ this.log(`[CodexDriver] spawning: ${effectiveBinary} exec <prompt> (workspace: ${input.workspace}, sandbox: ${sandboxMode})`);
100
+ const child = spawn(effectiveBinary, args, {
101
+ cwd: input.workspace,
102
+ env,
103
+ signal: input.signal,
104
+ stdio: ["ignore", "pipe", "pipe"],
105
+ // setsid() — prevents subprocess from opening /dev/tty for interactive
106
+ // prompts, and makes it its own process-group leader for treeKill.
107
+ detached: true,
108
+ });
109
+ // Node's `signal` option calls `child.kill()` on abort, which only
110
+ // signals the immediate child — insufficient given Codex's confirmed
111
+ // upstream orphaned-child-process bugs (see class doc comment).
112
+ const onAbort = () => treeKill(child);
113
+ input.signal.addEventListener("abort", onAbort, { once: true });
114
+ child.once("close", () => {
115
+ input.signal.removeEventListener("abort", onAbort);
116
+ });
117
+ let lineBuf = "";
118
+ let accumulated = "";
119
+ let outputBytesSent = 0;
120
+ let firstAgentMessageAt;
121
+ let sawError = false;
122
+ let errorText = "";
123
+ let resultUsage;
124
+ const emitText = (text) => {
125
+ if (text.length === 0)
126
+ return;
127
+ accumulated += text;
128
+ if (outputBytesSent < OUTPUT_CAP) {
129
+ const { send, bytes } = truncateToBytes(text, OUTPUT_CAP - outputBytesSent);
130
+ if (bytes > 0) {
131
+ input.onChunk?.(send);
132
+ outputBytesSent += bytes;
133
+ }
134
+ }
135
+ };
136
+ const handleLine = (line) => {
137
+ if (line.trim() === "")
138
+ return;
139
+ const parsed = parseStreamLine(line);
140
+ if (parsed.kind === "raw") {
141
+ emitText(parsed.text);
142
+ return;
143
+ }
144
+ const { event, text } = parsed;
145
+ if (event.type === "item.completed" &&
146
+ event.item?.type === "agent_message") {
147
+ if (firstAgentMessageAt === undefined)
148
+ firstAgentMessageAt = Date.now();
149
+ emitText(text);
150
+ }
151
+ else if (event.type === "turn.completed") {
152
+ resultUsage = event.usage;
153
+ }
154
+ else if (event.type === "error" || event.type === "turn.failed") {
155
+ sawError = true;
156
+ errorText = text || errorText;
157
+ }
158
+ };
159
+ child.stdout.setEncoding("utf-8");
160
+ child.stdout.on("data", (chunk) => {
161
+ const { lines, remainder } = splitLines(lineBuf, chunk);
162
+ lineBuf = remainder;
163
+ for (const line of lines)
164
+ handleLine(line);
165
+ });
166
+ let stderr = "";
167
+ child.stderr.setEncoding("utf-8");
168
+ child.stderr.on("data", (chunk) => {
169
+ if (Buffer.byteLength(stderr, "utf8") < OUTPUT_CAP) {
170
+ stderr += chunk;
171
+ if (Buffer.byteLength(stderr, "utf8") > OUTPUT_CAP) {
172
+ stderr = truncateUtf8Bytes(stderr, OUTPUT_CAP);
173
+ }
174
+ }
175
+ });
176
+ const start = Date.now();
177
+ const stderrTailOf = (s) => s.length > 0 ? scrubSecrets(s.slice(-2048)) : undefined;
178
+ const startupMsOf = () => firstAgentMessageAt !== undefined
179
+ ? firstAgentMessageAt - start
180
+ : undefined;
181
+ let startupTimedOut = false;
182
+ const startupHandle = input.startupTimeoutMs
183
+ ? setTimeout(() => {
184
+ if (firstAgentMessageAt === undefined) {
185
+ startupTimedOut = true;
186
+ treeKill(child);
187
+ }
188
+ }, input.startupTimeoutMs)
189
+ : null;
190
+ let exitCode;
191
+ try {
192
+ exitCode = await new Promise((resolve, reject) => {
193
+ child.on("close", (code) => resolve(code ?? 0));
194
+ child.on("error", reject);
195
+ });
196
+ }
197
+ catch (err) {
198
+ if (startupHandle)
199
+ clearTimeout(startupHandle);
200
+ const isAbort = (err instanceof Error && err.name === "AbortError") ||
201
+ input.signal.aborted;
202
+ if (isAbort) {
203
+ return {
204
+ text: truncateUtf8Bytes(accumulated, OUTPUT_CAP),
205
+ exitCode: -1,
206
+ durationMs: Date.now() - start,
207
+ stderrTail: stderrTailOf(stderr),
208
+ wasAborted: true,
209
+ startupMs: startupMsOf(),
210
+ };
211
+ }
212
+ throw err;
213
+ }
214
+ if (startupHandle)
215
+ clearTimeout(startupHandle);
216
+ // Flush any partial line remaining in lineBuf after stdout closes —
217
+ // mirrors the Claude driver's identical flush-on-close handling.
218
+ if (lineBuf.trim().length > 0) {
219
+ handleLine(lineBuf);
220
+ lineBuf = "";
221
+ }
222
+ if (startupTimedOut) {
223
+ return {
224
+ text: truncateUtf8Bytes(accumulated, OUTPUT_CAP),
225
+ exitCode: -1,
226
+ durationMs: Date.now() - start,
227
+ stderrTail: stderrTailOf(stderr),
228
+ wasAborted: true,
229
+ startupTimedOut: true,
230
+ };
231
+ }
232
+ const effectiveExitCode = sawError ? 1 : exitCode;
233
+ if (effectiveExitCode !== 0 && stderr) {
234
+ this.log(`[CodexDriver] stderr: ${stderr.slice(0, 500)}`);
235
+ }
236
+ const providerMeta = {};
237
+ if (typeof resultUsage?.input_tokens === "number" &&
238
+ typeof resultUsage?.output_tokens === "number") {
239
+ providerMeta.inputTokens = resultUsage.input_tokens;
240
+ providerMeta.outputTokens = resultUsage.output_tokens;
241
+ }
242
+ if (input.model && !input.model.startsWith("-")) {
243
+ providerMeta.model = input.model;
244
+ }
245
+ return {
246
+ text: truncateUtf8Bytes(sawError && accumulated.length === 0 ? errorText : accumulated, OUTPUT_CAP),
247
+ exitCode: effectiveExitCode,
248
+ errorMessage: sawError
249
+ ? errorText || "codex exec reported an error"
250
+ : undefined,
251
+ durationMs: Date.now() - start,
252
+ stderrTail: stderrTailOf(stderr),
253
+ startupMs: startupMsOf(),
254
+ providerMeta: Object.keys(providerMeta).length > 0 ? providerMeta : undefined,
255
+ };
256
+ }
257
+ async runOutcome(input) {
258
+ return toProviderTaskOutcome(await this.run(input));
259
+ }
260
+ }
261
+ //# sourceMappingURL=subprocess.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subprocess.js","sourceRoot":"","sources":["../../../src/drivers/codex/subprocess.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchwork-os",
3
- "version": "1.1.0-beta.4.canary.441",
3
+ "version": "1.1.0-beta.4.canary.442",
4
4
  "description": "Your personal AI runtime, local-first. Patchwork OS gives any AI model a consistent set of tools, YAML recipes, a delegation policy with approval queue, and a durable trace memory — all on your machine, all under your policy.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",