@mrpatronz/nexusflow 2.0.0 → 2.2.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 (112) hide show
  1. package/README.md +5 -1
  2. package/dist/agent/AcpCliAdapter.d.ts +75 -0
  3. package/dist/agent/AcpCliAdapter.d.ts.map +1 -0
  4. package/dist/agent/AcpCliAdapter.js +292 -0
  5. package/dist/agent/AcpCliAdapter.js.map +1 -0
  6. package/dist/agent/AcpCliAdapter.test.d.ts +2 -0
  7. package/dist/agent/AcpCliAdapter.test.d.ts.map +1 -0
  8. package/dist/agent/AcpCliAdapter.test.js +235 -0
  9. package/dist/agent/AcpCliAdapter.test.js.map +1 -0
  10. package/dist/agent/ClaudeCliAdapter.d.ts +40 -5
  11. package/dist/agent/ClaudeCliAdapter.d.ts.map +1 -1
  12. package/dist/agent/ClaudeCliAdapter.js +212 -15
  13. package/dist/agent/ClaudeCliAdapter.js.map +1 -1
  14. package/dist/agent/ClaudeCliAdapter.test.d.ts +2 -0
  15. package/dist/agent/ClaudeCliAdapter.test.d.ts.map +1 -0
  16. package/dist/agent/ClaudeCliAdapter.test.js +320 -0
  17. package/dist/agent/ClaudeCliAdapter.test.js.map +1 -0
  18. package/dist/agent/CliAdapterBase.d.ts +29 -12
  19. package/dist/agent/CliAdapterBase.d.ts.map +1 -1
  20. package/dist/agent/CliAdapterBase.js +76 -36
  21. package/dist/agent/CliAdapterBase.js.map +1 -1
  22. package/dist/agent/CodexCliAdapter.d.ts +51 -0
  23. package/dist/agent/CodexCliAdapter.d.ts.map +1 -0
  24. package/dist/agent/CodexCliAdapter.js +226 -0
  25. package/dist/agent/CodexCliAdapter.js.map +1 -0
  26. package/dist/agent/CodexCliAdapter.test.d.ts +2 -0
  27. package/dist/agent/CodexCliAdapter.test.d.ts.map +1 -0
  28. package/dist/agent/CodexCliAdapter.test.js +316 -0
  29. package/dist/agent/CodexCliAdapter.test.js.map +1 -0
  30. package/dist/agent/CopilotAcpAdapter.d.ts +7 -0
  31. package/dist/agent/CopilotAcpAdapter.d.ts.map +1 -0
  32. package/dist/agent/CopilotAcpAdapter.js +29 -0
  33. package/dist/agent/CopilotAcpAdapter.js.map +1 -0
  34. package/dist/agent/ProviderRegistry.d.ts +39 -3
  35. package/dist/agent/ProviderRegistry.d.ts.map +1 -1
  36. package/dist/agent/ProviderRegistry.js +43 -8
  37. package/dist/agent/ProviderRegistry.js.map +1 -1
  38. package/dist/agent/ProviderRegistry.test.js +52 -0
  39. package/dist/agent/ProviderRegistry.test.js.map +1 -1
  40. package/dist/agent/adapters.d.ts +7 -5
  41. package/dist/agent/adapters.d.ts.map +1 -1
  42. package/dist/agent/adapters.js +92 -17
  43. package/dist/agent/adapters.js.map +1 -1
  44. package/dist/agent/adapters.test.js +22 -0
  45. package/dist/agent/adapters.test.js.map +1 -1
  46. package/dist/agent/cliAvailability.d.ts +51 -13
  47. package/dist/agent/cliAvailability.d.ts.map +1 -1
  48. package/dist/agent/cliAvailability.js +163 -44
  49. package/dist/agent/cliAvailability.js.map +1 -1
  50. package/dist/agent/cliAvailability.test.js +140 -53
  51. package/dist/agent/cliAvailability.test.js.map +1 -1
  52. package/dist/agent/session.d.ts +2 -1
  53. package/dist/agent/session.d.ts.map +1 -1
  54. package/dist/agent/session.js +15 -4
  55. package/dist/agent/session.js.map +1 -1
  56. package/dist/agent/session.test.js +29 -8
  57. package/dist/agent/session.test.js.map +1 -1
  58. package/dist/core/workspace.d.ts +6 -0
  59. package/dist/core/workspace.d.ts.map +1 -1
  60. package/dist/core/workspace.js +17 -7
  61. package/dist/core/workspace.js.map +1 -1
  62. package/dist/core/workspace.test.js +12 -1
  63. package/dist/core/workspace.test.js.map +1 -1
  64. package/dist/gui/assets/DashboardPage-CUspfCap.js +1 -0
  65. package/dist/gui/assets/GettingStartedPage-BqtgARZW.js +1 -0
  66. package/dist/gui/assets/ProjectsPage-UBoQxI2G.js +1 -0
  67. package/dist/gui/assets/{ScaffoldRepoInline-D-2ZeuDK.js → ScaffoldRepoInline-DqoourJe.js} +1 -1
  68. package/dist/gui/assets/SettingsPage-BZl24tqD.js +1 -0
  69. package/dist/gui/assets/StartWorkPage-BGNFdBfj.js +1 -0
  70. package/dist/gui/assets/{StrategiesPage-Cizm0GWk.js → StrategiesPage-D0Y6A4Tw.js} +2 -2
  71. package/dist/gui/assets/WorkspaceLauncher-Cxv0O_wt.js +1 -0
  72. package/dist/gui/assets/WorkspacesPage-Cvb1rOeh.js +6 -0
  73. package/dist/gui/assets/index-CllPiiFL.js +52 -0
  74. package/dist/gui/assets/index-DGCBhMAn.css +2 -0
  75. package/dist/gui/index.html +2 -2
  76. package/dist/server.d.ts +13 -0
  77. package/dist/server.d.ts.map +1 -1
  78. package/dist/server.js +267 -39
  79. package/dist/server.js.map +1 -1
  80. package/dist/server.test.js +324 -18
  81. package/dist/server.test.js.map +1 -1
  82. package/dist/types.d.ts +13 -0
  83. package/dist/types.d.ts.map +1 -1
  84. package/dist/utils/detect-editors.d.ts.map +1 -1
  85. package/dist/utils/detect-editors.js +6 -0
  86. package/dist/utils/detect-editors.js.map +1 -1
  87. package/dist/utils/detect-editors.test.js +12 -0
  88. package/dist/utils/detect-editors.test.js.map +1 -1
  89. package/dist/utils/session-finder.d.ts +14 -0
  90. package/dist/utils/session-finder.d.ts.map +1 -1
  91. package/dist/utils/session-finder.js +127 -10
  92. package/dist/utils/session-finder.js.map +1 -1
  93. package/dist/utils/session-finder.test.js +104 -2
  94. package/dist/utils/session-finder.test.js.map +1 -1
  95. package/dist/utils/workspace-launch.d.ts +37 -0
  96. package/dist/utils/workspace-launch.d.ts.map +1 -0
  97. package/dist/utils/workspace-launch.js +200 -0
  98. package/dist/utils/workspace-launch.js.map +1 -0
  99. package/dist/utils/workspace-launch.test.d.ts +2 -0
  100. package/dist/utils/workspace-launch.test.d.ts.map +1 -0
  101. package/dist/utils/workspace-launch.test.js +94 -0
  102. package/dist/utils/workspace-launch.test.js.map +1 -0
  103. package/package.json +5 -3
  104. package/dist/gui/assets/DashboardPage-HNC3-OP0.js +0 -1
  105. package/dist/gui/assets/GettingStartedPage-Dguoya_Z.js +0 -1
  106. package/dist/gui/assets/ProjectsPage-DVR4j4sw.js +0 -1
  107. package/dist/gui/assets/SettingsPage-Bauo77q3.js +0 -1
  108. package/dist/gui/assets/StartWorkPage-DvuFEa5Y.js +0 -1
  109. package/dist/gui/assets/WorkspacesPage-DYOVfZqy.js +0 -6
  110. package/dist/gui/assets/external-link-BtYhMxno.js +0 -1
  111. package/dist/gui/assets/index-BqeoAIB1.js +0 -52
  112. package/dist/gui/assets/index-CsA2SueF.css +0 -2
