@mrpatronz/nexusflow 2.6.0 → 2.7.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.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +0 -1
  3. package/dist/agent/ClaudeSdkAdapter.d.ts +18 -0
  4. package/dist/agent/ClaudeSdkAdapter.d.ts.map +1 -0
  5. package/dist/agent/ClaudeSdkAdapter.js +162 -0
  6. package/dist/agent/ClaudeSdkAdapter.js.map +1 -0
  7. package/dist/agent/ClaudeSdkAdapter.test.d.ts +2 -0
  8. package/dist/agent/ClaudeSdkAdapter.test.d.ts.map +1 -0
  9. package/dist/agent/ClaudeSdkAdapter.test.js +143 -0
  10. package/dist/agent/ClaudeSdkAdapter.test.js.map +1 -0
  11. package/dist/agent/CliAdapterBase.d.ts.map +1 -1
  12. package/dist/agent/CliAdapterBase.js +3 -0
  13. package/dist/agent/CliAdapterBase.js.map +1 -1
  14. package/dist/agent/CliAdapterBase.test.js +49 -1
  15. package/dist/agent/CliAdapterBase.test.js.map +1 -1
  16. package/dist/agent/CodexSdkAdapter.d.ts +17 -0
  17. package/dist/agent/CodexSdkAdapter.d.ts.map +1 -0
  18. package/dist/agent/CodexSdkAdapter.js +126 -0
  19. package/dist/agent/CodexSdkAdapter.js.map +1 -0
  20. package/dist/agent/CodexSdkAdapter.test.d.ts +2 -0
  21. package/dist/agent/CodexSdkAdapter.test.d.ts.map +1 -0
  22. package/dist/agent/CodexSdkAdapter.test.js +76 -0
  23. package/dist/agent/CodexSdkAdapter.test.js.map +1 -0
  24. package/dist/agent/ProviderRegistry.d.ts +2 -2
  25. package/dist/agent/ProviderRegistry.d.ts.map +1 -1
  26. package/dist/agent/adapters.d.ts.map +1 -1
  27. package/dist/agent/adapters.js +76 -0
  28. package/dist/agent/adapters.js.map +1 -1
  29. package/dist/core/scheduler.d.ts +1 -0
  30. package/dist/core/scheduler.d.ts.map +1 -1
  31. package/dist/core/scheduler.js +10 -0
  32. package/dist/core/scheduler.js.map +1 -1
  33. package/dist/core/scheduler.test.js +6 -0
  34. package/dist/core/scheduler.test.js.map +1 -1
  35. package/dist/core/workspace.create.test.js +51 -11
  36. package/dist/core/workspace.create.test.js.map +1 -1
  37. package/dist/core/workspace.d.ts.map +1 -1
  38. package/dist/core/workspace.js +123 -84
  39. package/dist/core/workspace.js.map +1 -1
  40. package/dist/harness/claude.d.ts +16 -0
  41. package/dist/harness/claude.d.ts.map +1 -0
  42. package/dist/harness/claude.js +332 -0
  43. package/dist/harness/claude.js.map +1 -0
  44. package/dist/harness/codex.d.ts +18 -0
  45. package/dist/harness/codex.d.ts.map +1 -0
  46. package/dist/harness/codex.js +263 -0
  47. package/dist/harness/codex.js.map +1 -0
  48. package/dist/harness/harness.test.d.ts +2 -0
  49. package/dist/harness/harness.test.d.ts.map +1 -0
  50. package/dist/harness/harness.test.js +200 -0
  51. package/dist/harness/harness.test.js.map +1 -0
  52. package/dist/harness/index.d.ts +10 -0
  53. package/dist/harness/index.d.ts.map +1 -0
  54. package/dist/harness/index.js +13 -0
  55. package/dist/harness/index.js.map +1 -0
  56. package/dist/harness/interface.d.ts +42 -0
  57. package/dist/harness/interface.d.ts.map +1 -0
  58. package/dist/harness/interface.js +17 -0
  59. package/dist/harness/interface.js.map +1 -0
  60. package/dist/harness/pushable.d.ts +11 -0
  61. package/dist/harness/pushable.d.ts.map +1 -0
  62. package/dist/harness/pushable.js +32 -0
  63. package/dist/harness/pushable.js.map +1 -0
  64. package/dist/harness/types.d.ts +126 -0
  65. package/dist/harness/types.d.ts.map +1 -0
  66. package/dist/harness/types.js +12 -0
  67. package/dist/harness/types.js.map +1 -0
  68. package/dist/orchestration/runner.d.ts +1 -1
  69. package/dist/orchestration/runner.d.ts.map +1 -1
  70. package/dist/orchestration/runner.js +29 -14
  71. package/dist/orchestration/runner.js.map +1 -1
  72. package/dist/orchestration/runner.test.js +33 -1
  73. package/dist/orchestration/runner.test.js.map +1 -1
  74. package/dist/server.d.ts.map +1 -1
  75. package/dist/server.js +13 -4
  76. package/dist/server.js.map +1 -1
  77. package/dist/server.test.js +22 -0
  78. package/dist/server.test.js.map +1 -1
  79. package/dist/utils/git.d.ts +0 -15
  80. package/dist/utils/git.d.ts.map +1 -1
  81. package/dist/utils/git.js +4 -0
  82. package/dist/utils/git.js.map +1 -1
  83. package/dist/utils/git.test.js +33 -1
  84. package/dist/utils/git.test.js.map +1 -1
  85. package/dist/utils/multi-git.d.ts +30 -6
  86. package/dist/utils/multi-git.d.ts.map +1 -1
  87. package/dist/utils/multi-git.js +132 -12
  88. package/dist/utils/multi-git.js.map +1 -1
  89. package/dist/utils/multi-git.test.js +153 -1
  90. package/dist/utils/multi-git.test.js.map +1 -1
  91. package/dist/utils/session-finder.d.ts +3 -0
  92. package/dist/utils/session-finder.d.ts.map +1 -1
  93. package/dist/utils/session-finder.js +10 -9
  94. package/dist/utils/session-finder.js.map +1 -1
  95. package/package.json +3 -1
