@alpacakit/agents 0.1.0-beta.39 → 0.2.0-beta.2

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 (53) hide show
  1. package/README.md +121 -1
  2. package/dist/agents/claude-session.d.ts +37 -0
  3. package/dist/agents/claude-session.d.ts.map +1 -0
  4. package/dist/agents/claude-session.js +419 -0
  5. package/dist/agents/claude-stream.d.ts +65 -0
  6. package/dist/agents/claude-stream.d.ts.map +1 -0
  7. package/dist/agents/claude-stream.js +111 -0
  8. package/dist/agents/claude.d.ts +2 -1
  9. package/dist/agents/claude.d.ts.map +1 -1
  10. package/dist/agents/claude.js +6 -107
  11. package/dist/agents/codex-session.d.ts +52 -0
  12. package/dist/agents/codex-session.d.ts.map +1 -0
  13. package/dist/agents/codex-session.js +495 -0
  14. package/dist/agents/codex.d.ts +2 -1
  15. package/dist/agents/codex.d.ts.map +1 -1
  16. package/dist/agents/codex.js +3 -1
  17. package/dist/codex/app-server.d.ts +50 -1
  18. package/dist/codex/app-server.d.ts.map +1 -1
  19. package/dist/codex/app-server.js +130 -27
  20. package/dist/codex/index.d.ts +3 -2
  21. package/dist/codex/index.d.ts.map +1 -1
  22. package/dist/codex/index.js +2 -1
  23. package/dist/codex/protocol.d.ts +101 -0
  24. package/dist/codex/protocol.d.ts.map +1 -1
  25. package/dist/codex/protocol.js +78 -0
  26. package/dist/core/process-close.d.ts +11 -0
  27. package/dist/core/process-close.d.ts.map +1 -0
  28. package/dist/core/process-close.js +27 -0
  29. package/dist/core/session.d.ts +100 -0
  30. package/dist/core/session.d.ts.map +1 -0
  31. package/dist/core/session.js +29 -0
  32. package/dist/host/session-files.d.ts +22 -0
  33. package/dist/host/session-files.d.ts.map +1 -0
  34. package/dist/host/session-files.js +91 -0
  35. package/dist/index.d.ts +7 -2
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +3 -0
  38. package/dist/internal/controlled-process/supervisor-runtime.js +27 -1
  39. package/dist/kernel/definition.d.ts +11 -2
  40. package/dist/kernel/definition.d.ts.map +1 -1
  41. package/dist/kernel/facets.d.ts +38 -1
  42. package/dist/kernel/facets.d.ts.map +1 -1
  43. package/dist/kernel/facets.js +20 -0
  44. package/dist/kernel/runtime.d.ts +10 -6
  45. package/dist/kernel/runtime.d.ts.map +1 -1
  46. package/dist/kernel/runtime.js +4 -1
  47. package/dist/kernel/session.d.ts +97 -0
  48. package/dist/kernel/session.d.ts.map +1 -0
  49. package/dist/kernel/session.js +255 -0
  50. package/dist/testing/fake-exec.d.ts +6 -0
  51. package/dist/testing/fake-exec.d.ts.map +1 -1
  52. package/dist/testing/fake-exec.js +3 -1
  53. package/package.json +2 -2
@@ -1,8 +1,24 @@
1
+ /**
2
+ * Codex app-server client over stdio JSON-RPC. One client is one child
3
+ * process, held as long as the caller wants: host-plane calls create one
4
+ * per call (`withCodexAppServer`), a Session keeps one for the thread's
5
+ * whole life. Both directions are modeled — client requests get typed,
6
+ * decoded results; server notifications and server-initiated requests
7
+ * (approval prompts) arrive on `incoming`, and `respond` answers the latter.
8
+ * A request timeout fails that request only; it never kills the process,
9
+ * because a Session's other traffic shares it.
10
+ */
11
+ import { AsyncQueue } from "../core/async-queue.js";
1
12
  import { AGENT_ERROR_CODE, AgentError, NOT_AVAILABLE_CAUSE, TIMEOUT_KIND, } from "../core/error.js";
2
13
  import { readJsonRecord } from "../core/json.js";
3
14
  import { redactSecrets } from "../core/redact.js";
4
- import { OUTPUT_CHANNEL, PROCESS_SIGNAL } from "../core/values.js";
15
+ import { endProcessGracefully } from "../core/process-close.js";
16
+ import { OUTPUT_CHANNEL } from "../core/values.js";
5
17
  import { CODEX_APP_SERVER_METHOD, CODEX_APP_SERVER_RESULT_DECODERS, CODEX_MCP_STATUS_DETAIL, } from "./protocol.js";