@@ -0,0 +1,51 @@
1
+ import { CliAdapterBase } from './CliAdapterBase.js';
2
+ import { type AgentSession } from './session.js';
3
+ import type { AgentExecutionProfile } from './ProviderRegistry.js';
4
+ export type CodexOutputEvent = {
5
+ type: 'session';
6
+ id: string;
7
+ } | {
8
+ type: 'message';
9
+ text: string;
10
+ } | {
11
+ type: 'complete';
12
+ } | {
13
+ type: 'error';
14
+ message: string;
15
+ source: 'protocol' | 'provider';
16
+ };
17
+ /** Incrementally decodes the JSONL stream produced by `codex exec --json`. */
18
+ export declare class CodexJsonlDecoder {
19
+ private readonly maxRecordChars;
20
+ private buffer;
21
+ private failed;
22
+ constructor(maxRecordChars?: number);
23
+ push(chunk: string): CodexOutputEvent[];
24
+ finish(): CodexOutputEvent[];
25
+ private failOversizedRecord;
26
+ }
27
+ /** Decode one complete Codex JSONL record into the small chat protocol. */
28
+ export declare function decodeCodexLine(line: string): CodexOutputEvent[];
29
+ /** Build one keyless Codex CLI turn. Prompts always arrive over stdin. */
30
+ export declare function buildCodexTurnArgs(sessionId?: string, executionProfile?: AgentExecutionProfile): string[];
31
+ export declare class CodexCliAdapter extends CliAdapterBase {
32
+ protected readonly binary: string;
33
+ protected readonly label = "Codex CLI";
34
+ protected readonly useShell: boolean;
35
+ protected readonly promptViaStdin = true;
36
+ private requestedSession;
37
+ private activeSessionId;
38
+ private decoder;
39
+ private sawTurnOutcome;
40
+ private sawAssistantMessage;
41
+ private acknowledgedThisTurn;
42
+ private turnFinished;
43
+ constructor();
44
+ start(cwd: string, session?: AgentSession): Promise<void>;
45
+ protected buildArgs(isFirstTurn: boolean, _prompt: string, executionProfile?: AgentExecutionProfile): string[];
46
+ protected handleStdout(text: string): boolean;
47
+ protected finishStdout(exitCode: number | null): boolean;
48
+ private emitDecoded;
49
+ private resumabilitySuffix;
50
+ }
51
+ //# sourceMappingURL=CodexCliAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodexCliAdapter.d.ts","sourceRoot":"","sources":["../../src/agent/CodexCliAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAErE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAA;CAAE,CAAC;AAKxE,8EAA8E;AAC9E,qBAAa,iBAAiB;IAIT,OAAO,CAAC,QAAQ,CAAC,cAAc;IAHlD,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,MAAM,CAAS;gBAEa,cAAc,SAAyB;IAE3E,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,EAAE;IAgBvC,MAAM,IAAI,gBAAgB,EAAE;IAQ5B,OAAO,CAAC,mBAAmB;CAK5B;AAeD,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAoChE;AAYD,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAChC,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,GAAE,qBAAgC,GACjD,MAAM,EAAE,CAMV;AAED,qBAAa,eAAgB,SAAQ,cAAc;IACjD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,QAAQ,CAAC,KAAK,eAAe;IACvC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IACrC,SAAS,CAAC,QAAQ,CAAC,cAAc,QAAQ;IAEzC,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,YAAY,CAAS;;IAQtB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAchE,SAAS,CAAC,SAAS,CACjB,WAAW,EAAE,OAAO,EACpB,OAAO,EAAE,MAAM,EACf,gBAAgB,GAAE,qBAAgC,GACjD,MAAM,EAAE;IAYX,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI7C,SAAS,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO;IAmBxD,OAAO,CAAC,WAAW;IA4DnB,OAAO,CAAC,kBAAkB;CAK3B"}
@@ -0,0 +1,226 @@
1
+ import { CliAdapterBase } from './CliAdapterBase.js';
2
+ import { isValidSessionUuid } from './session.js';
3
+ import { findExecutable } from './cliAvailability.js';
4
+ const MAX_JSONL_RECORD_CHARS = 8 * 1024 * 1024;
5
+ const OVERSIZED_RECORD_MESSAGE = 'Codex structured output exceeded the supported record size.';
6
+ /** Incrementally decodes the JSONL stream produced by `codex exec --json`. */
7
+ export class CodexJsonlDecoder {
8
+ maxRecordChars;
9
+ buffer = '';
10
+ failed = false;
11
+ constructor(maxRecordChars = MAX_JSONL_RECORD_CHARS) {
12
+ this.maxRecordChars = maxRecordChars;
13
+ }
14
+ push(chunk) {
15
+ if (this.failed)
16
+ return [];
17
+ this.buffer += chunk;
18
+ const events = [];
19
+ let newline = this.buffer.indexOf('\n');
20
+ while (newline !== -1) {
21
+ if (newline > this.maxRecordChars)
22
+ return this.failOversizedRecord();
23
+ const line = this.buffer.slice(0, newline).trim();
24
+ this.buffer = this.buffer.slice(newline + 1);
25
+ if (line)
26
+ events.push(...decodeCodexLine(line));
27
+ newline = this.buffer.indexOf('\n');
28
+ }
29
+ if (this.buffer.length > this.maxRecordChars)
30
+ return this.failOversizedRecord();
31
+ return events;
32
+ }
33
+ finish() {
34
+ if (this.failed)
35
+ return [];
36
+ if (this.buffer.length > this.maxRecordChars)
37
+ return this.failOversizedRecord();
38
+ const line = this.buffer.trim();
39
+ this.buffer = '';
40
+ return line ? decodeCodexLine(line) : [];
41
+ }
42
+ failOversizedRecord() {
43
+ this.failed = true;
44
+ this.buffer = '';
45
+ return [{ type: 'error', message: OVERSIZED_RECORD_MESSAGE, source: 'protocol' }];
46
+ }
47
+ }
48
+ function isRecord(value) {
49
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
50
+ }
51
+ function failureMessage(value) {
52
+ const error = isRecord(value.error) ? value.error : null;
53
+ const candidates = [error?.message, value.message, typeof value.error === 'string' ? value.error : null];
54
+ const message = candidates.find((candidate) => (typeof candidate === 'string' && candidate.trim().length > 0));
55
+ return message?.trim().slice(0, 2_000) ?? 'Codex could not complete the turn.';
56
+ }
57
+ /** Decode one complete Codex JSONL record into the small chat protocol. */
58
+ export function decodeCodexLine(line) {
59
+ let value;
60
+ try {
61
+ value = JSON.parse(line);
62
+ }
63
+ catch {
64
+ return [{ type: 'error', message: 'Codex emitted malformed structured output.', source: 'protocol' }];
65
+ }
66
+ if (!isRecord(value)) {
67
+ return [{ type: 'error', message: 'Codex emitted an invalid structured record.', source: 'protocol' }];
68
+ }
69
+ if (value.type === 'thread.started') {
70
+ return typeof value.thread_id === 'string' && isValidSessionUuid(value.thread_id)
71
+ ? [{ type: 'session', id: value.thread_id }]
72
+ : [{ type: 'error', message: 'Codex started without a valid thread identity.', source: 'protocol' }];
73
+ }
74
+ if (value.type === 'item.completed'
75
+ && isRecord(value.item)
76
+ && value.item.type === 'agent_message'
77
+ && typeof value.item.text === 'string'
78
+ && value.item.text) {
79
+ return [{ type: 'message', text: value.item.text }];
80
+ }
81
+ if (value.type === 'turn.completed') {
82
+ return [{ type: 'complete' }];
83
+ }
84
+ if (value.type === 'turn.failed' || value.type === 'error') {
85
+ return [{ type: 'error', message: failureMessage(value), source: 'provider' }];
86
+ }
87
+ return [];
88
+ }
89
+ function codexRunConfig(executionProfile) {
90
+ return [
91
+ '-c', `sandbox_mode="${executionProfile === 'workspace-write' ? 'workspace-write' : 'read-only'}"`,
92
+ '-c', 'approval_policy="never"',
93
+ ...(executionProfile === 'workspace-write'
94
+ ? ['-c', 'sandbox_workspace_write.network_access=false']
95
+ : []),
96
+ ];
97
+ }
98
+ /** Build one keyless Codex CLI turn. Prompts always arrive over stdin. */
99
+ export function buildCodexTurnArgs(sessionId, executionProfile = 'review') {
100
+ const runConfig = codexRunConfig(executionProfile);
101
+ if (sessionId) {
102
+ return ['exec', 'resume', '--json', ...runConfig, sessionId, '-'];
103
+ }
104
+ return ['exec', '--json', '--color', 'never', ...runConfig, '-'];
105
+ }
106
+ export class CodexCliAdapter extends CliAdapterBase {
107
+ binary;
108
+ label = 'Codex CLI';
109
+ useShell;
110
+ promptViaStdin = true;
111
+ requestedSession;
112
+ activeSessionId;
113
+ decoder = new CodexJsonlDecoder();
114
+ sawTurnOutcome = false;
115
+ sawAssistantMessage = false;
116
+ acknowledgedThisTurn = false;
117
+ turnFinished = false;
118
+ constructor() {
119
+ super();
120
+ this.binary = findExecutable('codex') ?? 'codex';
121
+ this.useShell = process.platform === 'win32' && /\.(cmd|bat)$/i.test(this.binary);
122
+ }
123
+ start(cwd, session) {
124
+ // The renderer sends start and the first input as adjacent WebSocket
125
+ // frames. Capture the requested resume identity before returning the
126
+ // start promise so that input cannot accidentally launch a new thread.
127
+ this.requestedSession = session;
128
+ this.activeSessionId = session?.resume ? session.id : undefined;
129
+ this.decoder = new CodexJsonlDecoder();
130
+ this.sawTurnOutcome = false;
131
+ this.sawAssistantMessage = false;
132
+ this.acknowledgedThisTurn = false;
133
+ this.turnFinished = false;
134
+ return super.start(cwd);
135
+ }
136
+ buildArgs(isFirstTurn, _prompt, executionProfile = 'review') {
137
+ this.decoder = new CodexJsonlDecoder();
138
+ this.sawTurnOutcome = false;
139
+ this.sawAssistantMessage = false;
140
+ this.acknowledgedThisTurn = false;
141
+ this.turnFinished = false;
142
+ const sessionId = isFirstTurn
143
+ ? (this.requestedSession?.resume ? this.requestedSession.id : undefined)
144
+ : this.activeSessionId;
145
+ return buildCodexTurnArgs(sessionId, executionProfile);
146
+ }
147
+ handleStdout(text) {
148
+ return this.emitDecoded(this.decoder.push(text));
149
+ }
150
+ finishStdout(exitCode) {
151
+ const handled = this.emitDecoded(this.decoder.finish());
152
+ if (!this.sawTurnOutcome && this.sawAssistantMessage) {
153
+ this.sawTurnOutcome = true;
154
+ this.failCurrentTurn(new Error('Codex CLI ended before confirming turn completion. The active session remains resumable.'));
155
+ return true;
156
+ }
157
+ if (!this.sawTurnOutcome && exitCode === 0) {
158
+ this.sawTurnOutcome = true;
159
+ this.failCurrentTurn(new Error('Codex CLI ended without a recognized response. Update Codex and try again; its JSON output may be incompatible with this NexusFlow version.'));
160
+ return true;
161
+ }
162
+ return handled;
163
+ }
164
+ emitDecoded(events) {
165
+ let handled = false;
166
+ for (const event of events) {
167
+ if (this.turnFinished)
168
+ break;
169
+ if (event.type === 'session') {
170
+ const expectedId = this.activeSessionId;
171
+ if (expectedId && event.id.toLowerCase() !== expectedId.toLowerCase()) {
172
+ this.turnFinished = true;
173
+ this.sawTurnOutcome = true;
174
+ handled = true;
175
+ this.failCurrentTurn(new Error('Codex returned a conflicting thread identity. The unexpected identity was rejected; the active session remains resumable.'), true);
176
+ continue;
177
+ }
178
+ if (!this.acknowledgedThisTurn) {
179
+ const acknowledgedId = expectedId ?? event.id;
180
+ this.activeSessionId = acknowledgedId;
181
+ this.acknowledgedThisTurn = true;
182
+ this.emit('session', acknowledgedId);
183
+ }
184
+ }
185
+ else if (event.type === 'message') {
186
+ handled = true;
187
+ if (!this.acknowledgedThisTurn) {
188
+ this.turnFinished = true;
189
+ this.sawTurnOutcome = true;
190
+ this.failCurrentTurn(new Error(`Codex completed output without acknowledging a thread identity. ${this.resumabilitySuffix()}`), true);
191
+ }
192
+ else {
193
+ this.sawAssistantMessage = true;
194
+ this.emit('data', event.text);
195
+ }
196
+ }
197
+ else if (event.type === 'complete') {
198
+ handled = true;
199
+ this.sawTurnOutcome = true;
200
+ this.turnFinished = true;
201
+ if (!this.acknowledgedThisTurn) {
202
+ this.failCurrentTurn(new Error(`Codex completed without acknowledging a thread identity. ${this.resumabilitySuffix()}`), true);
203
+ }
204
+ else if (!this.sawAssistantMessage) {
205
+ this.failCurrentTurn(new Error('Codex completed without a recognizable assistant response. The active session remains resumable.'), true);
206
+ }
207
+ }
208
+ else {
209
+ handled = true;
210
+ this.sawTurnOutcome = true;
211
+ this.turnFinished = true;
212
+ const message = event.source === 'protocol'
213
+ ? `${event.message} ${this.resumabilitySuffix()}`
214
+ : event.message;
215
+ this.failCurrentTurn(new Error(message), true);
216
+ }
217
+ }
218
+ return handled;
219
+ }
220
+ resumabilitySuffix() {
221
+ return this.activeSessionId
222
+ ? 'The active session remains resumable.'
223
+ : 'The turn was not marked resumable.';
224
+ }
225
+ }
226
+ //# sourceMappingURL=CodexCliAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodexCliAdapter.js","sourceRoot":"","sources":["../../src/agent/CodexCliAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=CodexCliAdapter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodexCliAdapter.test.d.ts","sourceRoot":"","sources":["../../src/agent/CodexCliAdapter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,316 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+ import { buildCodexTurnArgs, CodexCliAdapter, CodexJsonlDecoder, decodeCodexLine, } from './CodexCliAdapter.js';
4
+ const ID = '0199a213-81c0-7800-8aa1-bbab2a035a53';
5
+ const OTHER_ID = '0199a213-81c0-7800-8aa1-bbab2a035a54';
6
+ function threadRecord(id = ID) {
7
+ return `${JSON.stringify({ type: 'thread.started', thread_id: id })}\n`;
8
+ }
9
+ function messageRecord(text = 'Done') {
10
+ return `${JSON.stringify({
11
+ type: 'item.completed',
12
+ item: { type: 'agent_message', text },
13
+ })}\n`;
14
+ }
15
+ function completeRecord() {
16
+ return `${JSON.stringify({ type: 'turn.completed', usage: { input_tokens: 1 } })}\n`;
17
+ }
18
+ function failureRecord(message = 'Permission denied') {
19
+ return `${JSON.stringify({ type: 'turn.failed', error: { message } })}\n`;
20
+ }
21
+ class FakeChild extends EventEmitter {
22
+ stdin = { write: vi.fn(), end: vi.fn() };
23
+ stdout = Object.assign(new EventEmitter(), { setEncoding: vi.fn() });
24
+ stderr = new EventEmitter();
25
+ killed = false;
26
+ exitCode = null;
27
+ pid;
28
+ }
29
+ class TestCodexCliAdapter extends CodexCliAdapter {
30
+ processes = [];
31
+ spawnProcess(args) {
32
+ const child = new FakeChild();
33
+ this.processes.push({ args, child });
34
+ return child;
35
+ }
36
+ }
37
+ describe('buildCodexTurnArgs', () => {
38
+ it('starts a JSONL exec turn in a read-only sandbox by default', () => {
39
+ expect(buildCodexTurnArgs(undefined, 'review')).toEqual([
40
+ 'exec', '--json', '--color', 'never',
41
+ '-c', 'sandbox_mode="read-only"',
42
+ '-c', 'approval_policy="never"',
43
+ '-',
44
+ ]);
45
+ });
46
+ it('resumes the exact Codex thread id', () => {
47
+ expect(buildCodexTurnArgs(ID, 'review')).toEqual([
48
+ 'exec', 'resume', '--json',
49
+ '-c', 'sandbox_mode="read-only"',
50
+ '-c', 'approval_policy="never"',
51
+ ID, '-',
52
+ ]);
53
+ });
54
+ it('uses workspace-write with network and approval escalation disabled', () => {
55
+ expect(buildCodexTurnArgs(undefined, 'workspace-write')).toEqual([
56
+ 'exec', '--json', '--color', 'never',
57
+ '-c', 'sandbox_mode="workspace-write"',
58
+ '-c', 'approval_policy="never"',
59
+ '-c', 'sandbox_workspace_write.network_access=false',
60
+ '-',
61
+ ]);
62
+ expect(buildCodexTurnArgs(ID, 'workspace-write')).toEqual([
63
+ 'exec', 'resume', '--json',
64
+ '-c', 'sandbox_mode="workspace-write"',
65
+ '-c', 'approval_policy="never"',
66
+ '-c', 'sandbox_workspace_write.network_access=false',
67
+ ID, '-',
68
+ ]);
69
+ });
70
+ });
71
+ describe('Codex JSONL decoding', () => {
72
+ it('extracts a chunked thread id and completed assistant message', () => {
73
+ const decoder = new CodexJsonlDecoder();
74
+ const stream = threadRecord() + messageRecord() + completeRecord();
75
+ expect(decoder.push(stream.slice(0, 17))).toEqual([]);
76
+ expect(decoder.push(stream.slice(17))).toEqual([
77
+ { type: 'session', id: ID },
78
+ { type: 'message', text: 'Done' },
79
+ { type: 'complete' },
80
+ ]);
81
+ });
82
+ it('flushes a final record without a newline', () => {
83
+ const decoder = new CodexJsonlDecoder();
84
+ decoder.push(messageRecord('Final').trimEnd());
85
+ expect(decoder.finish()).toEqual([{ type: 'message', text: 'Final' }]);
86
+ });
87
+ it('fails closed for malformed records and invalid thread identities', () => {
88
+ expect(decodeCodexLine('{not json')).toEqual([{
89
+ type: 'error',
90
+ message: 'Codex emitted malformed structured output.',
91
+ source: 'protocol',
92
+ }]);
93
+ expect(decodeCodexLine('[]')).toEqual([{
94
+ type: 'error',
95
+ message: 'Codex emitted an invalid structured record.',
96
+ source: 'protocol',
97
+ }]);
98
+ expect(decodeCodexLine('{"type":"thread.started","thread_id":"bad; echo injected"}'))
99
+ .toEqual([{
100
+ type: 'error',
101
+ message: 'Codex started without a valid thread identity.',
102
+ source: 'protocol',
103
+ }]);
104
+ });
105
+ it('caps one structured record and stays failed afterward', () => {
106
+ const decoder = new CodexJsonlDecoder(32);
107
+ expect(decoder.push(`{"type":"unknown","padding":"${'x'.repeat(32)}`)).toEqual([{
108
+ type: 'error',
109
+ message: 'Codex structured output exceeded the supported record size.',
110
+ source: 'protocol',
111
+ }]);
112
+ expect(decoder.push(`"}\n${threadRecord()}`)).toEqual([]);
113
+ expect(decoder.finish()).toEqual([]);
114
+ });
115
+ it('bounds provider error strings and never stringifies arbitrary metadata', () => {
116
+ const longMessage = `Denied ${'x'.repeat(3_000)}`;
117
+ const [bounded] = decodeCodexLine(failureRecord(longMessage));
118
+ expect(bounded).toMatchObject({ type: 'error', source: 'provider' });
119
+ expect(bounded.type === 'error' && bounded.message).toHaveLength(2_000);
120
+ expect(decodeCodexLine(JSON.stringify({
121
+ type: 'turn.failed',
122
+ error: { metadata: { secret: 'do-not-render' } },
123
+ message: { arbitrary: 'object' },
124
+ }))).toEqual([{
125
+ type: 'error',
126
+ message: 'Codex could not complete the turn.',
127
+ source: 'provider',
128
+ }]);
129
+ });
130
+ it('ignores valid non-user-facing events', () => {
131
+ expect(decodeCodexLine('{"type":"turn.started"}')).toEqual([]);
132
+ });
133
+ });
134
+ describe('Codex acknowledged thread lifecycle', () => {
135
+ it('uses the requested resume id even when input follows start immediately', async () => {
136
+ const adapter = new TestCodexCliAdapter();
137
+ const starting = adapter.start('C:\\workspace', { id: ID, resume: true });
138
+ await adapter.send('Resume without waiting for transport setup');
139
+ await starting;
140
+ expect(adapter.processes).toHaveLength(1);
141
+ expect(adapter.processes[0].args).toContain(ID);
142
+ expect(adapter.processes[0].args.slice(0, 3)).toEqual(['exec', 'resume', '--json']);
143
+ });
144
+ it('acknowledges a new thread, returns its message, then resumes the exact id', async () => {
145
+ const adapter = new TestCodexCliAdapter();
146
+ const sessions = [];
147
+ const data = [];
148
+ adapter.on('session', (id) => sessions.push(id));
149
+ adapter.on('data', (text) => data.push(text));
150
+ await adapter.start('C:\\workspace');
151
+ await adapter.send('Inspect', 'review');
152
+ adapter.processes[0].child.stdout.emit('data', Buffer.from(threadRecord() + messageRecord() + completeRecord()));
153
+ adapter.processes[0].child.emit('close', 0);
154
+ await adapter.send('Apply', 'workspace-write');
155
+ expect(adapter.processes[0].child.stdout.setEncoding).toHaveBeenCalledWith('utf8');
156
+ expect(adapter.processes.map(process => process.args)).toEqual([
157
+ [
158
+ 'exec', '--json', '--color', 'never',
159
+ '-c', 'sandbox_mode="read-only"',
160
+ '-c', 'approval_policy="never"',
161
+ '-',
162
+ ],
163
+ [
164
+ 'exec', 'resume', '--json',
165
+ '-c', 'sandbox_mode="workspace-write"',
166
+ '-c', 'approval_policy="never"',
167
+ '-c', 'sandbox_workspace_write.network_access=false',
168
+ ID, '-',
169
+ ],
170
+ ]);
171
+ expect(sessions).toEqual([ID]);
172
+ expect(data).toEqual(['Done']);
173
+ });
174
+ it('keeps a malformed pre-ack turn busy until settlement, then retries as new', async () => {
175
+ const adapter = new TestCodexCliAdapter();
176
+ const errors = [];
177
+ const idle = [];
178
+ adapter.on('error', (error) => errors.push(error.message));
179
+ adapter.on('idle', () => idle.push(1));
180
+ await adapter.start('C:\\workspace');
181
+ await adapter.send('Start');
182
+ adapter.processes[0].child.stdout.emit('data', Buffer.from('{not json}\n'));
183
+ await adapter.send('Must not overlap');
184
+ expect(errors).toEqual([]);
185
+ expect(idle).toEqual([]);
186
+ expect(adapter.processes).toHaveLength(1);
187
+ adapter.processes[0].child.emit('close', 1);
188
+ await adapter.send('Retry after settlement');
189
+ expect(errors).toEqual([
190
+ 'Codex emitted malformed structured output. The turn was not marked resumable.',
191
+ ]);
192
+ expect(idle).toHaveLength(1);
193
+ expect(adapter.processes[1].args.slice(0, 4)).toEqual(['exec', '--json', '--color', 'never']);
194
+ });
195
+ it('rejects successful output before a new thread is acknowledged', async () => {
196
+ const adapter = new TestCodexCliAdapter();
197
+ const data = [];
198
+ const errors = [];
199
+ adapter.on('data', (text) => data.push(text));
200
+ adapter.on('error', (error) => errors.push(error.message));
201
+ await adapter.start('C:\\workspace');
202
+ await adapter.send('Start');
203
+ adapter.processes[0].child.stdout.emit('data', Buffer.from(messageRecord()));
204
+ adapter.processes[0].child.emit('close', 0);
205
+ expect(data).toEqual([]);
206
+ expect(errors).toEqual([
207
+ 'Codex completed output without acknowledging a thread identity. The turn was not marked resumable.',
208
+ ]);
209
+ });
210
+ it('accepts UUID case canonicalization and retains the exact requested resume id', async () => {
211
+ const adapter = new TestCodexCliAdapter();
212
+ const requestedId = ID.toUpperCase();
213
+ const sessions = [];
214
+ adapter.on('session', (id) => sessions.push(id));
215
+ await adapter.start('C:\\workspace', { id: requestedId, resume: true });
216
+ await adapter.send('Resume');
217
+ adapter.processes[0].child.stdout.emit('data', Buffer.from(threadRecord() + messageRecord() + completeRecord()));
218
+ adapter.processes[0].child.emit('close', 0);
219
+ await adapter.send('Continue');
220
+ expect(sessions).toEqual([requestedId]);
221
+ expect(adapter.processes[1].args).toContain(requestedId);
222
+ });
223
+ it('rejects a conflicting resume identity and keeps the requested id active', async () => {
224
+ const adapter = new TestCodexCliAdapter();
225
+ const sessions = [];
226
+ const errors = [];
227
+ adapter.on('session', (id) => sessions.push(id));
228
+ adapter.on('error', (error) => errors.push(error.message));
229
+ await adapter.start('C:\\workspace', { id: ID, resume: true });
230
+ await adapter.send('Resume safely');
231
+ adapter.processes[0].child.stdout.emit('data', Buffer.from(threadRecord(OTHER_ID)));
232
+ adapter.processes[0].child.emit('close', 1);
233
+ await adapter.send('Retry the requested session');
234
+ expect(sessions).toEqual([]);
235
+ expect(errors).toEqual([
236
+ 'Codex returned a conflicting thread identity. The unexpected identity was rejected; the active session remains resumable.',
237
+ ]);
238
+ expect(adapter.processes[1].args).toContain(ID);
239
+ });
240
+ it('rejects a later identity change and resumes only the acknowledged id', async () => {
241
+ const adapter = new TestCodexCliAdapter();
242
+ const sessions = [];
243
+ const errors = [];
244
+ adapter.on('session', (id) => sessions.push(id));
245
+ adapter.on('error', (error) => errors.push(error.message));
246
+ await adapter.start('C:\\workspace');
247
+ await adapter.send('Start safely');
248
+ adapter.processes[0].child.stdout.emit('data', Buffer.from(threadRecord() + threadRecord(OTHER_ID) + messageRecord()));
249
+ adapter.processes[0].child.emit('close', 1);
250
+ await adapter.send('Resume safely');
251
+ expect(sessions).toEqual([ID]);
252
+ expect(errors).toEqual([
253
+ 'Codex returned a conflicting thread identity. The unexpected identity was rejected; the active session remains resumable.',
254
+ ]);
255
+ expect(adapter.processes[1].args).toContain(ID);
256
+ });
257
+ it('resumes an acknowledged thread after a structured provider failure', async () => {
258
+ const adapter = new TestCodexCliAdapter();
259
+ const errors = [];
260
+ adapter.on('error', (error) => errors.push(error.message));
261
+ await adapter.start('C:\\workspace');
262
+ await adapter.send('Start');
263
+ adapter.processes[0].child.stdout.emit('data', Buffer.from(threadRecord() + failureRecord()));
264
+ adapter.processes[0].child.emit('close', 1);
265
+ await adapter.send('Resume');
266
+ expect(errors).toEqual(['Permission denied']);
267
+ expect(adapter.processes[1].args).toContain(ID);
268
+ });
269
+ it('reports a crash after assistant output but before turn.completed', async () => {
270
+ const adapter = new TestCodexCliAdapter();
271
+ const data = [];
272
+ const errors = [];
273
+ adapter.on('data', (text) => data.push(text));
274
+ adapter.on('error', (error) => errors.push(error.message));
275
+ await adapter.start('C:\\workspace');
276
+ await adapter.send('Start');
277
+ adapter.processes[0].child.stdout.emit('data', Buffer.from(threadRecord() + messageRecord('Partial')));
278
+ adapter.processes[0].child.emit('close', 1);
279
+ expect(data).toEqual(['Partial']);
280
+ expect(errors).toEqual([
281
+ 'Codex CLI ended before confirming turn completion. The active session remains resumable.',
282
+ ]);
283
+ });
284
+ it('rejects turn.completed without a recognizable assistant response', async () => {
285
+ const adapter = new TestCodexCliAdapter();
286
+ const errors = [];
287
+ adapter.on('error', (error) => errors.push(error.message));
288
+ await adapter.start('C:\\workspace');
289
+ await adapter.send('Start');
290
+ adapter.processes[0].child.stdout.emit('data', Buffer.from(threadRecord() + completeRecord()));
291
+ adapter.processes[0].child.emit('close', 0);
292
+ expect(errors).toEqual([
293
+ 'Codex completed without a recognizable assistant response. The active session remains resumable.',
294
+ ]);
295
+ });
296
+ it('surfaces a successful process with no recognized structured response', async () => {
297
+ const adapter = new TestCodexCliAdapter();
298
+ const errors = [];
299
+ adapter.on('error', (error) => errors.push(error.message));
300
+ await adapter.start('C:\\workspace');
301
+ await adapter.send('Inspect');
302
+ adapter.processes[0].child.stdout.emit('data', Buffer.from('{"type":"turn.started"}\n'));
303
+ adapter.processes[0].child.emit('close', 0);
304
+ expect(errors).toEqual([expect.stringMatching(/without a recognized response/i)]);
305
+ });
306
+ it('leaves a nonzero no-output exit for the base stderr diagnostic', async () => {
307
+ const adapter = new TestCodexCliAdapter();
308
+ const errors = [];
309
+ adapter.on('error', (error) => errors.push(error.message));
310
+ await adapter.start('C:\\workspace');
311
+ await adapter.send('Inspect');
312
+ adapter.processes[0].child.emit('close', 1);
313
+ expect(errors).toEqual(['Codex CLI exited with code 1']);
314
+ });
315
+ });
316
+ //# sourceMappingURL=CodexCliAdapter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodexCliAdapter.test.js","sourceRoot":"","sources":["../../src/agent/CodexCliAdapter.test.ts"],"names":[],"mappings":"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"}