@@ -0,0 +1,332 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { query, } from "@anthropic-ai/claude-agent-sdk";
3
+ import { AuthRequiredError, UnsupportedOperationError, } from "./interface.js";
4
+ import { Pushable } from "./pushable.js";
5
+ function serializeError(err) {
6
+ if (err instanceof Error) {
7
+ return {
8
+ message: err.message || "Unknown error",
9
+ name: err.name,
10
+ stack: err.stack,
11
+ };
12
+ }
13
+ return { message: String(err) };
14
+ }
15
+ export class ClaudeCodeAdapter {
16
+ sessionStore;
17
+ vendor = "claude-code";
18
+ constructor(sessionStore) {
19
+ this.sessionStore = sessionStore;
20
+ }
21
+ async start(spec) {
22
+ const auth = await this.authStatus(spec.workspace, spec.env);
23
+ if (!auth.configured) {
24
+ throw new AuthRequiredError(this.vendor, auth.message ?? "Authentication required");
25
+ }
26
+ return this.spawn(spec);
27
+ }
28
+ async resume(spec) {
29
+ const auth = await this.authStatus(spec.workspace, spec.env);
30
+ if (!auth.configured) {
31
+ throw new AuthRequiredError(this.vendor, auth.message ?? "Authentication required");
32
+ }
33
+ return this.spawn(spec, {
34
+ resume: spec.sessionId,
35
+ forkSession: spec.mode === "fork", // audit-preserving retries => mode:"fork"
36
+ });
37
+ }
38
+ async authStatus(_workspace, env) {
39
+ const hasApiKey = Boolean(env?.ANTHROPIC_API_KEY ?? process.env.ANTHROPIC_API_KEY);
40
+ const hasOAuth = Boolean(env?.CLAUDE_CODE_OAUTH_TOKEN ??
41
+ process.env.CLAUDE_CODE_OAUTH_TOKEN);
42
+ // Anthropic documented precedence: API key bills first when both exist
43
+ if (hasApiKey) {
44
+ return {
45
+ configured: true,
46
+ method: "api-key",
47
+ hasApiKeyFallback: hasOAuth,
48
+ };
49
+ }
50
+ if (hasOAuth) {
51
+ return {
52
+ configured: true,
53
+ method: "subscription-oauth",
54
+ hasApiKeyFallback: false,
55
+ };
56
+ }
57
+ return {
58
+ configured: false,
59
+ method: "unauthenticated",
60
+ message: "No Anthropic API key or Claude Code OAuth token detected.",
61
+ };
62
+ }
63
+ async listSessions(_workspace) {
64
+ // Requires CLAUDE_CODE_PROJECT_DIR_NAME=<workspaceId> and CLAUDE_CONFIG_DIR
65
+ // to have been set at session start so projectKey matches across hosts (verified in Spike 2).
66
+ throw new UnsupportedOperationError("claude-code", "listSessions", "wire to sessionStore-backed listSessions() once store adapter lands");
67
+ }
68
+ // ── internals ──────────────────────────────────────────────────────────
69
+ spawn(spec, overrides = {}) {
70
+ const out = new Pushable();
71
+ let disposed = false;
72
+ const approvalTimers = new Map();
73
+ const safePush = (ev) => {
74
+ if (disposed)
75
+ return;
76
+ try {
77
+ out.push(ev);
78
+ }
79
+ catch {
80
+ // Stream ended or disposed concurrently; ignore to prevent unhandled rejections
81
+ }
82
+ };
83
+ // Streaming-input mode: enables multi-turn `send()` without losing the session.
84
+ const userInput = new Pushable();
85
+ const approvals = new Map();
86
+ const abort = new AbortController();
87
+ let resolveId;
88
+ let rejectId;
89
+ const sessionIdPromise = new Promise((res, rej) => {
90
+ resolveId = res;
91
+ rejectId = rej;
92
+ });
93
+ // Armor against unhandled rejections if caller never attaches a handler before interrupt/dispose
94
+ sessionIdPromise.catch(() => { });
95
+ abort.signal.addEventListener("abort", () => {
96
+ try {
97
+ rejectId(new DOMException("aborted", "AbortError"));
98
+ }
99
+ catch { }
100
+ }, { once: true });
101
+ if (spec.prompt !== undefined && spec.prompt.length > 0) {
102
+ try {
103
+ userInput.push({
104
+ type: "user",
105
+ message: {
106
+ role: "user",
107
+ content: [{ type: "text", text: spec.prompt }],
108
+ },
109
+ parent_tool_use_id: null,
110
+ });
111
+ }
112
+ catch { }
113
+ }
114
+ // Approval bridge: canUseTool callback ↔ approval_required event + respondToApproval()
115
+ const canUseTool = async (_toolName, _input, { signal }) => {
116
+ if (disposed) {
117
+ return { behavior: "deny", message: "Session disposed" };
118
+ }
119
+ const requestId = randomUUID();
120
+ safePush({
121
+ type: "approval_required",
122
+ requestId,
123
+ tool: _toolName,
124
+ input: _input,
125
+ });
126
+ // Auto-deny on timeout so handles never hang indefinitely
127
+ return await new Promise((resolve) => {
128
+ const timer = setTimeout(() => {
129
+ approvalTimers.delete(requestId);
130
+ approvals.delete(requestId);
131
+ resolve({ behavior: "deny", message: "Approval request timed out after 5 minutes" });
132
+ }, 5 * 60 * 1000);
133
+ approvalTimers.set(requestId, timer);
134
+ approvals.set(requestId, (decision) => {
135
+ clearTimeout(timer);
136
+ approvalTimers.delete(requestId);
137
+ approvals.delete(requestId);
138
+ if (decision.behavior === "allow") {
139
+ resolve({
140
+ behavior: "allow",
141
+ updatedInput: decision.updatedInput,
142
+ });
143
+ }
144
+ else {
145
+ resolve({
146
+ behavior: "deny",
147
+ message: decision.message,
148
+ });
149
+ }
150
+ });
151
+ signal?.addEventListener("abort", () => {
152
+ clearTimeout(timer);
153
+ approvalTimers.delete(requestId);
154
+ approvals.delete(requestId);
155
+ resolve({ behavior: "deny", message: "interrupted" });
156
+ }, { once: true });
157
+ });
158
+ };
159
+ void this.pump({
160
+ spec,
161
+ overrides,
162
+ userInput,
163
+ safePush,
164
+ out,
165
+ canUseTool,
166
+ approvals,
167
+ resolveId,
168
+ rejectId,
169
+ abortController: abort,
170
+ isDisposed: () => disposed,
171
+ });
172
+ return {
173
+ vendor: this.vendor,
174
+ sessionId: () => sessionIdPromise,
175
+ events: out,
176
+ send: (prompt) => {
177
+ if (disposed)
178
+ return;
179
+ try {
180
+ userInput.push({
181
+ type: "user",
182
+ message: {
183
+ role: "user",
184
+ content: [{ type: "text", text: prompt }],
185
+ },
186
+ parent_tool_use_id: null,
187
+ });
188
+ }
189
+ catch { }
190
+ },
191
+ respondToApproval: (requestId, decision) => approvals.get(requestId)?.(decision),
192
+ interrupt: async () => abort.abort(),
193
+ dispose: async () => {
194
+ disposed = true;
195
+ for (const timer of approvalTimers.values()) {
196
+ clearTimeout(timer);
197
+ }
198
+ approvalTimers.clear();
199
+ approvals.clear();
200
+ abort.abort();
201
+ try {
202
+ userInput.end();
203
+ }
204
+ catch { }
205
+ try {
206
+ out.end();
207
+ }
208
+ catch { }
209
+ },
210
+ };
211
+ }
212
+ async pump(args) {
213
+ const { spec, overrides, userInput, safePush, out, canUseTool, abortController, isDisposed } = args;
214
+ try {
215
+ const options = {
216
+ cwd: spec.workspace.rootPath,
217
+ additionalDirectories: spec.workspace.additionalDirectories,
218
+ permissionMode: spec.permissionMode ?? "acceptEdits",
219
+ maxTurns: spec.maxTurns,
220
+ model: spec.model,
221
+ // Spike 1 finding: Agent SDK env REPLACES process.env, so callers must spread parent process.env.
222
+ env: spec.env ? { ...process.env, ...spec.env } : undefined,
223
+ mcpServers: spec.mcpServers,
224
+ canUseTool,
225
+ includePartialMessages: true, // enables stream_event deltas below
226
+ sessionStore: this.sessionStore,
227
+ abortController,
228
+ ...overrides,
229
+ // ESCAPE HATCH — deliberately last, wins over everything above.
230
+ ...spec.nativeOptions,
231
+ };
232
+ const queryHandle = query({
233
+ prompt: userInput,
234
+ options,
235
+ });
236
+ for await (const msg of queryHandle) {
237
+ if (isDisposed())
238
+ break;
239
+ this.mapMessage(msg, safePush, args);
240
+ }
241
+ }
242
+ catch (err) {
243
+ try {
244
+ args.rejectId(err instanceof Error ? err : new Error(String(err)));
245
+ }
246
+ catch { }
247
+ safePush({ type: "turn_failed", error: serializeError(err), fatal: true });
248
+ try {
249
+ out.end();
250
+ }
251
+ catch { }
252
+ }
253
+ }
254
+ mapMessage(msg, push, args) {
255
+ switch (msg.type) {
256
+ case "system":
257
+ if (msg.subtype === "init") {
258
+ args.resolveId(msg.session_id);
259
+ push({ type: "session_started", sessionId: msg.session_id });
260
+ }
261
+ break;
262
+ case "stream_event": {
263
+ // Partial assistant text deltas (requires includePartialMessages).
264
+ const event = msg.event;
265
+ if (event?.type === "content_block_delta" && event?.delta?.type === "text_delta" && event.delta.text) {
266
+ push({ type: "text_delta", text: event.delta.text });
267
+ }
268
+ break;
269
+ }
270
+ case "assistant":
271
+ for (const block of msg.message?.content ?? []) {
272
+ if (block.type === "text") {
273
+ push({ type: "assistant_message", text: block.text });
274
+ }
275
+ else if (block.type === "tool_use") {
276
+ push({
277
+ type: "tool_requested",
278
+ callId: block.id,
279
+ tool: block.name,
280
+ input: block.input,
281
+ });
282
+ }
283
+ }
284
+ break;
285
+ case "user": {
286
+ // Tool results arrive as user messages.
287
+ const content = msg.message?.content;
288
+ if (Array.isArray(content)) {
289
+ for (const block of content) {
290
+ if (block.type === "tool_result") {
291
+ push({
292
+ type: "tool_completed",
293
+ callId: block.tool_use_id,
294
+ ok: !block.is_error,
295
+ });
296
+ }
297
+ }
298
+ }
299
+ break;
300
+ }
301
+ case "result": {
302
+ if (msg.subtype === "success") {
303
+ push({
304
+ type: "turn_completed",
305
+ usage: this.normalizeUsage(msg.usage, msg.total_cost_usd),
306
+ });
307
+ }
308
+ else {
309
+ push({
310
+ type: "turn_failed",
311
+ error: { message: `claude turn failed: ${msg.subtype}` },
312
+ fatal: msg.subtype === "error_during_execution",
313
+ });
314
+ }
315
+ break;
316
+ }
317
+ }
318
+ if (args.spec.debugMirrorRaw) {
319
+ push({ type: "raw", vendor: "claude-code", payload: msg });
320
+ }
321
+ }
322
+ normalizeUsage(u, costUsdEstimate) {
323
+ return {
324
+ inputTokens: u?.input_tokens ?? 0,
325
+ outputTokens: u?.output_tokens ?? 0,
326
+ cachedInputTokens: (u?.cache_read_input_tokens ?? 0) +
327
+ (u?.cache_creation_input_tokens ?? 0),
328
+ costUsdEstimate,
329
+ };
330
+ }
331
+ }
332
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/harness/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { Codex } from "@openai/codex-sdk";
2
+ import { type HarnessAdapter, type SessionHandle, type SessionSummary } from "./interface.js";
3
+ import type { AuthStatus, ResumeSpec, StartSpec, WorkspaceRef } from "./types.js";
4
+ export declare class CodexAdapter implements HarnessAdapter {
5
+ readonly vendor: "codex";
6
+ constructor(clientOpts?: ConstructorParameters<typeof Codex>[0]);
7
+ private client;
8
+ start(spec: StartSpec): Promise<SessionHandle>;
9
+ resume(spec: ResumeSpec): Promise<SessionHandle>;
10
+ authStatus(_workspace?: WorkspaceRef, env?: Record<string, string>): Promise<AuthStatus>;
11
+ listSessions(_workspace: WorkspaceRef): Promise<SessionSummary[]>;
12
+ private spawn;
13
+ private runTurn;
14
+ private mapEvent;
15
+ private mapItem;
16
+ private normalizeUsage;
17
+ }
18
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/harness/codex.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAkD,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,cAAc,EAGpB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EACV,UAAU,EAIV,UAAU,EAEV,SAAS,EACT,YAAY,EACb,MAAM,YAAY,CAAC;AA4BpB,qBAAa,YAAa,YAAW,cAAc;IACjD,QAAQ,CAAC,MAAM,EAAG,OAAO,CAAU;gBAEvB,UAAU,GAAE,qBAAqB,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAM;IAGnE,OAAO,CAAC,MAAM,CAAQ;IAEhB,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC;IAe9C,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBhD,UAAU,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAkCxF,YAAY,CAAC,UAAU,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAUvE,OAAO,CAAC,KAAK;YA4EC,OAAO;IA+BrB,OAAO,CAAC,QAAQ;IA2ChB,OAAO,CAAC,OAAO;IA6Bf,OAAO,CAAC,cAAc;CAOvB"}
@@ -0,0 +1,263 @@
1
+ import * as fs from "node:fs";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+ import { Codex } from "@openai/codex-sdk";
5
+ import { AuthRequiredError, UnsupportedOperationError, } from "./interface.js";
6
+ import { Pushable } from "./pushable.js";
7
+ function serializeError(err) {
8
+ if (err instanceof Error) {
9
+ return {
10
+ message: err.message || "Unknown error",
11
+ name: err.name,
12
+ stack: err.stack,
13
+ };
14
+ }
15
+ return { message: String(err) };
16
+ }
17
+ function mapPatchKind(rawKind) {
18
+ switch (rawKind) {
19
+ case "add":
20
+ return "write";
21
+ case "update":
22
+ return "edit";
23
+ case "delete":
24
+ return "delete";
25
+ default:
26
+ return rawKind ?? "edit";
27
+ }
28
+ }
29
+ export class CodexAdapter {
30
+ vendor = "codex";
31
+ constructor(clientOpts = {}) {
32
+ this.client = new Codex(clientOpts);
33
+ }
34
+ client;
35
+ async start(spec) {
36
+ const auth = await this.authStatus(spec.workspace, spec.env);
37
+ if (!auth.configured) {
38
+ throw new AuthRequiredError(this.vendor, auth.message ?? "Authentication required");
39
+ }
40
+ const thread = this.client.startThread({
41
+ workingDirectory: spec.workspace.rootPath,
42
+ // NexusFlow workspaces are multi-repo roots => usually NOT a git repo.
43
+ // Without this, Codex refuses to run (verified in Spike 4).
44
+ skipGitRepoCheck: true,
45
+ ...spec.nativeOptions,
46
+ });
47
+ return this.spawn(spec, thread);
48
+ }
49
+ async resume(spec) {
50
+ const auth = await this.authStatus(spec.workspace, spec.env);
51
+ if (!auth.configured) {
52
+ throw new AuthRequiredError(this.vendor, auth.message ?? "Authentication required");
53
+ }
54
+ if (spec.mode === "fork") {
55
+ // Known asymmetry: no native fork. Emulate later via NexusFlow-side
56
+ // history replay onto a fresh thread. Until then, degrade loudly.
57
+ throw new UnsupportedOperationError("codex", "fork", "no native fork; emulate via history replay (Phase 3)");
58
+ }
59
+ const thread = this.client.resumeThread(spec.sessionId);
60
+ return this.spawn(spec, thread);
61
+ }
62
+ async authStatus(_workspace, env) {
63
+ const hasApiKey = Boolean(env?.OPENAI_API_KEY ??
64
+ process.env.OPENAI_API_KEY ??
65
+ env?.CODEX_API_KEY ??
66
+ process.env.CODEX_API_KEY);
67
+ if (hasApiKey) {
68
+ return {
69
+ configured: true,
70
+ method: "api-key",
71
+ hasApiKeyFallback: true,
72
+ };
73
+ }
74
+ // Probe Codex CLI authentication file
75
+ const codexHome = env?.CODEX_HOME || process.env.CODEX_HOME || path.join(os.homedir(), ".codex");
76
+ const authFile = path.join(codexHome, "auth.json");
77
+ if (fs.existsSync(authFile)) {
78
+ return {
79
+ configured: true,
80
+ method: "chatgpt-signin",
81
+ hasApiKeyFallback: false,
82
+ };
83
+ }
84
+ return {
85
+ configured: false,
86
+ method: "unauthenticated",
87
+ message: "No OpenAI API key or Codex CLI authentication found (~/.codex/auth.json). Run 'codex login' or set OPENAI_API_KEY.",
88
+ };
89
+ }
90
+ async listSessions(_workspace) {
91
+ throw new UnsupportedOperationError("codex", "listSessions", "~/.codex/sessions rollout files are opaque; NexusFlow DB rows are source of truth");
92
+ }
93
+ // ── internals ──────────────────────────────────────────────────────────
94
+ spawn(spec, thread) {
95
+ const out = new Pushable();
96
+ // Serial turn queue: Codex threads support sequential runs, not concurrent ones.
97
+ const turnQueue = [];
98
+ let draining = false;
99
+ let disposed = false;
100
+ let currentAbort = null;
101
+ const safePush = (ev) => {
102
+ if (disposed)
103
+ return;
104
+ try {
105
+ out.push(ev);
106
+ }
107
+ catch {
108
+ // Stream ended or disposed concurrently
109
+ }
110
+ };
111
+ let resolveId;
112
+ let rejectId;
113
+ const sessionIdPromise = new Promise((res, rej) => {
114
+ resolveId = res;
115
+ rejectId = rej;
116
+ });
117
+ // Armor against unhandled rejections if caller never attaches a handler before interrupt/dispose
118
+ sessionIdPromise.catch(() => { });
119
+ const drain = async () => {
120
+ if (draining || disposed)
121
+ return;
122
+ draining = true;
123
+ try {
124
+ while (turnQueue.length > 0 && !disposed) {
125
+ const prompt = turnQueue.shift();
126
+ currentAbort = new AbortController();
127
+ await this.runTurn(thread, prompt, safePush, out, spec, resolveId, rejectId, currentAbort.signal, () => disposed);
128
+ currentAbort = null;
129
+ }
130
+ }
131
+ finally {
132
+ draining = false;
133
+ }
134
+ };
135
+ if (spec.prompt !== undefined && spec.prompt.length > 0) {
136
+ turnQueue.push(spec.prompt);
137
+ void drain();
138
+ }
139
+ return {
140
+ vendor: this.vendor,
141
+ sessionId: () => sessionIdPromise,
142
+ events: out,
143
+ send: (prompt) => {
144
+ if (disposed)
145
+ return;
146
+ turnQueue.push(prompt);
147
+ void drain();
148
+ },
149
+ respondToApproval: (_requestId, _decision) => {
150
+ // Codex approvals are configured at thread startup (sandboxMode/approvalPolicy).
151
+ },
152
+ interrupt: async () => {
153
+ if (currentAbort) {
154
+ currentAbort.abort();
155
+ }
156
+ },
157
+ dispose: async () => {
158
+ disposed = true;
159
+ turnQueue.length = 0;
160
+ if (currentAbort) {
161
+ currentAbort.abort();
162
+ }
163
+ try {
164
+ out.end();
165
+ }
166
+ catch { }
167
+ },
168
+ };
169
+ }
170
+ async runTurn(thread, prompt, safePush, out, spec, resolveId, rejectId, signal, isDisposed) {
171
+ try {
172
+ const run = await thread.runStreamed(prompt, { signal });
173
+ for await (const ev of run.events) {
174
+ if (isDisposed())
175
+ break;
176
+ this.mapEvent(ev, safePush, resolveId);
177
+ if (spec.debugMirrorRaw) {
178
+ safePush({ type: "raw", vendor: "codex", payload: ev });
179
+ }
180
+ }
181
+ }
182
+ catch (err) {
183
+ try {
184
+ rejectId(err instanceof Error ? err : new Error(String(err)));
185
+ }
186
+ catch { }
187
+ safePush({ type: "turn_failed", error: serializeError(err), fatal: true });
188
+ try {
189
+ out.end();
190
+ }
191
+ catch { }
192
+ }
193
+ }
194
+ mapEvent(ev, push, resolveId) {
195
+ switch (ev.type) {
196
+ case "thread.started":
197
+ resolveId(ev.thread_id);
198
+ push({ type: "session_started", sessionId: ev.thread_id });
199
+ break;
200
+ case "item.started":
201
+ case "item.updated":
202
+ // Item in progress (commands, tool calls)
203
+ break;
204
+ case "item.completed":
205
+ this.mapItem(ev.item, push);
206
+ break;
207
+ case "turn.completed":
208
+ push({ type: "turn_completed", usage: this.normalizeUsage(ev.usage) });
209
+ // Streams stay open across consecutive turns until explicit dispose()
210
+ break;
211
+ case "turn.failed":
212
+ push({
213
+ type: "turn_failed",
214
+ error: { message: ev.error.message ?? "codex turn failed" },
215
+ fatal: true,
216
+ });
217
+ break;
218
+ case "error":
219
+ push({
220
+ type: "turn_failed",
221
+ error: { message: ev.message },
222
+ fatal: true,
223
+ });
224
+ break;
225
+ }
226
+ }
227
+ mapItem(item, push) {
228
+ switch (item.type) {
229
+ case "agent_message":
230
+ push({ type: "assistant_message", text: item.text });
231
+ break;
232
+ case "file_change":
233
+ push({
234
+ type: "file_changed",
235
+ kind: mapPatchKind(item.changes?.[0]?.kind),
236
+ paths: item.changes?.map((c) => c.path) ?? [],
237
+ });
238
+ break;
239
+ case "command_execution":
240
+ push({
241
+ type: "tool_completed",
242
+ callId: item.id,
243
+ ok: item.exit_code === 0,
244
+ outputSummary: item.aggregated_output?.slice(0, 500),
245
+ });
246
+ break;
247
+ case "mcp_tool_call":
248
+ push({ type: "tool_completed", callId: item.id, ok: item.status === "completed" });
249
+ break;
250
+ default:
251
+ // reasoning / web_search / todo_list — pass-through only via raw mirroring
252
+ break;
253
+ }
254
+ }
255
+ normalizeUsage(u) {
256
+ return {
257
+ inputTokens: u?.input_tokens ?? 0,
258
+ outputTokens: u?.output_tokens ?? 0,
259
+ cachedInputTokens: u?.cached_input_tokens,
260
+ }; // costUsd unavailable on Codex — left undefined by design
261
+ }
262
+ }
263
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/harness/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=harness.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.test.d.ts","sourceRoot":"","sources":["../../src/harness/harness.test.ts"],"names":[],"mappings":""}