mcp-codex-worker 0.1.24 → 0.1.26

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.
@@ -6,6 +6,7 @@ import { CODEX_CAPABILITIES } from './provider-capabilities.js';
6
6
  import { BaseProviderAdapter, } from './base-adapter.js';
7
7
  import { CodexRuntime } from '../services/codex-runtime.js';
8
8
  import { attachPauseFlow } from './codex-pause-flow.js';
9
+ import { attachEventCapture } from './codex-event-capture.js';
9
10
  import { REQUEST_TIMEOUT_MS } from '../config/defaults.js';
10
11
  // ---------------------------------------------------------------------------
11
12
  // Adapter
@@ -34,11 +35,14 @@ export class CodexAdapter extends BaseProviderAdapter {
34
35
  async executeSession(handle, prompt, _signal, options) {
35
36
  const runtime = this.getRuntime();
36
37
  let detachPauseFlow;
38
+ let detachEventCapture;
37
39
  let removeExitListener;
38
40
  // Clean up listeners only once, regardless of which path triggers it.
39
41
  const cleanup = () => {
40
42
  detachPauseFlow?.();
41
43
  detachPauseFlow = undefined;
44
+ detachEventCapture?.();
45
+ detachEventCapture = undefined;
42
46
  removeExitListener?.();
43
47
  removeExitListener = undefined;
44
48
  };
@@ -62,6 +66,7 @@ export class CodexAdapter extends BaseProviderAdapter {
62
66
  const client = runtime
63
67
  .getCurrentClient();
64
68
  detachPauseFlow = attachPauseFlow(client, handle, threadId);
69
+ detachEventCapture = attachEventCapture(client, handle, threadId);
65
70
  // 3b. Listen for app-server crashes. If the process exits while the
66
71
  // task is paused (WAITING_ANSWER), mark it failed so the
67
72
  // orchestrator doesn't wait on a ghost.
@@ -1 +1 @@
1
- {"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../../../src/execution/codex-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../../../src/execution/codex-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { AppServerClient } from '../services/app-server-client.js';
2
+ import type { TaskHandle } from '../task/task-handle.js';
3
+ /**
4
+ * Listen for `notification` events on the AppServerClient, capture agent
5
+ * messages, command output, file diffs, and errors — writing them to the
6
+ * TaskHandle's output methods. Returns an unsubscribe function.
7
+ */
8
+ export declare function attachEventCapture(client: AppServerClient, handle: TaskHandle, threadId: string): () => void;
@@ -0,0 +1,137 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Helpers
3
+ // ---------------------------------------------------------------------------
4
+ function asObject(value) {
5
+ if (!value || typeof value !== 'object' || Array.isArray(value))
6
+ return undefined;
7
+ return value;
8
+ }
9
+ function asString(value) {
10
+ return typeof value === 'string' ? value : undefined;
11
+ }
12
+ function ts() {
13
+ const d = new Date();
14
+ return [d.getHours(), d.getMinutes(), d.getSeconds()]
15
+ .map(n => String(n).padStart(2, '0'))
16
+ .join(':');
17
+ }
18
+ function truncate(text, max = 200) {
19
+ const oneLine = text.replace(/\n/g, ' ').trim();
20
+ return oneLine.length <= max ? oneLine : oneLine.slice(0, max) + '...';
21
+ }
22
+ function countDiffLines(diff) {
23
+ let added = 0, removed = 0;
24
+ for (const line of diff.split('\n')) {
25
+ if (line.startsWith('+') && !line.startsWith('+++'))
26
+ added++;
27
+ if (line.startsWith('-') && !line.startsWith('---'))
28
+ removed++;
29
+ }
30
+ return { added, removed };
31
+ }
32
+ // ---------------------------------------------------------------------------
33
+ // Attachment: wire event capture onto an AppServerClient + TaskHandle
34
+ // ---------------------------------------------------------------------------
35
+ /**
36
+ * Listen for `notification` events on the AppServerClient, capture agent
37
+ * messages, command output, file diffs, and errors — writing them to the
38
+ * TaskHandle's output methods. Returns an unsubscribe function.
39
+ */
40
+ export function attachEventCapture(client, handle, threadId) {
41
+ const agentMessageBuffers = new Map();
42
+ const commandOutputBuffers = new Map();
43
+ const onNotification = (notification) => {
44
+ const params = asObject(notification.params);
45
+ if (asString(params?.threadId) !== threadId)
46
+ return;
47
+ switch (notification.method) {
48
+ // -- agent message deltas -----------------------------------------------
49
+ case 'item/agentMessage/delta': {
50
+ const itemId = asString(params?.itemId);
51
+ const delta = asString(params?.delta);
52
+ if (!itemId || !delta)
53
+ break;
54
+ const existing = agentMessageBuffers.get(itemId) ?? '';
55
+ agentMessageBuffers.set(itemId, existing + delta);
56
+ break;
57
+ }
58
+ // -- command output deltas ----------------------------------------------
59
+ case 'item/commandExecution/outputDelta': {
60
+ const itemId = asString(params?.itemId);
61
+ const delta = asString(params?.delta);
62
+ if (!itemId || !delta)
63
+ break;
64
+ const existing = commandOutputBuffers.get(itemId) ?? '';
65
+ commandOutputBuffers.set(itemId, existing + delta);
66
+ handle.writeOutputFileOnly(delta);
67
+ break;
68
+ }
69
+ // -- item completed -----------------------------------------------------
70
+ case 'item/completed': {
71
+ const item = asObject(params?.item);
72
+ const itemType = asString(item?.type);
73
+ const itemId = asString(item?.id);
74
+ if (itemType === 'agentMessage') {
75
+ const text = (itemId ? agentMessageBuffers.get(itemId) : undefined)
76
+ ?? asString(item?.text) ?? '';
77
+ handle.writeOutput(`[${ts()}] agent: ${truncate(text)}`);
78
+ handle.writeOutputFileOnly(`[${ts()}] === agent message ===\n${text}`);
79
+ if (itemId)
80
+ agentMessageBuffers.delete(itemId);
81
+ }
82
+ else if (itemType === 'commandExecution') {
83
+ const command = asString(item?.command) ?? 'unknown';
84
+ const exitCode = typeof item?.exitCode === 'number' ? item.exitCode : undefined;
85
+ const durationMs = typeof item?.durationMs === 'number' ? item.durationMs : undefined;
86
+ const duration = durationMs !== undefined ? (durationMs / 1000).toFixed(1) + 's' : '';
87
+ handle.writeOutput(`[${ts()}] cmd: ${command} (exit ${exitCode ?? '?'}${duration ? ', ' + duration : ''})`);
88
+ if (itemId) {
89
+ const accumulated = commandOutputBuffers.get(itemId);
90
+ if (accumulated) {
91
+ handle.writeOutputFileOnly(`[${ts()}] === command output: ${command} ===\n${accumulated}`);
92
+ }
93
+ commandOutputBuffers.delete(itemId);
94
+ }
95
+ }
96
+ else if (itemType === 'fileChange') {
97
+ const changes = Array.isArray(item?.changes) ? item.changes : [];
98
+ for (const raw of changes) {
99
+ const change = asObject(raw);
100
+ if (!change)
101
+ continue;
102
+ const path = asString(change.path) ?? 'unknown';
103
+ const diff = asString(change.diff) ?? '';
104
+ const { added, removed } = countDiffLines(diff);
105
+ handle.writeOutput(`[${ts()}] edit: ${path} (+${added} -${removed})`);
106
+ handle.writeOutputFileOnly(`[${ts()}] === file diff: ${path} ===\n${diff}`);
107
+ }
108
+ }
109
+ break;
110
+ }
111
+ // -- turn diff ----------------------------------------------------------
112
+ case 'turn/diff/updated': {
113
+ const diff = asString(params?.diff);
114
+ if (diff) {
115
+ handle.writeOutputFileOnly(`[${ts()}] === turn diff ===\n${diff}`);
116
+ }
117
+ break;
118
+ }
119
+ // -- error --------------------------------------------------------------
120
+ case 'error': {
121
+ const errorObj = asObject(params?.error);
122
+ const message = asString(errorObj?.message) ?? asString(params?.message) ?? 'unknown';
123
+ const codexErrorInfo = asString(errorObj?.codexErrorInfo) ?? asString(params?.codexErrorInfo) ?? 'unknown';
124
+ handle.writeOutput(`[${ts()}] ERROR: ${codexErrorInfo} — ${truncate(message)}`);
125
+ handle.writeOutputFileOnly(`[${ts()}] === error ===\n${message}\ncodexErrorInfo: ${codexErrorInfo}`);
126
+ break;
127
+ }
128
+ default:
129
+ break;
130
+ }
131
+ };
132
+ client.on('notification', onNotification);
133
+ return () => {
134
+ client.off('notification', onNotification);
135
+ };
136
+ }
137
+ //# sourceMappingURL=codex-event-capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-event-capture.js","sourceRoot":"","sources":["../../../src/execution/codex-event-capture.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-codex-worker",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "description": "MCP server bridge for Codex app-server",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -15,6 +15,7 @@ import {
15
15
  import { CodexRuntime } from '../services/codex-runtime.js';
16
16
  import type { AppServerClient } from '../services/app-server-client.js';
17
17
  import { attachPauseFlow } from './codex-pause-flow.js';
18
+ import { attachEventCapture } from './codex-event-capture.js';
18
19
  import { REQUEST_TIMEOUT_MS } from '../config/defaults.js';
19
20
 
20
21
  // ---------------------------------------------------------------------------
@@ -67,12 +68,15 @@ export class CodexAdapter extends BaseProviderAdapter {
67
68
  ): Promise<void> {
68
69
  const runtime = this.getRuntime();
69
70
  let detachPauseFlow: (() => void) | undefined;
71
+ let detachEventCapture: (() => void) | undefined;
70
72
  let removeExitListener: (() => void) | undefined;
71
73
 
72
74
  // Clean up listeners only once, regardless of which path triggers it.
73
75
  const cleanup = () => {
74
76
  detachPauseFlow?.();
75
77
  detachPauseFlow = undefined;
78
+ detachEventCapture?.();
79
+ detachEventCapture = undefined;
76
80
  removeExitListener?.();
77
81
  removeExitListener = undefined;
78
82
  };
@@ -101,6 +105,7 @@ export class CodexAdapter extends BaseProviderAdapter {
101
105
  const client = (runtime as unknown as { getCurrentClient(): AppServerClient })
102
106
  .getCurrentClient();
103
107
  detachPauseFlow = attachPauseFlow(client, handle, threadId);
108
+ detachEventCapture = attachEventCapture(client, handle, threadId);
104
109
 
105
110
  // 3b. Listen for app-server crashes. If the process exits while the
106
111
  // task is paused (WAITING_ANSWER), mark it failed so the
@@ -0,0 +1,156 @@
1
+ import type { AppServerClient } from '../services/app-server-client.js';
2
+ import type { TaskHandle } from '../task/task-handle.js';
3
+ import type { JsonLineNotification } from '../types/codex.js';
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Helpers
7
+ // ---------------------------------------------------------------------------
8
+
9
+ function asObject(value: unknown): Record<string, unknown> | undefined {
10
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;
11
+ return value as Record<string, unknown>;
12
+ }
13
+
14
+ function asString(value: unknown): string | undefined {
15
+ return typeof value === 'string' ? value : undefined;
16
+ }
17
+
18
+ function ts(): string {
19
+ const d = new Date();
20
+ return [d.getHours(), d.getMinutes(), d.getSeconds()]
21
+ .map(n => String(n).padStart(2, '0'))
22
+ .join(':');
23
+ }
24
+
25
+ function truncate(text: string, max = 200): string {
26
+ const oneLine = text.replace(/\n/g, ' ').trim();
27
+ return oneLine.length <= max ? oneLine : oneLine.slice(0, max) + '...';
28
+ }
29
+
30
+ function countDiffLines(diff: string): { added: number; removed: number } {
31
+ let added = 0, removed = 0;
32
+ for (const line of diff.split('\n')) {
33
+ if (line.startsWith('+') && !line.startsWith('+++')) added++;
34
+ if (line.startsWith('-') && !line.startsWith('---')) removed++;
35
+ }
36
+ return { added, removed };
37
+ }
38
+
39
+ // ---------------------------------------------------------------------------
40
+ // Attachment: wire event capture onto an AppServerClient + TaskHandle
41
+ // ---------------------------------------------------------------------------
42
+
43
+ /**
44
+ * Listen for `notification` events on the AppServerClient, capture agent
45
+ * messages, command output, file diffs, and errors — writing them to the
46
+ * TaskHandle's output methods. Returns an unsubscribe function.
47
+ */
48
+ export function attachEventCapture(
49
+ client: AppServerClient,
50
+ handle: TaskHandle,
51
+ threadId: string,
52
+ ): () => void {
53
+ const agentMessageBuffers = new Map<string, string>();
54
+ const commandOutputBuffers = new Map<string, string>();
55
+
56
+ const onNotification = (notification: JsonLineNotification) => {
57
+ const params = asObject(notification.params);
58
+ if (asString(params?.threadId) !== threadId) return;
59
+
60
+ switch (notification.method) {
61
+ // -- agent message deltas -----------------------------------------------
62
+ case 'item/agentMessage/delta': {
63
+ const itemId = asString(params?.itemId);
64
+ const delta = asString(params?.delta);
65
+ if (!itemId || !delta) break;
66
+ const existing = agentMessageBuffers.get(itemId) ?? '';
67
+ agentMessageBuffers.set(itemId, existing + delta);
68
+ break;
69
+ }
70
+
71
+ // -- command output deltas ----------------------------------------------
72
+ case 'item/commandExecution/outputDelta': {
73
+ const itemId = asString(params?.itemId);
74
+ const delta = asString(params?.delta);
75
+ if (!itemId || !delta) break;
76
+ const existing = commandOutputBuffers.get(itemId) ?? '';
77
+ commandOutputBuffers.set(itemId, existing + delta);
78
+ handle.writeOutputFileOnly(delta);
79
+ break;
80
+ }
81
+
82
+ // -- item completed -----------------------------------------------------
83
+ case 'item/completed': {
84
+ const item = asObject(params?.item);
85
+ const itemType = asString(item?.type);
86
+ const itemId = asString(item?.id);
87
+
88
+ if (itemType === 'agentMessage') {
89
+ const text = (itemId ? agentMessageBuffers.get(itemId) : undefined)
90
+ ?? asString(item?.text) ?? '';
91
+ handle.writeOutput(`[${ts()}] agent: ${truncate(text)}`);
92
+ handle.writeOutputFileOnly(`[${ts()}] === agent message ===\n${text}`);
93
+ if (itemId) agentMessageBuffers.delete(itemId);
94
+ } else if (itemType === 'commandExecution') {
95
+ const command = asString(item?.command) ?? 'unknown';
96
+ const exitCode = typeof item?.exitCode === 'number' ? item.exitCode : undefined;
97
+ const durationMs = typeof item?.durationMs === 'number' ? item.durationMs : undefined;
98
+ const duration = durationMs !== undefined ? (durationMs / 1000).toFixed(1) + 's' : '';
99
+ handle.writeOutput(
100
+ `[${ts()}] cmd: ${command} (exit ${exitCode ?? '?'}${duration ? ', ' + duration : ''})`,
101
+ );
102
+ if (itemId) {
103
+ const accumulated = commandOutputBuffers.get(itemId);
104
+ if (accumulated) {
105
+ handle.writeOutputFileOnly(
106
+ `[${ts()}] === command output: ${command} ===\n${accumulated}`,
107
+ );
108
+ }
109
+ commandOutputBuffers.delete(itemId);
110
+ }
111
+ } else if (itemType === 'fileChange') {
112
+ const changes = Array.isArray(item?.changes) ? (item.changes as unknown[]) : [];
113
+ for (const raw of changes) {
114
+ const change = asObject(raw);
115
+ if (!change) continue;
116
+ const path = asString(change.path) ?? 'unknown';
117
+ const diff = asString(change.diff) ?? '';
118
+ const { added, removed } = countDiffLines(diff);
119
+ handle.writeOutput(`[${ts()}] edit: ${path} (+${added} -${removed})`);
120
+ handle.writeOutputFileOnly(`[${ts()}] === file diff: ${path} ===\n${diff}`);
121
+ }
122
+ }
123
+ break;
124
+ }
125
+
126
+ // -- turn diff ----------------------------------------------------------
127
+ case 'turn/diff/updated': {
128
+ const diff = asString(params?.diff);
129
+ if (diff) {
130
+ handle.writeOutputFileOnly(`[${ts()}] === turn diff ===\n${diff}`);
131
+ }
132
+ break;
133
+ }
134
+
135
+ // -- error --------------------------------------------------------------
136
+ case 'error': {
137
+ const errorObj = asObject(params?.error);
138
+ const message = asString(errorObj?.message) ?? asString(params?.message) ?? 'unknown';
139
+ const codexErrorInfo = asString(errorObj?.codexErrorInfo) ?? asString(params?.codexErrorInfo) ?? 'unknown';
140
+ handle.writeOutput(`[${ts()}] ERROR: ${codexErrorInfo} — ${truncate(message)}`);
141
+ handle.writeOutputFileOnly(
142
+ `[${ts()}] === error ===\n${message}\ncodexErrorInfo: ${codexErrorInfo}`,
143
+ );
144
+ break;
145
+ }
146
+
147
+ default:
148
+ break;
149
+ }
150
+ };
151
+
152
+ client.on('notification', onNotification);
153
+ return () => {
154
+ client.off('notification', onNotification);
155
+ };
156
+ }