18
+ export const CODEX_INCOMING_KIND = {
19
+ notification: "notification",
20
+ request: "request",
21
+ };
6
22
  const DEFAULT_CODEX_COMMAND = "codex";
7
23
  const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
8
24
  const APP_SERVER_ARGS = ["app-server"];
@@ -14,7 +30,7 @@ const APP_SERVER_ARGS = ["app-server"];
14
30
  const DEFAULT_APP_SERVER_CLIENT_INFO = {
15
31
  name: "agents",
16
32
  title: "Agents",
17
- version: "0.1.0",
33
+ version: "0.2.0",
18
34
  };
19
35
  const OUTPUT_TAIL_CHARS = 2_000;
20
36
  const MCP_PAGE_LIMIT = 500;
@@ -23,6 +39,7 @@ const JSON_RPC_FRAME_BOUNDARY = /\r?\n/u;
23
39
  const JSON_RPC_FIELD = {
24
40
  id: "id",
25
41
  method: "method",
42
+ params: "params",
26
43
  result: "result",
27
44
  error: "error",
28
45
  message: "message",
@@ -61,23 +78,65 @@ class ExecCodexAppServer {
61
78
  nextId = 1;
62
79
  stderr = "";
63
80
  stdoutLine = "";
81
+ /** Set by close(); no child is spawned after it. */
82
+ closing = false;
83
+ /** Set once every stream has ended (the child exited, or close() found none). */
84
+ closed = false;
64
85
  pending = new Map();
86
+ subscribers = new Set();
87
+ settleExit = () => { };
88
+ exit;
89
+ get stderrTail() {
90
+ return this.stderr;
91
+ }
65
92
  constructor(options) {
66
93
  this.options = options;
94
+ this.exit = new Promise((resolve) => {
95
+ this.settleExit = resolve;
96
+ });
97
+ }
98
+ get incoming() {
99
+ return {
100
+ [Symbol.asyncIterator]: () => {
101
+ const queue = new AsyncQueue();
102
+ if (this.closed) {
103
+ queue.end();
104
+ }
105
+ else {
106
+ this.subscribers.add(queue);
107
+ }
108
+ return queue[Symbol.asyncIterator]();
109
+ },
110
+ };
67
111
  }
68
112
  async request(method, params) {
69
113
  await this.connect();
70
114
  return this.sendRequest(method, params);
71
115
  }
116
+ respond(id, answer) {
117
+ const process = this.process;
118
+ if (process === null) {
119
+ // A request that arrives while the server is closing has nobody left
120
+ // to answer; dropping it is the only honest option.
121
+ return;
122
+ }
123
+ process.writeStdin(`${JSON.stringify({ id, ...answer })}${JSON_RPC_FRAME_SEPARATOR}`);
124
+ }
72
125
  async close() {
126
+ this.closing = true;
73
127
  const process = this.process;
74
128
  this.process = null;
75
129
  this.initialized = false;
76
- if (process !== null) {
77
- process.endStdin();
78
- process.kill(PROCESS_SIGNAL.sigterm);
79
- }
80
130
  this.rejectAll(appServerClosedError());
131
+ if (process === null) {
132
+ this.finish({ code: null, signal: null });
133
+ return;
134
+ }
135
+ // EOF is what makes the server exit cleanly — it removes the thread
136
+ // writer lock on the way out, which a SIGTERM-ed server leaves behind
137
+ // (T61 lab). Signals follow only for a server that does not exit on EOF.
138
+ await endProcessGracefully(process, this.options.clock);
139
+ await this.exit;
81
140
  }
82
141
  async connect() {
83
142
  if (this.initialized) {
@@ -103,7 +162,14 @@ class ExecCodexAppServer {
103
162
  this.initialized = true;
104
163
  }
105
164
  async startProcess() {
165
+ if (this.closing) {
166
+ throw appServerClosedError();
167
+ }
106
168
  const command = await this.options.exec.which(this.options.command, this.options.env);
169
+ if (this.closing) {
170
+ // close() ran while PATH was being resolved: spawning now would orphan a child.
171
+ throw appServerClosedError();
172
+ }
107
173
  if (command === null) {
108
174
  throw new AgentError({
109
175
  code: AGENT_ERROR_CODE.notAvailable,
@@ -124,6 +190,7 @@ class ExecCodexAppServer {
124
190
  void this.readProcess(process);
125
191
  }
126
192
  async readProcess(process) {
193
+ let exit = { code: null, signal: null };
127
194
  try {
128
195
  for await (const chunk of process.chunks) {
129
196
  if (chunk.channel === OUTPUT_CHANNEL.stderr) {
@@ -133,30 +200,57 @@ class ExecCodexAppServer {
133
200
  this.handleStdout(chunk.text);
134
201
  }
135
202
  }
136
- const exit = await process.exit;
203
+ exit = await process.exit;
204
+ this.rejectAll(appServerExitedError(exit.code, this.stderr));
205
+ }
206
+ catch (error) {
207
+ this.rejectAll(appServerExitedError(null, error instanceof Error ? error.message : ""));
208
+ }
209
+ finally {
137
210
  if (this.process === process) {
138
211
  this.process = null;
139
212
  this.initialized = false;
140
213
  }
141
- if (this.pending.size > 0) {
142
- this.rejectAll(appServerExitedError(exit.code, this.stderr));
143
- }
214
+ this.finish(exit);
144
215
  }
145
- catch (error) {
146
- this.rejectAll(appServerExitedError(null, error instanceof Error ? error.message : ""));
216
+ }
217
+ /** The child is gone (or was never started and we closed): end every stream once. */
218
+ finish(exit) {
219
+ if (this.closed) {
220
+ return;
221
+ }
222
+ this.closed = true;
223
+ for (const queue of this.subscribers) {
224
+ queue.end();
147
225
  }
226
+ this.subscribers.clear();
227
+ this.settleExit(exit);
148
228
  }
149
229
  handleStdout(text) {
150
230
  this.stdoutLine += text;
151
231
  const lines = this.stdoutLine.split(JSON_RPC_FRAME_BOUNDARY);
152
232
  this.stdoutLine = lines.pop() ?? "";
153
233
  for (const line of lines) {
154
- const response = parseResponseLine(line);
234
+ const record = readJsonRecord(line.trim());
235
+ if (record === null) {
236
+ continue;
237
+ }
238
+ const incoming = parseIncoming(record);
239
+ if (incoming !== null) {
240
+ this.publish(incoming);
241
+ continue;
242
+ }
243
+ const response = parseResponse(record);
155
244
  if (response !== null) {
156
245
  this.handleResponse(response);
157
246
  }
158
247
  }
159
248
  }
249
+ publish(incoming) {
250
+ for (const queue of this.subscribers) {
251
+ queue.push(incoming);
252
+ }
253
+ }
160
254
  sendRequest(method, params) {
161
255
  const process = this.process;
162
256
  if (process === null) {
@@ -165,14 +259,11 @@ class ExecCodexAppServer {
165
259
  const id = this.nextId;
166
260
  this.nextId += 1;
167
261
  return new Promise((resolve, reject) => {
262
+ // A timeout fails only this request. JSON-RPC has no per-call
263
+ // cancellation, but a Session's other turns share this process, so the
264
+ // client never kills it on a slow answer; `close()` is the caller's call.
168
265
  const cancelTimeout = this.options.clock.setTimeout(() => {
169
266
  this.pending.delete(id);
170
- // A timeout kills the whole server, not just this request: JSON-RPC
171
- // gives no per-call cancellation, and a hung app-server cannot be
172
- // trusted with further requests. Other in-flight requests are then
173
- // rejected as `failed` by the exit path; clients are created per
174
- // host-plane call, so the blast radius is that one call.
175
- process.kill(PROCESS_SIGNAL.sigkill);
176
267
  reject(new AgentError({
177
268
  code: AGENT_ERROR_CODE.timeout,
178
269
  classification: AgentError.agentFailure(AGENT_ERROR_CODE.timeout),
@@ -249,17 +340,29 @@ function appendTail(current, next) {
249
340
  ? combined
250
341
  : combined.slice(-OUTPUT_TAIL_CHARS);
251
342
  }
252
- function parseResponseLine(line) {
253
- const record = readJsonRecord(line.trim());
254
- if (record === null) {
343
+ /**
344
+ * Server-originated frames carry `method`; a response never does. Their id
345
+ * space is the server's own, so an id on such a frame marks a request the
346
+ * server awaits an answer to, not one of our pending requests.
347
+ */
348
+ function parseIncoming(record) {
349
+ const method = record[JSON_RPC_FIELD.method];
350
+ if (typeof method !== "string") {
255
351
  return null;
256
352
  }
257
- // Server-initiated requests and notifications carry `method`; a JSON-RPC
258
- // response never does. Their id space is the server's own, so treating
259
- // them as responses would resolve an unrelated pending client request.
260
- if (record[JSON_RPC_FIELD.method] !== undefined) {
261
- return null;
353
+ const paramsValue = record[JSON_RPC_FIELD.params];
354
+ const params = typeof paramsValue === "object" &&
355
+ paramsValue !== null &&
356
+ !Array.isArray(paramsValue)
357
+ ? paramsValue
358
+ : null;
359
+ const id = record[JSON_RPC_FIELD.id];
360
+ if (typeof id === "number" || typeof id === "string") {
361
+ return { kind: CODEX_INCOMING_KIND.request, id, method, params };
262
362
  }
363
+ return { kind: CODEX_INCOMING_KIND.notification, method, params };
364
+ }
365
+ function parseResponse(record) {
263
366
  const id = record[JSON_RPC_FIELD.id];
264
367
  if (typeof id !== "number") {
265
368
  return null;
@@ -1,3 +1,4 @@
1
- export { type AppServerClientInfo, type CodexAppServer, type CodexAppServerOptions, createCodexAppServer, listAllCodexMcpServerStatuses, withCodexAppServer, } from "./app-server.js";
2
- export type { CodexAppServerMethods, CodexMcpServerStatus, CodexMcpServerStatusPage, CodexPluginInstallResult, CodexPluginListResult, CodexPluginMarketplace, CodexPluginSummary, CodexSkillListResult, } from "./protocol.js";
1
+ export { type AppServerClientInfo, CODEX_INCOMING_KIND, type CodexAppServer, type CodexAppServerOptions, type CodexIncoming, type CodexServerRequestAnswer, type CodexServerRequestId, createCodexAppServer, listAllCodexMcpServerStatuses, withCodexAppServer, } from "./app-server.js";
2
+ export { CODEX_APP_SERVER_INCOMING, CODEX_APP_SERVER_METHOD, CODEX_SANDBOX_MODE, encodeCodexThreadPermissions, } from "./protocol.js";
3
+ export type { CodexAppServerMethods, CodexConfigOverrides, CodexSandboxMode, CodexThreadPermissionParams, CodexThreadPermissionWireParams, CodexThreadRef, CodexTurnRef, CodexUserInput, CodexWorkspaceWriteConfig, CodexMcpServerStatus, CodexMcpServerStatusPage, CodexPluginInstallResult, CodexPluginListResult, CodexPluginMarketplace, CodexPluginSummary, CodexSkillListResult, } from "./protocol.js";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codex/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,6BAA6B,EAC7B,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codex/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,mBAAmB,EACnB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,oBAAoB,EACpB,6BAA6B,EAC7B,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,kBAAkB,EAClB,4BAA4B,GAC7B,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,2BAA2B,EAC3B,+BAA+B,EAC/B,cAAc,EACd,YAAY,EACZ,cAAc,EACd,yBAAyB,EACzB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,eAAe,CAAC"}
@@ -1 +1,2 @@
1
- export { createCodexAppServer, listAllCodexMcpServerStatuses, withCodexAppServer, } from "./app-server.js";
1
+ export { CODEX_INCOMING_KIND, createCodexAppServer, listAllCodexMcpServerStatuses, withCodexAppServer, } from "./app-server.js";
2
+ export { CODEX_APP_SERVER_INCOMING, CODEX_APP_SERVER_METHOD, CODEX_SANDBOX_MODE, encodeCodexThreadPermissions, } from "./protocol.js";
@@ -15,6 +15,65 @@ export declare const CODEX_APP_SERVER_METHOD: {
15
15
  readonly pluginInstall: "plugin/install";
16
16
  readonly skillsList: "skills/list";
17
17
  readonly mcpServerStatusList: "mcpServerStatus/list";
18
+ readonly threadStart: "thread/start";
19
+ readonly threadResume: "thread/resume";
20
+ readonly threadUnarchive: "thread/unarchive";
21
+ readonly turnStart: "turn/start";
22
+ readonly turnSteer: "turn/steer";
23
+ readonly turnInterrupt: "turn/interrupt";
24
+ };
25
+ /** Notifications and server-initiated requests the session adapter reads. */
26
+ export declare const CODEX_APP_SERVER_INCOMING: {
27
+ readonly itemStarted: "item/started";
28
+ readonly itemCompleted: "item/completed";
29
+ readonly turnCompleted: "turn/completed";
30
+ readonly commandExecutionRequestApproval: "item/commandExecution/requestApproval";
31
+ readonly fileChangeRequestApproval: "item/fileChange/requestApproval";
32
+ };
33
+ /** `thread/start` / `thread/resume` sandbox words (codex 0.153.4 `SandboxMode`). */
34
+ export declare const CODEX_SANDBOX_MODE: {
35
+ readonly readOnly: "read-only";
36
+ readonly workspaceWrite: "workspace-write";
37
+ readonly dangerFullAccess: "danger-full-access";
38
+ };
39
+ export type CodexSandboxMode = (typeof CODEX_SANDBOX_MODE)[keyof typeof CODEX_SANDBOX_MODE];
40
+ /**
41
+ * `workspace-write` details travel as config.toml overrides on
42
+ * `thread/start` / `thread/resume` (`config`), the same keys
43
+ * `codex -c sandbox_workspace_write.*` takes.
44
+ */
45
+ export type CodexWorkspaceWriteConfig = {
46
+ readonly writableRoots: readonly string[];
47
+ readonly networkAccess: boolean;
48
+ readonly excludeTmpdirEnvVar: boolean;
49
+ readonly excludeSlashTmp: boolean;
50
+ };
51
+ export type CodexThreadPermissionParams = {
52
+ readonly sandbox: CodexSandboxMode;
53
+ readonly approvalPolicy: string;
54
+ readonly approvalsReviewer: string;
55
+ readonly workspaceWrite: CodexWorkspaceWriteConfig | null;
56
+ };
57
+ type CodexConfigScalar = boolean | string | readonly string[];
58
+ /** A `config.toml` override object as `thread/start` / `thread/resume` take it. */
59
+ export type CodexConfigOverrides = Readonly<Record<string, Readonly<Record<string, CodexConfigScalar>>>>;
60
+ /** The wire shape of the permission params (`config` carries workspace-write). */
61
+ export type CodexThreadPermissionWireParams = {
62
+ readonly sandbox: CodexSandboxMode;
63
+ readonly approvalPolicy: string;
64
+ readonly approvalsReviewer: string;
65
+ readonly config: CodexConfigOverrides | null;
66
+ };
67
+ export declare function encodeCodexThreadPermissions(input: CodexThreadPermissionParams): CodexThreadPermissionWireParams;
68
+ export type CodexThreadRef = {
69
+ readonly threadId: string;
70
+ };
71
+ export type CodexTurnRef = {
72
+ readonly turnId: string;
73
+ };
74
+ export type CodexUserInput = {
75
+ readonly type: "text";
76
+ readonly text: string;
18
77
  };
19
78
  export declare const CODEX_MCP_STATUS_DETAIL: {
20
79
  readonly toolsAndAuthOnly: "toolsAndAuthOnly";
@@ -116,9 +175,51 @@ export type CodexAppServerMethods = {
116
175
  };
117
176
  readonly result: CodexMcpServerStatusPage;
118
177
  };
178
+ [CODEX_APP_SERVER_METHOD.threadStart]: {
179
+ readonly params: {
180
+ readonly cwd: string;
181
+ } & CodexThreadPermissionWireParams;
182
+ readonly result: CodexThreadRef;
183
+ };
184
+ [CODEX_APP_SERVER_METHOD.threadResume]: {
185
+ readonly params: {
186
+ readonly threadId: string;
187
+ readonly excludeTurns: boolean;
188
+ } & CodexThreadPermissionWireParams;
189
+ readonly result: CodexThreadRef;
190
+ };
191
+ [CODEX_APP_SERVER_METHOD.threadUnarchive]: {
192
+ readonly params: {
193
+ readonly threadId: string;
194
+ };
195
+ readonly result: CodexThreadRef;
196
+ };
197
+ [CODEX_APP_SERVER_METHOD.turnStart]: {
198
+ readonly params: {
199
+ readonly threadId: string;
200
+ readonly input: readonly CodexUserInput[];
201
+ };
202
+ readonly result: CodexTurnRef;
203
+ };
204
+ [CODEX_APP_SERVER_METHOD.turnSteer]: {
205
+ readonly params: {
206
+ readonly threadId: string;
207
+ readonly expectedTurnId: string;
208
+ readonly input: readonly CodexUserInput[];
209
+ };
210
+ readonly result: CodexTurnRef;
211
+ };
212
+ [CODEX_APP_SERVER_METHOD.turnInterrupt]: {
213
+ readonly params: {
214
+ readonly threadId: string;
215
+ readonly turnId: string;
216
+ };
217
+ readonly result: Readonly<Record<string, never>>;
218
+ };
119
219
  };
120
220
  export type CodexAppServerResultDecoder<M extends keyof CodexAppServerMethods> = (value: unknown) => CodexAppServerMethods[M]["result"] | null;
121
221
  export declare const CODEX_APP_SERVER_RESULT_DECODERS: {
122
222
  readonly [M in keyof CodexAppServerMethods]: CodexAppServerResultDecoder<M>;
123
223
  };
224
+ export {};
124
225
  //# sourceMappingURL=protocol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/codex/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/codex/protocol.ts"],"names":[],"mappings":"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"}
@@ -16,7 +16,53 @@ export const CODEX_APP_SERVER_METHOD = {
16
16
  pluginInstall: "plugin/install",
17
17
  skillsList: "skills/list",
18
18
  mcpServerStatusList: "mcpServerStatus/list",
19
+ threadStart: "thread/start",
20
+ threadResume: "thread/resume",
21
+ threadUnarchive: "thread/unarchive",
22
+ turnStart: "turn/start",
23
+ turnSteer: "turn/steer",
24
+ turnInterrupt: "turn/interrupt",
19
25
  };
26
+ /** Notifications and server-initiated requests the session adapter reads. */
27
+ export const CODEX_APP_SERVER_INCOMING = {
28
+ itemStarted: "item/started",
29
+ itemCompleted: "item/completed",
30
+ turnCompleted: "turn/completed",
31
+ commandExecutionRequestApproval: "item/commandExecution/requestApproval",
32
+ fileChangeRequestApproval: "item/fileChange/requestApproval",
33
+ };
34
+ /** `thread/start` / `thread/resume` sandbox words (codex 0.153.4 `SandboxMode`). */
35
+ export const CODEX_SANDBOX_MODE = {
36
+ readOnly: "read-only",
37
+ workspaceWrite: "workspace-write",
38
+ dangerFullAccess: "danger-full-access",
39
+ };
40
+ /** config.toml keys, spelled once (`codex -c sandbox_workspace_write.writable_roots=…`). */
41
+ const CODEX_CONFIG_KEY = {
42
+ sandboxWorkspaceWrite: "sandbox_workspace_write",
43
+ writableRoots: "writable_roots",
44
+ networkAccess: "network_access",
45
+ excludeTmpdirEnvVar: "exclude_tmpdir_env_var",
46
+ excludeSlashTmp: "exclude_slash_tmp",
47
+ };
48
+ export function encodeCodexThreadPermissions(input) {
49
+ const workspaceWrite = input.workspaceWrite;
50
+ return {
51
+ sandbox: input.sandbox,
52
+ approvalPolicy: input.approvalPolicy,
53
+ approvalsReviewer: input.approvalsReviewer,
54
+ config: workspaceWrite === null
55
+ ? null
56
+ : {
57
+ [CODEX_CONFIG_KEY.sandboxWorkspaceWrite]: {
58
+ [CODEX_CONFIG_KEY.writableRoots]: workspaceWrite.writableRoots,
59
+ [CODEX_CONFIG_KEY.networkAccess]: workspaceWrite.networkAccess,
60
+ [CODEX_CONFIG_KEY.excludeTmpdirEnvVar]: workspaceWrite.excludeTmpdirEnvVar,
61
+ [CODEX_CONFIG_KEY.excludeSlashTmp]: workspaceWrite.excludeSlashTmp,
62
+ },
63
+ },
64
+ };
65
+ }
20
66
  export const CODEX_MCP_STATUS_DETAIL = {
21
67
  toolsAndAuthOnly: "toolsAndAuthOnly",
22
68
  };
@@ -50,14 +96,46 @@ const RESULT_FIELD = {
50
96
  shortDescription: "shortDescription",
51
97
  skills: "skills",
52
98
  status: "status",
99
+ thread: "thread",
53
100
  tools: "tools",
101
+ turn: "turn",
102
+ turnId: "turnId",
54
103
  };
55
104
  export const CODEX_APP_SERVER_RESULT_DECODERS = {
56
105
  [CODEX_APP_SERVER_METHOD.pluginList]: decodePluginListResult,
57
106
  [CODEX_APP_SERVER_METHOD.pluginInstall]: decodePluginInstallResult,
58
107
  [CODEX_APP_SERVER_METHOD.skillsList]: decodeSkillListResult,
59
108
  [CODEX_APP_SERVER_METHOD.mcpServerStatusList]: decodeMcpServerStatusPage,
109
+ [CODEX_APP_SERVER_METHOD.threadStart]: decodeThreadRef,
110
+ [CODEX_APP_SERVER_METHOD.threadResume]: decodeThreadRef,
111
+ [CODEX_APP_SERVER_METHOD.threadUnarchive]: decodeThreadRef,
112
+ [CODEX_APP_SERVER_METHOD.turnStart]: decodeTurnRefFromTurn,
113
+ [CODEX_APP_SERVER_METHOD.turnSteer]: decodeTurnRef,
114
+ [CODEX_APP_SERVER_METHOD.turnInterrupt]: decodeEmptyResult,
60
115
  };
116
+ /** `{thread: {id}}` — the rest of the thread object is not modeled here. */
117
+ function decodeThreadRef(value) {
118
+ const record = readUnknownRecord(value);
119
+ const thread = record === null ? null : readUnknownRecord(record[RESULT_FIELD.thread]);
120
+ const threadId = thread === null ? null : readString(thread, RESULT_FIELD.id);
121
+ return threadId === null ? null : { threadId };
122
+ }
123
+ /** `turn/start` answers `{turn: {id, status, …}}`. */
124
+ function decodeTurnRefFromTurn(value) {
125
+ const record = readUnknownRecord(value);
126
+ const turn = record === null ? null : readUnknownRecord(record[RESULT_FIELD.turn]);
127
+ const turnId = turn === null ? null : readString(turn, RESULT_FIELD.id);
128
+ return turnId === null ? null : { turnId };
129
+ }
130
+ /** `turn/steer` answers `{turnId}`. */
131
+ function decodeTurnRef(value) {
132
+ const record = readUnknownRecord(value);
133
+ const turnId = record === null ? null : readString(record, RESULT_FIELD.turnId);
134
+ return turnId === null ? null : { turnId };
135
+ }
136
+ function decodeEmptyResult(value) {
137
+ return readUnknownRecord(value) === null ? null : {};
138
+ }
61
139
  function decodeItems(values, decodeItem) {
62
140
  const items = [];
63
141
  for (const value of values) {
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The one way a held child is ended: stdin EOF first (both hosts exit on
3
+ * it — and only that exit removes Codex's thread writer lock), SIGTERM
4
+ * after a grace for a child that is not reading stdin, SIGKILL after
5
+ * another for one that ignores both. Shared by the session child and the
6
+ * codex app-server client so the escalation exists once.
7
+ */
8
+ import type { Clock, ExecExit, InteractiveExecProcess } from "./ports.js";
9
+ export declare const CLOSE_GRACE_MS = 5000;
10
+ export declare function endProcessGracefully(process: InteractiveExecProcess, clock: Clock): Promise<ExecExit>;
11
+ //# sourceMappingURL=process-close.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-close.d.ts","sourceRoot":"","sources":["../../src/core/process-close.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAG1E,eAAO,MAAM,cAAc,OAAQ,CAAC;AAEpC,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,sBAAsB,EAC/B,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,QAAQ,CAAC,CAoBnB"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * The one way a held child is ended: stdin EOF first (both hosts exit on
3
+ * it — and only that exit removes Codex's thread writer lock), SIGTERM
4
+ * after a grace for a child that is not reading stdin, SIGKILL after
5
+ * another for one that ignores both. Shared by the session child and the
6
+ * codex app-server client so the escalation exists once.
7
+ */
8
+ import { PROCESS_SIGNAL } from "./values.js";
9
+ export const CLOSE_GRACE_MS = 5_000;
10
+ export async function endProcessGracefully(process, clock) {
11
+ process.endStdin();
12
+ const cancels = [];
13
+ cancels.push(clock.setTimeout(() => {
14
+ process.kill(PROCESS_SIGNAL.sigterm);
15
+ cancels.push(clock.setTimeout(() => {
16
+ process.kill(PROCESS_SIGNAL.sigkill);
17
+ }, CLOSE_GRACE_MS));
18
+ }, CLOSE_GRACE_MS));
19
+ try {
20
+ return await process.exit;
21
+ }
22
+ finally {
23
+ for (const cancel of cancels.splice(0)) {
24
+ cancel();
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Session-plane vocabulary: a Session is one long-lived host conversation
3
+ * (Claude `-p --input-format stream-json` process, Codex app-server thread)
4
+ * that the caller keeps open across turns. One turn is one `send()`; the
5
+ * host's own conversation id is the Session id. Outbound types follow
6
+ * absence rule 2: keys always present, `null` is meaningful absence.
7
+ */
8
+ export declare const SESSION_EVENT_TYPE: {
9
+ readonly turnStarted: "turn_started";
10
+ readonly turnEnded: "turn_ended";
11
+ readonly message: "message";
12
+ readonly tool: "tool";
13
+ readonly approvalRequested: "approval_requested";
14
+ readonly exited: "exited";
15
+ };
16
+ export declare const TURN_OUTCOME: {
17
+ readonly completed: "completed";
18
+ readonly interrupted: "interrupted";
19
+ readonly failed: "failed";
20
+ };
21
+ export type TurnOutcome = (typeof TURN_OUTCOME)[keyof typeof TURN_OUTCOME];
22
+ /** The neutral answer to a host approval request; hosts map it to their own words. */
23
+ export declare const APPROVAL_DECISION: {
24
+ readonly accept: "accept";
25
+ readonly decline: "decline";
26
+ };
27
+ export type ApprovalDecision = (typeof APPROVAL_DECISION)[keyof typeof APPROVAL_DECISION];
28
+ export type SessionEvent = {
29
+ type: typeof SESSION_EVENT_TYPE.turnStarted;
30
+ turnId: string;
31
+ } | {
32
+ type: typeof SESSION_EVENT_TYPE.turnEnded;
33
+ turnId: string;
34
+ outcome: TurnOutcome;
35
+ } | {
36
+ type: typeof SESSION_EVENT_TYPE.message;
37
+ text: string;
38
+ } | {
39
+ type: typeof SESSION_EVENT_TYPE.tool;
40
+ name: string;
41
+ } | {
42
+ type: typeof SESSION_EVENT_TYPE.approvalRequested;
43
+ requestId: string;
44
+ /** Host-provided one-line description (command, tool name, reason). */
45
+ summary: string;
46
+ /** Decisions the host will accept for this request. */
47
+ decisions: readonly ApprovalDecision[];
48
+ } | {
49
+ type: typeof SESSION_EVENT_TYPE.exited;
50
+ code: number | null;
51
+ signal: string | null;
52
+ };
53
+ export type TurnResult = {
54
+ turnId: string;
55
+ outcome: TurnOutcome;
56
+ /** The host's final answer text for the turn ("" when it produced none). */
57
+ text: string;
58
+ };
59
+ export declare const SESSION_OWNER_KIND: {
60
+ readonly none: "none";
61
+ readonly process: "process";
62
+ };
63
+ /**
64
+ * Who holds the conversation right now, as far as the host's own files say.
65
+ * Claude records `{pid, entrypoint}` in its session registry; Codex only
66
+ * leaves a writer lock, so `pid` is `null` there.
67
+ */
68
+ export type SessionOwner = {
69
+ kind: typeof SESSION_OWNER_KIND.none;
70
+ } | {
71
+ kind: typeof SESSION_OWNER_KIND.process;
72
+ pid: number | null;
73
+ entrypoint: string | null;
74
+ };
75
+ export type SessionFacts<Permissions> = {
76
+ /** The working directory the conversation was recorded in. */
77
+ workspace: string;
78
+ /** The permissions the last turn ran with; `null` when unreadable. */
79
+ lastPermissions: Permissions | null;
80
+ owner: SessionOwner;
81
+ /** Codex moves archived rollouts aside; resume unarchives first. */
82
+ archived: boolean;
83
+ };
84
+ export interface Session {
85
+ /** The host's own conversation id (Claude session_id / Codex thread id). */
86
+ readonly id: string;
87
+ /** Live events; a late subscriber receives the retained replay window. */
88
+ readonly events: AsyncIterable<SessionEvent>;
89
+ /** Start one turn as the user; resolves when the host ends the turn. */
90
+ send(text: string): Promise<TurnResult>;
91
+ /** Add to the running turn (Codex `turn/steer`; Claude absorbs it at the next tool boundary). */
92
+ steer(text: string): Promise<void>;
93
+ /** Stop the running turn; the turn ends with outcome `interrupted`. */
94
+ interrupt(): Promise<void>;
95
+ /** Answer an `approval_requested` event. */
96
+ respond(requestId: string, decision: ApprovalDecision): Promise<void>;
97
+ /** Release the conversation: close stdin, wait for exit (escalating to signals). */
98
+ close(): Promise<void>;
99
+ }
100
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"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"}