@nyssance/codex-acp-v2 0.7.4 → 0.7.5

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 (3) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/index.js +540 -166
  3. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.5 — 2026-10-08
4
+
5
+ ### Added
6
+
7
+ - Chat branches and fork lineage under `_meta.codex`: `forkAtTurn` and `sessionLineage` capabilities;
8
+ `session/fork` and `session/resume` responses carry `nativeSessionId` and `forkedFromId`; session
9
+ messages carry `turnId` and `turnStartedAt` so a client can tell which turn a message came from.
10
+
11
+ ### Changed
12
+
13
+ - `@agentclientprotocol/sdk` ^1.7.0 (schema v2.0.0-alpha.7). The protocol now lets `session/new` and
14
+ `session/resume` responses carry `availableCommands` and `configOptions`; the adapter does not fill
15
+ them yet and still announces commands through `available_commands_update`. The 1.7.0 types reject a
16
+ hand-built update with an unknown tag (no `_` prefix) or a malformed known variant at compile time;
17
+ runtime validation is unchanged.
18
+
19
+ ### Fixed
20
+
21
+ - `AppServerClient` wrote a raw NUL byte into a template literal as the turn-key separator, so `file`
22
+ and `grep` treated the source as binary. It is the `\0` escape now.
23
+
3
24
  ## 0.7.4 — 2026-09-30
4
25
 
5
26
  ### Added
package/dist/index.js CHANGED
@@ -3406,7 +3406,7 @@ var require_main = __commonJS(function(exports) {
3406
3406
  exports.createMessageConnection = createMessageConnection;
3407
3407
  var ril_1 = __importDefault(require_ril());
3408
3408
  ril_1.default.install();
3409
- var path8 = __importStar(__require("path"));
3409
+ var path9 = __importStar(__require("path"));
3410
3410
  var os3 = __importStar(__require("os"));
3411
3411
  var fs7 = __importStar(__require("fs"));
3412
3412
  var crypto_1 = __require("crypto");
@@ -3564,7 +3564,7 @@ var require_main = __commonJS(function(exports) {
3564
3564
  throw new Error(`Unable to generate a random pipe name with ${randomLength} characters.`);
3565
3565
  }
3566
3566
  const randomSuffix = (0, crypto_1.randomBytes)(Math.floor(randomLength / 2)).toString("hex");
3567
- return path8.join(tmpDir, `lsp-${randomSuffix}.sock`);
3567
+ return path9.join(tmpDir, `lsp-${randomSuffix}.sock`);
3568
3568
  }
3569
3569
  function createClientPipeTransport(pipeName, encoding = "utf-8") {
3570
3570
  let connectResolve;
@@ -3681,9 +3681,7 @@ var AGENT_METHODS = {
3681
3681
  var CLIENT_METHODS = {
3682
3682
  session_request_permission: "session/request_permission",
3683
3683
  session_update: "session/update",
3684
- mcp_connect: "mcp/connect",
3685
3684
  mcp_message: "mcp/message",
3686
- mcp_disconnect: "mcp/disconnect",
3687
3685
  elicitation_create: "elicitation/create",
3688
3686
  elicitation_complete: "elicitation/complete"
3689
3687
  };
@@ -15345,27 +15343,16 @@ var zCreateElicitationRequest = preserveCustomPayload(intersection(union([
15345
15343
  })
15346
15344
  })), "mode", ["form", "url"]);
15347
15345
  var zMcpServerAcpId = string2();
15348
- var zConnectMcpRequest = object({
15349
- serverId: zMcpServerAcpId,
15350
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
15351
- return;
15352
- })
15353
- });
15354
- var zMcpConnectionId = string2();
15346
+ var zMcpRequestId = string2();
15355
15347
  var zMessageMcpRequest = object({
15356
- connectionId: zMcpConnectionId,
15348
+ serverId: zMcpServerAcpId,
15349
+ requestId: zMcpRequestId,
15357
15350
  method: string2(),
15358
15351
  params: record(string2(), unknown()).nullish(),
15359
15352
  _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
15360
15353
  return;
15361
15354
  })
15362
15355
  });
15363
- var zDisconnectMcpRequest = object({
15364
- connectionId: zMcpConnectionId,
15365
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
15366
- return;
15367
- })
15368
- });
15369
15356
  var zExtRequest = unknown();
15370
15357
  var zAgentRequest = object({
15371
15358
  id: zRequestId,
@@ -15373,9 +15360,7 @@ var zAgentRequest = object({
15373
15360
  params: union([
15374
15361
  zRequestPermissionRequest,
15375
15362
  zCreateElicitationRequest,
15376
- zConnectMcpRequest,
15377
15363
  zMessageMcpRequest,
15378
- zDisconnectMcpRequest,
15379
15364
  zExtRequest
15380
15365
  ]).nullish()
15381
15366
  });
@@ -15826,9 +15811,34 @@ var zSessionConfigOption = preserveCustomPayload(intersection(union([
15826
15811
  return;
15827
15812
  })
15828
15813
  })), "type", ["boolean", "select"]);
15814
+ var zTextCommandInput = object({
15815
+ hint: string2(),
15816
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
15817
+ return;
15818
+ })
15819
+ });
15820
+ var zAvailableCommandInput = preserveCustomPayload(union([
15821
+ zTextCommandInput.and(object({
15822
+ type: literal("text")
15823
+ })),
15824
+ excludeKnownTags(object({
15825
+ type: string2()
15826
+ }), "type", ["text"])
15827
+ ]), "type", ["text"]);
15828
+ var zAvailableCommand = object({
15829
+ name: string2(),
15830
+ description: string2(),
15831
+ input: defaultOnError(zAvailableCommandInput.nullish(), () => {
15832
+ return;
15833
+ }),
15834
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
15835
+ return;
15836
+ })
15837
+ });
15829
15838
  var zNewSessionResponse = object({
15830
15839
  sessionId: zSessionId,
15831
15840
  configOptions: defaultOnError(vecSkipError(zSessionConfigOption).optional(), () => []),
15841
+ availableCommands: defaultOnError(vecSkipError(zAvailableCommand).optional(), () => []),
15832
15842
  _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
15833
15843
  return;
15834
15844
  })
@@ -15865,12 +15875,14 @@ var zDeleteSessionResponse = object({
15865
15875
  var zForkSessionResponse = object({
15866
15876
  sessionId: zSessionId,
15867
15877
  configOptions: defaultOnError(vecSkipError(zSessionConfigOption).optional(), () => []),
15878
+ availableCommands: defaultOnError(vecSkipError(zAvailableCommand).optional(), () => []),
15868
15879
  _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
15869
15880
  return;
15870
15881
  })
15871
15882
  });
15872
15883
  var zResumeSessionResponse = object({
15873
15884
  configOptions: defaultOnError(vecSkipError(zSessionConfigOption).optional(), () => []),
15885
+ availableCommands: defaultOnError(vecSkipError(zAvailableCommand).optional(), () => []),
15874
15886
  _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
15875
15887
  return;
15876
15888
  })
@@ -15993,7 +16005,6 @@ var zCloseNesResponse = object({
15993
16005
  })
15994
16006
  });
15995
16007
  var zExtResponse = unknown();
15996
- var zMessageMcpResponse = unknown();
15997
16008
  var zErrorCode = union([
15998
16009
  literal(-32700),
15999
16010
  literal(-32600),
@@ -16037,8 +16048,7 @@ var zAgentResponse = union([
16037
16048
  zStartNesResponse,
16038
16049
  zSuggestNesResponse,
16039
16050
  zCloseNesResponse,
16040
- zExtResponse,
16041
- zMessageMcpResponse
16051
+ zExtResponse
16042
16052
  ])
16043
16053
  }),
16044
16054
  object({
@@ -16126,6 +16136,11 @@ var zRequiresActionStateUpdate = object({
16126
16136
  return;
16127
16137
  })
16128
16138
  });
16139
+ var zUnknownStateUpdate = object({
16140
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16141
+ return;
16142
+ })
16143
+ });
16129
16144
  var zStateUpdate = preserveCustomPayload(union([
16130
16145
  zRunningStateUpdate.and(object({
16131
16146
  state: literal("running")
@@ -16136,10 +16151,13 @@ var zStateUpdate = preserveCustomPayload(union([
16136
16151
  zRequiresActionStateUpdate.and(object({
16137
16152
  state: literal("requires_action")
16138
16153
  })),
16154
+ zUnknownStateUpdate.and(object({
16155
+ state: literal("unknown")
16156
+ })),
16139
16157
  excludeKnownTags(object({
16140
16158
  state: string2()
16141
- }), "state", ["idle", "requires_action", "running"])
16142
- ]), "state", ["idle", "requires_action", "running"]);
16159
+ }), "state", ["idle", "requires_action", "running", "unknown"])
16160
+ ]), "state", ["idle", "requires_action", "running", "unknown"]);
16143
16161
  var zToolCallContentChunk = object({
16144
16162
  toolCallId: zToolCallId,
16145
16163
  content: zToolCallContent,
@@ -16261,30 +16279,6 @@ var zPlanRemoved = object({
16261
16279
  return;
16262
16280
  })
16263
16281
  });
16264
- var zTextCommandInput = object({
16265
- hint: string2(),
16266
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16267
- return;
16268
- })
16269
- });
16270
- var zAvailableCommandInput = preserveCustomPayload(union([
16271
- zTextCommandInput.and(object({
16272
- type: literal("text")
16273
- })),
16274
- excludeKnownTags(object({
16275
- type: string2()
16276
- }), "type", ["text"])
16277
- ]), "type", ["text"]);
16278
- var zAvailableCommand = object({
16279
- name: string2(),
16280
- description: string2(),
16281
- input: defaultOnError(zAvailableCommandInput.nullish(), () => {
16282
- return;
16283
- }),
16284
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16285
- return;
16286
- })
16287
- });
16288
16282
  var zAvailableCommandsUpdate = object({
16289
16283
  availableCommands: requiredDefaultOnError(vecSkipError(zAvailableCommand), () => []),
16290
16284
  _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
@@ -16369,6 +16363,65 @@ var zCompactionSummaryChunk = object({
16369
16363
  return;
16370
16364
  })
16371
16365
  });
16366
+ var zSessionCancelCapabilities = object({
16367
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16368
+ return;
16369
+ })
16370
+ });
16371
+ var zSubagentSessionCapabilities = object({
16372
+ cancel: defaultOnError(zSessionCancelCapabilities.nullish(), () => {
16373
+ return;
16374
+ }),
16375
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16376
+ return;
16377
+ })
16378
+ });
16379
+ var zSubagentUpdate = object({
16380
+ sessionId: zSessionId,
16381
+ title: defaultOnError(string2().nullish(), () => {
16382
+ return;
16383
+ }),
16384
+ description: defaultOnError(string2().nullish(), () => {
16385
+ return;
16386
+ }),
16387
+ capabilities: defaultOnError(zSubagentSessionCapabilities.nullish(), () => {
16388
+ return;
16389
+ }),
16390
+ state: defaultOnError(zStateUpdate.nullish(), () => {
16391
+ return;
16392
+ }),
16393
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16394
+ return;
16395
+ })
16396
+ });
16397
+ var zSessionMessage = object({
16398
+ messageId: zMessageId,
16399
+ senderSessionId: defaultOnError(zSessionId.nullish(), () => {
16400
+ return;
16401
+ }),
16402
+ recipientSessionId: defaultOnError(zSessionId.nullish(), () => {
16403
+ return;
16404
+ }),
16405
+ content: defaultOnError(vecSkipError(zContentBlock).nullish(), () => {
16406
+ return;
16407
+ }),
16408
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16409
+ return;
16410
+ })
16411
+ });
16412
+ var zSessionMessageChunk = object({
16413
+ messageId: zMessageId,
16414
+ senderSessionId: defaultOnError(zSessionId.nullish(), () => {
16415
+ return;
16416
+ }),
16417
+ recipientSessionId: defaultOnError(zSessionId.nullish(), () => {
16418
+ return;
16419
+ }),
16420
+ content: zContentBlock,
16421
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16422
+ return;
16423
+ })
16424
+ });
16372
16425
  var zSessionUpdate = preserveCustomPayload(union([
16373
16426
  zContentChunk.and(object({
16374
16427
  sessionUpdate: literal("user_message_chunk")
@@ -16430,6 +16483,15 @@ var zSessionUpdate = preserveCustomPayload(union([
16430
16483
  zCompactionSummaryChunk.and(object({
16431
16484
  sessionUpdate: literal("compaction_summary_chunk")
16432
16485
  })),
16486
+ zSubagentUpdate.and(object({
16487
+ sessionUpdate: literal("subagent_update")
16488
+ })),
16489
+ zSessionMessage.and(object({
16490
+ sessionUpdate: literal("session_message")
16491
+ })),
16492
+ zSessionMessageChunk.and(object({
16493
+ sessionUpdate: literal("session_message_chunk")
16494
+ })),
16433
16495
  excludeKnownTags(object({
16434
16496
  sessionUpdate: string2()
16435
16497
  }), "sessionUpdate", [
@@ -16445,7 +16507,10 @@ var zSessionUpdate = preserveCustomPayload(union([
16445
16507
  "plan_removed",
16446
16508
  "plan_update",
16447
16509
  "session_info_update",
16510
+ "session_message",
16511
+ "session_message_chunk",
16448
16512
  "state_update",
16513
+ "subagent_update",
16449
16514
  "terminal_output_chunk",
16450
16515
  "terminal_update",
16451
16516
  "tool_call_content_chunk",
@@ -16467,7 +16532,10 @@ var zSessionUpdate = preserveCustomPayload(union([
16467
16532
  "plan_removed",
16468
16533
  "plan_update",
16469
16534
  "session_info_update",
16535
+ "session_message",
16536
+ "session_message_chunk",
16470
16537
  "state_update",
16538
+ "subagent_update",
16471
16539
  "terminal_output_chunk",
16472
16540
  "terminal_update",
16473
16541
  "tool_call_content_chunk",
@@ -16489,23 +16557,12 @@ var zCompleteElicitationNotification = object({
16489
16557
  return;
16490
16558
  })
16491
16559
  });
16492
- var zMessageMcpNotification = object({
16493
- connectionId: zMcpConnectionId,
16494
- method: string2(),
16495
- params: defaultOnError(record(string2(), unknown()).nullish(), () => {
16496
- return;
16497
- }),
16498
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16499
- return;
16500
- })
16501
- });
16502
16560
  var zExtNotification = unknown();
16503
16561
  var zAgentNotification = object({
16504
16562
  method: string2(),
16505
16563
  params: union([
16506
16564
  zUpdateSessionNotification,
16507
16565
  zCompleteElicitationNotification,
16508
- zMessageMcpNotification,
16509
16566
  zExtNotification
16510
16567
  ]).nullish()
16511
16568
  });
@@ -16917,7 +16974,6 @@ var zClientRequest = object({
16917
16974
  zStartNesRequest,
16918
16975
  zSuggestNesRequest,
16919
16976
  zCloseNesRequest,
16920
- zMessageMcpRequest,
16921
16977
  zExtRequest
16922
16978
  ]).nullish()
16923
16979
  });
@@ -16972,25 +17028,35 @@ var zCreateElicitationResponse = preserveCustomPayload(intersection(union([
16972
17028
  return;
16973
17029
  })
16974
17030
  })), "action", ["accept", "cancel", "decline"]);
16975
- var zConnectMcpResponse = object({
16976
- connectionId: zMcpConnectionId,
16977
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16978
- return;
16979
- })
17031
+ var zMcpError = looseObject({
17032
+ code: int().min(-2147483648, {
17033
+ error: "Invalid value: Expected int32 to be >= -2147483648"
17034
+ }).max(2147483647, {
17035
+ error: "Invalid value: Expected int32 to be <= 2147483647"
17036
+ }),
17037
+ message: string2(),
17038
+ data: unknown().optional()
16980
17039
  });
16981
- var zDisconnectMcpResponse = object({
16982
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
16983
- return;
17040
+ var zMessageMcpResponse = union([
17041
+ object({
17042
+ result: unknown(),
17043
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
17044
+ return;
17045
+ })
17046
+ }),
17047
+ object({
17048
+ error: zMcpError,
17049
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
17050
+ return;
17051
+ })
16984
17052
  })
16985
- });
17053
+ ]);
16986
17054
  var zClientResponse = union([
16987
17055
  object({
16988
17056
  id: zRequestId,
16989
17057
  result: union([
16990
17058
  zRequestPermissionResponse,
16991
17059
  zCreateElicitationResponse,
16992
- zConnectMcpResponse,
16993
- zDisconnectMcpResponse,
16994
17060
  zMessageMcpResponse,
16995
17061
  zExtResponse
16996
17062
  ])
@@ -17080,6 +17146,15 @@ var zRejectNesNotification = object({
17080
17146
  return;
17081
17147
  })
17082
17148
  });
17149
+ var zMessageMcpNotification = object({
17150
+ serverId: zMcpServerAcpId,
17151
+ requestId: zMcpRequestId,
17152
+ method: string2(),
17153
+ params: record(string2(), unknown()).nullish(),
17154
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
17155
+ return;
17156
+ })
17157
+ });
17083
17158
  var zClientNotification = object({
17084
17159
  method: string2(),
17085
17160
  params: union([
@@ -17146,6 +17221,7 @@ var zGuardSessionConfigOptionCustom = object({
17146
17221
  configId: zSessionConfigId,
17147
17222
  name: string2()
17148
17223
  });
17224
+ var zGuardAvailableCommandInputText = zTextCommandInput.and(object({ type: literal("text") }));
17149
17225
  var zGuardNesSuggestionEdit = zNesEditSuggestion.and(object({ kind: literal("edit") }));
17150
17226
  var zGuardNesSuggestionJump = zNesJumpSuggestion.and(object({ kind: literal("jump") }));
17151
17227
  var zGuardNesSuggestionRename = zNesRenameSuggestion.and(object({ kind: literal("rename") }));
@@ -17173,14 +17249,17 @@ var zGuardSessionUpdateUsageUpdate = zUsageUpdate.and(object({ sessionUpdate: li
17173
17249
  var zGuardSessionUpdateNotice = zNotice.and(object({ sessionUpdate: literal("notice") }));
17174
17250
  var zGuardSessionUpdateCompactionUpdate = zCompactionUpdate.and(object({ sessionUpdate: literal("compaction_update") }));
17175
17251
  var zGuardSessionUpdateCompactionSummaryChunk = zCompactionSummaryChunk.and(object({ sessionUpdate: literal("compaction_summary_chunk") }));
17252
+ var zGuardSessionUpdateSubagentUpdate = zSubagentUpdate.and(object({ sessionUpdate: literal("subagent_update") }));
17253
+ var zGuardSessionUpdateSessionMessage = zSessionMessage.and(object({ sessionUpdate: literal("session_message") }));
17254
+ var zGuardSessionUpdateSessionMessageChunk = zSessionMessageChunk.and(object({ sessionUpdate: literal("session_message_chunk") }));
17176
17255
  var zGuardStateUpdateRunning = zRunningStateUpdate.and(object({ state: literal("running") }));
17177
17256
  var zGuardStateUpdateIdle = zIdleStateUpdate.and(object({ state: literal("idle") }));
17178
17257
  var zGuardStateUpdateRequiresAction = zRequiresActionStateUpdate.and(object({ state: literal("requires_action") }));
17258
+ var zGuardStateUpdateUnknown = zUnknownStateUpdate.and(object({ state: literal("unknown") }));
17179
17259
  var zGuardPlanUpdateContentItems = zPlanItems.and(object({ type: literal("items") }));
17180
17260
  var zGuardPlanUpdateContentFile = zPlanFile.and(object({ type: literal("file") }));
17181
17261
  var zGuardPlanUpdateContentMarkdown = zPlanMarkdown.and(object({ type: literal("markdown") }));
17182
17262
  var zGuardPlanUpdateContentCustom = object({ planId: zPlanId });
17183
- var zGuardAvailableCommandInputText = zTextCommandInput.and(object({ type: literal("text") }));
17184
17263
  var zGuardMcpServerHttp = zMcpServerHttp.and(object({ type: literal("http") }));
17185
17264
  var zGuardMcpServerAcp = zMcpServerAcp.and(object({ type: literal("acp") }));
17186
17265
  var zGuardMcpServerStdio = zMcpServerStdio.and(object({ type: literal("stdio") }));
@@ -17290,6 +17369,15 @@ var SessionUpdate = {
17290
17369
  isCompactionSummaryChunk(value) {
17291
17370
  return tagOf(value, "sessionUpdate") === "compaction_summary_chunk" && zGuardSessionUpdateCompactionSummaryChunk.safeParse(value).success;
17292
17371
  },
17372
+ isSubagentUpdate(value) {
17373
+ return tagOf(value, "sessionUpdate") === "subagent_update" && zGuardSessionUpdateSubagentUpdate.safeParse(value).success;
17374
+ },
17375
+ isSessionMessage(value) {
17376
+ return tagOf(value, "sessionUpdate") === "session_message" && zGuardSessionUpdateSessionMessage.safeParse(value).success;
17377
+ },
17378
+ isSessionMessageChunk(value) {
17379
+ return tagOf(value, "sessionUpdate") === "session_message_chunk" && zGuardSessionUpdateSessionMessageChunk.safeParse(value).success;
17380
+ },
17293
17381
  isCustom(value) {
17294
17382
  const tag = tagOf(value, "sessionUpdate");
17295
17383
  return typeof tag === "string" && ![
@@ -17305,7 +17393,10 @@ var SessionUpdate = {
17305
17393
  "plan_removed",
17306
17394
  "plan_update",
17307
17395
  "session_info_update",
17396
+ "session_message",
17397
+ "session_message_chunk",
17308
17398
  "state_update",
17399
+ "subagent_update",
17309
17400
  "terminal_output_chunk",
17310
17401
  "terminal_update",
17311
17402
  "tool_call_content_chunk",
@@ -17326,9 +17417,12 @@ var StateUpdate = {
17326
17417
  isRequiresAction(value) {
17327
17418
  return tagOf(value, "state") === "requires_action" && zGuardStateUpdateRequiresAction.safeParse(value).success;
17328
17419
  },
17420
+ isUnknown(value) {
17421
+ return tagOf(value, "state") === "unknown" && zGuardStateUpdateUnknown.safeParse(value).success;
17422
+ },
17329
17423
  isCustom(value) {
17330
17424
  const tag = tagOf(value, "state");
17331
- return typeof tag === "string" && !["idle", "requires_action", "running"].includes(tag);
17425
+ return typeof tag === "string" && !["idle", "requires_action", "running", "unknown"].includes(tag);
17332
17426
  }
17333
17427
  };
17334
17428
  var McpServer = {
@@ -18857,27 +18951,16 @@ var zCreateElicitationRequest2 = preserveCustomPayload(intersection(union([
18857
18951
  })
18858
18952
  })), "mode", ["form", "url"]);
18859
18953
  var zMcpServerAcpId2 = string2();
18860
- var zConnectMcpRequest2 = object({
18861
- serverId: zMcpServerAcpId2,
18862
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
18863
- return;
18864
- })
18865
- });
18866
- var zMcpConnectionId2 = string2();
18954
+ var zMcpRequestId2 = string2();
18867
18955
  var zMessageMcpRequest2 = object({
18868
- connectionId: zMcpConnectionId2,
18956
+ serverId: zMcpServerAcpId2,
18957
+ requestId: zMcpRequestId2,
18869
18958
  method: string2(),
18870
18959
  params: record(string2(), unknown()).nullish(),
18871
18960
  _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
18872
18961
  return;
18873
18962
  })
18874
18963
  });
18875
- var zDisconnectMcpRequest2 = object({
18876
- connectionId: zMcpConnectionId2,
18877
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
18878
- return;
18879
- })
18880
- });
18881
18964
  var zExtRequest2 = unknown();
18882
18965
  var zAgentRequest2 = object({
18883
18966
  id: zRequestId2,
@@ -18892,9 +18975,7 @@ var zAgentRequest2 = object({
18892
18975
  zWaitForTerminalExitRequest,
18893
18976
  zKillTerminalRequest,
18894
18977
  zCreateElicitationRequest2,
18895
- zConnectMcpRequest2,
18896
18978
  zMessageMcpRequest2,
18897
- zDisconnectMcpRequest2,
18898
18979
  zExtRequest2
18899
18980
  ]).nullish()
18900
18981
  });
@@ -19590,7 +19671,6 @@ var zCloseNesResponse2 = object({
19590
19671
  })
19591
19672
  });
19592
19673
  var zExtResponse2 = unknown();
19593
- var zMessageMcpResponse2 = unknown();
19594
19674
  var zErrorCode2 = union([
19595
19675
  literal(-32700),
19596
19676
  literal(-32600),
@@ -19636,8 +19716,7 @@ var zAgentResponse2 = union([
19636
19716
  zStartNesResponse2,
19637
19717
  zSuggestNesResponse2,
19638
19718
  zCloseNesResponse2,
19639
- zExtResponse2,
19640
- zMessageMcpResponse2
19719
+ zExtResponse2
19641
19720
  ])
19642
19721
  }),
19643
19722
  object({
@@ -19855,6 +19934,108 @@ var zCompactionSummaryChunk2 = object({
19855
19934
  return;
19856
19935
  })
19857
19936
  });
19937
+ var zSessionCancelCapabilities2 = object({
19938
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
19939
+ return;
19940
+ })
19941
+ });
19942
+ var zSubagentSessionCapabilities2 = object({
19943
+ cancel: defaultOnError(zSessionCancelCapabilities2.nullish(), () => {
19944
+ return;
19945
+ }),
19946
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
19947
+ return;
19948
+ })
19949
+ });
19950
+ var zRunningStateUpdate2 = object({
19951
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
19952
+ return;
19953
+ })
19954
+ });
19955
+ var zIdleStateUpdate2 = object({
19956
+ stopReason: defaultOnError(zStopReason2.nullish(), () => {
19957
+ return;
19958
+ }),
19959
+ usage: defaultOnError(zUsage2.nullish(), () => {
19960
+ return;
19961
+ }),
19962
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
19963
+ return;
19964
+ })
19965
+ });
19966
+ var zRequiresActionStateUpdate2 = object({
19967
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
19968
+ return;
19969
+ })
19970
+ });
19971
+ var zUnknownStateUpdate2 = object({
19972
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
19973
+ return;
19974
+ })
19975
+ });
19976
+ var zStateUpdate2 = preserveCustomPayload(union([
19977
+ zRunningStateUpdate2.and(object({
19978
+ state: literal("running")
19979
+ })),
19980
+ zIdleStateUpdate2.and(object({
19981
+ state: literal("idle")
19982
+ })),
19983
+ zRequiresActionStateUpdate2.and(object({
19984
+ state: literal("requires_action")
19985
+ })),
19986
+ zUnknownStateUpdate2.and(object({
19987
+ state: literal("unknown")
19988
+ })),
19989
+ excludeKnownTags(object({
19990
+ state: string2()
19991
+ }), "state", ["idle", "requires_action", "running", "unknown"])
19992
+ ]), "state", ["idle", "requires_action", "running", "unknown"]);
19993
+ var zSubagentUpdate2 = object({
19994
+ sessionId: zSessionId2,
19995
+ title: defaultOnError(string2().nullish(), () => {
19996
+ return;
19997
+ }),
19998
+ description: defaultOnError(string2().nullish(), () => {
19999
+ return;
20000
+ }),
20001
+ capabilities: defaultOnError(zSubagentSessionCapabilities2.nullish(), () => {
20002
+ return;
20003
+ }),
20004
+ state: defaultOnError(zStateUpdate2.nullish(), () => {
20005
+ return;
20006
+ }),
20007
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
20008
+ return;
20009
+ })
20010
+ });
20011
+ var zSessionMessage2 = object({
20012
+ messageId: zMessageId2,
20013
+ senderSessionId: defaultOnError(zSessionId2.nullish(), () => {
20014
+ return;
20015
+ }),
20016
+ recipientSessionId: defaultOnError(zSessionId2.nullish(), () => {
20017
+ return;
20018
+ }),
20019
+ content: defaultOnError(vecSkipError(zContentBlock2).nullish(), () => {
20020
+ return;
20021
+ }),
20022
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
20023
+ return;
20024
+ })
20025
+ });
20026
+ var zSessionMessageChunk2 = object({
20027
+ messageId: zMessageId2,
20028
+ senderSessionId: defaultOnError(zSessionId2.nullish(), () => {
20029
+ return;
20030
+ }),
20031
+ recipientSessionId: defaultOnError(zSessionId2.nullish(), () => {
20032
+ return;
20033
+ }),
20034
+ content: zContentBlock2,
20035
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
20036
+ return;
20037
+ })
20038
+ });
19858
20039
  var zSessionUpdate2 = union([
19859
20040
  zContentChunk2.and(object({
19860
20041
  sessionUpdate: literal("user_message_chunk")
@@ -19903,6 +20084,15 @@ var zSessionUpdate2 = union([
19903
20084
  })),
19904
20085
  zCompactionSummaryChunk2.and(object({
19905
20086
  sessionUpdate: literal("compaction_summary_chunk")
20087
+ })),
20088
+ zSubagentUpdate2.and(object({
20089
+ sessionUpdate: literal("subagent_update")
20090
+ })),
20091
+ zSessionMessage2.and(object({
20092
+ sessionUpdate: literal("session_message")
20093
+ })),
20094
+ zSessionMessageChunk2.and(object({
20095
+ sessionUpdate: literal("session_message_chunk")
19906
20096
  }))
19907
20097
  ]);
19908
20098
  var zSessionNotification = object({
@@ -19918,23 +20108,12 @@ var zCompleteElicitationNotification2 = object({
19918
20108
  return;
19919
20109
  })
19920
20110
  });
19921
- var zMessageMcpNotification2 = object({
19922
- connectionId: zMcpConnectionId2,
19923
- method: string2(),
19924
- params: defaultOnError(record(string2(), unknown()).nullish(), () => {
19925
- return;
19926
- }),
19927
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
19928
- return;
19929
- })
19930
- });
19931
20111
  var zExtNotification2 = unknown();
19932
20112
  var zAgentNotification2 = object({
19933
20113
  method: string2(),
19934
20114
  params: union([
19935
20115
  zSessionNotification,
19936
20116
  zCompleteElicitationNotification2,
19937
- zMessageMcpNotification2,
19938
20117
  zExtNotification2
19939
20118
  ]).nullish()
19940
20119
  });
@@ -19974,6 +20153,11 @@ var zClientSessionCapabilities = object({
19974
20153
  return;
19975
20154
  })
19976
20155
  });
20156
+ var zSubagentCapabilities = object({
20157
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
20158
+ return;
20159
+ })
20160
+ });
19977
20161
  var zPlanCapabilities = object({
19978
20162
  _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
19979
20163
  return;
@@ -20041,6 +20225,9 @@ var zClientCapabilities2 = object({
20041
20225
  session: defaultOnError(zClientSessionCapabilities.nullish(), () => {
20042
20226
  return;
20043
20227
  }),
20228
+ subagents: defaultOnError(zSubagentCapabilities.nullish(), () => {
20229
+ return;
20230
+ }),
20044
20231
  plan: defaultOnError(zPlanCapabilities.nullish(), () => {
20045
20232
  return;
20046
20233
  }),
@@ -20394,7 +20581,6 @@ var zClientRequest2 = object({
20394
20581
  zStartNesRequest2,
20395
20582
  zSuggestNesRequest2,
20396
20583
  zCloseNesRequest2,
20397
- zMessageMcpRequest2,
20398
20584
  zExtRequest2
20399
20585
  ]).nullish()
20400
20586
  });
@@ -20509,17 +20695,29 @@ var zCreateElicitationResponse2 = preserveCustomPayload(intersection(union([
20509
20695
  return;
20510
20696
  })
20511
20697
  })), "action", ["accept", "cancel", "decline"]);
20512
- var zConnectMcpResponse2 = object({
20513
- connectionId: zMcpConnectionId2,
20514
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
20515
- return;
20516
- })
20698
+ var zMcpError2 = looseObject({
20699
+ code: int().min(-2147483648, {
20700
+ error: "Invalid value: Expected int32 to be >= -2147483648"
20701
+ }).max(2147483647, {
20702
+ error: "Invalid value: Expected int32 to be <= 2147483647"
20703
+ }),
20704
+ message: string2(),
20705
+ data: unknown().optional()
20517
20706
  });
20518
- var zDisconnectMcpResponse2 = object({
20519
- _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
20520
- return;
20707
+ var zMessageMcpResponse2 = union([
20708
+ object({
20709
+ result: unknown(),
20710
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
20711
+ return;
20712
+ })
20713
+ }),
20714
+ object({
20715
+ error: zMcpError2,
20716
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
20717
+ return;
20718
+ })
20521
20719
  })
20522
- });
20720
+ ]);
20523
20721
  var zClientResponse2 = union([
20524
20722
  object({
20525
20723
  id: zRequestId2,
@@ -20533,8 +20731,6 @@ var zClientResponse2 = union([
20533
20731
  zWaitForTerminalExitResponse,
20534
20732
  zKillTerminalResponse,
20535
20733
  zCreateElicitationResponse2,
20536
- zConnectMcpResponse2,
20537
- zDisconnectMcpResponse2,
20538
20734
  zMessageMcpResponse2,
20539
20735
  zExtResponse2
20540
20736
  ])
@@ -20623,6 +20819,15 @@ var zRejectNesNotification2 = object({
20623
20819
  return;
20624
20820
  })
20625
20821
  });
20822
+ var zMessageMcpNotification2 = object({
20823
+ serverId: zMcpServerAcpId2,
20824
+ requestId: zMcpRequestId2,
20825
+ method: string2(),
20826
+ params: record(string2(), unknown()).nullish(),
20827
+ _meta: defaultOnError(record(string2(), unknown()).nullish(), () => {
20828
+ return;
20829
+ })
20830
+ });
20626
20831
  var zClientNotification2 = object({
20627
20832
  method: string2(),
20628
20833
  params: union([
@@ -20675,7 +20880,7 @@ function assertV2BatchMethods(entries, requestMethods, notificationMethods) {
20675
20880
  }
20676
20881
  }
20677
20882
  function parseV2InitializeRequest(params) {
20678
- const request = zInitializeRequest.parse(params);
20883
+ const request = received(zInitializeRequest).parse(params);
20679
20884
  if (request.protocolVersion !== PROTOCOL_VERSION) {
20680
20885
  throw RequestError.invalidParams({
20681
20886
  expectedProtocolVersion: PROTOCOL_VERSION,
@@ -20692,7 +20897,7 @@ function normalizeOutgoingV2InitializeRequest(params) {
20692
20897
  });
20693
20898
  }
20694
20899
  function mapV2InitializeResponse(response) {
20695
- const parsed = zInitializeResponse.parse(response);
20900
+ const parsed = received(zInitializeResponse).parse(response);
20696
20901
  if (parsed.protocolVersion !== PROTOCOL_VERSION) {
20697
20902
  throw RequestError.invalidRequest({
20698
20903
  expectedProtocolVersion: PROTOCOL_VERSION,
@@ -20937,9 +21142,7 @@ var methods = {
20937
21142
  update: CLIENT_METHODS.session_update
20938
21143
  },
20939
21144
  mcp: {
20940
- connect: CLIENT_METHODS.mcp_connect,
20941
- message: CLIENT_METHODS.mcp_message,
20942
- disconnect: CLIENT_METHODS.mcp_disconnect
21145
+ message: CLIENT_METHODS.mcp_message
20943
21146
  },
20944
21147
  elicitation: {
20945
21148
  create: CLIENT_METHODS.elicitation_create,
@@ -21453,6 +21656,9 @@ function parseParams(parser, params) {
21453
21656
  }
21454
21657
  return parser.parse(params);
21455
21658
  }
21659
+ function received(validator) {
21660
+ return validator;
21661
+ }
21456
21662
  function requestSpec(method, params, response, serializeResponse) {
21457
21663
  return { method, params, response, serializeResponse };
21458
21664
  }
@@ -21488,18 +21694,17 @@ var agentRequestSpecs = {
21488
21694
  unstable_listProviders: requestSpec(AGENT_METHODS.providers_list, zListProvidersRequest, zListProvidersResponse),
21489
21695
  unstable_setProvider: requestSpec(AGENT_METHODS.providers_set, zSetProviderRequest, zSetProviderResponse, emptyObjectResponse),
21490
21696
  unstable_disableProvider: requestSpec(AGENT_METHODS.providers_disable, zDisableProviderRequest, zDisableProviderResponse, emptyObjectResponse),
21491
- newSession: requestSpec(AGENT_METHODS.session_new, zNewSessionRequest, zNewSessionResponse),
21492
- setSessionConfigOption: requestSpec(AGENT_METHODS.session_set_config_option, zSetSessionConfigOptionRequest, zSetSessionConfigOptionResponse),
21493
- prompt: requestSpec(AGENT_METHODS.session_prompt, zPromptRequest, zPromptResponse),
21494
- unstable_messageMcp: requestSpec(AGENT_METHODS.mcp_message, zMessageMcpRequest, zMessageMcpResponse),
21697
+ newSession: requestSpec(AGENT_METHODS.session_new, received(zNewSessionRequest), received(zNewSessionResponse)),
21698
+ setSessionConfigOption: requestSpec(AGENT_METHODS.session_set_config_option, received(zSetSessionConfigOptionRequest), received(zSetSessionConfigOptionResponse)),
21699
+ prompt: requestSpec(AGENT_METHODS.session_prompt, received(zPromptRequest), received(zPromptResponse)),
21495
21700
  listSessions: requestSpec(AGENT_METHODS.session_list, zListSessionsRequest, zListSessionsResponse),
21496
21701
  deleteSession: requestSpec(AGENT_METHODS.session_delete, zDeleteSessionRequest, zDeleteSessionResponse, emptyObjectResponse),
21497
- unstable_forkSession: requestSpec(AGENT_METHODS.session_fork, zForkSessionRequest, zForkSessionResponse),
21498
- resumeSession: requestSpec(AGENT_METHODS.session_resume, zResumeSessionRequest, zResumeSessionResponse),
21702
+ unstable_forkSession: requestSpec(AGENT_METHODS.session_fork, received(zForkSessionRequest), received(zForkSessionResponse)),
21703
+ resumeSession: requestSpec(AGENT_METHODS.session_resume, received(zResumeSessionRequest), received(zResumeSessionResponse)),
21499
21704
  closeSession: requestSpec(AGENT_METHODS.session_close, zCloseSessionRequest, zCloseSessionResponse, emptyObjectResponse),
21500
21705
  logoutAuth: requestSpec(AGENT_METHODS.auth_logout, zLogoutAuthRequest, zLogoutAuthResponse, emptyObjectResponse),
21501
21706
  unstable_startNes: requestSpec(AGENT_METHODS.nes_start, zStartNesRequest, zStartNesResponse),
21502
- unstable_suggestNes: requestSpec(AGENT_METHODS.nes_suggest, zSuggestNesRequest, zSuggestNesResponse),
21707
+ unstable_suggestNes: requestSpec(AGENT_METHODS.nes_suggest, received(zSuggestNesRequest), received(zSuggestNesResponse)),
21503
21708
  unstable_closeNes: requestSpec(AGENT_METHODS.nes_close, zCloseNesRequest, zCloseNesResponse, emptyObjectResponse)
21504
21709
  };
21505
21710
  var agentNotificationSpecs = {
@@ -21514,15 +21719,12 @@ var agentNotificationSpecs = {
21514
21719
  unstable_rejectNes: notificationSpec(AGENT_METHODS.nes_reject, zRejectNesNotification)
21515
21720
  };
21516
21721
  var clientRequestSpecs = {
21517
- requestPermission: requestSpec(CLIENT_METHODS.session_request_permission, zRequestPermissionRequest, zRequestPermissionResponse),
21518
- unstable_connectMcp: requestSpec(CLIENT_METHODS.mcp_connect, zConnectMcpRequest, zConnectMcpResponse),
21722
+ requestPermission: requestSpec(CLIENT_METHODS.session_request_permission, received(zRequestPermissionRequest), received(zRequestPermissionResponse)),
21519
21723
  unstable_messageMcp: requestSpec(CLIENT_METHODS.mcp_message, zMessageMcpRequest, zMessageMcpResponse),
21520
- unstable_disconnectMcp: requestSpec(CLIENT_METHODS.mcp_disconnect, zDisconnectMcpRequest, zDisconnectMcpResponse, emptyObjectResponse),
21521
- createElicitation: requestSpec(CLIENT_METHODS.elicitation_create, zCreateElicitationRequest, zCreateElicitationResponse)
21724
+ createElicitation: requestSpec(CLIENT_METHODS.elicitation_create, received(zCreateElicitationRequest), received(zCreateElicitationResponse))
21522
21725
  };
21523
21726
  var clientNotificationSpecs = {
21524
- sessionUpdate: notificationSpec(CLIENT_METHODS.session_update, zUpdateSessionNotification),
21525
- unstable_messageMcp: notificationSpec(CLIENT_METHODS.mcp_message, zMessageMcpNotification),
21727
+ sessionUpdate: notificationSpec(CLIENT_METHODS.session_update, received(zUpdateSessionNotification)),
21526
21728
  completeElicitation: notificationSpec(CLIENT_METHODS.elicitation_complete, zCompleteElicitationNotification)
21527
21729
  };
21528
21730
  var agentRequestSpecsByMethod = specsByMethod(agentRequestSpecs);
@@ -21566,7 +21768,7 @@ class SessionUpdateRouter {
21566
21768
  if (message.kind !== "notification" || message.method !== CLIENT_METHODS.session_update) {
21567
21769
  return Handled.no(message);
21568
21770
  }
21569
- const notification = zUpdateSessionNotification.parse(message.params);
21771
+ const notification = received(zUpdateSessionNotification).parse(message.params);
21570
21772
  const { update } = notification;
21571
21773
  const isIdle = SessionUpdate.isStateUpdate(update) && StateUpdate.isIdle(update);
21572
21774
  const activeSessions = this.activeSessions.get(notification.sessionId);
@@ -21844,7 +22046,7 @@ var package_default = {
21844
22046
  publishConfig: {
21845
22047
  access: "public"
21846
22048
  },
21847
- version: "0.7.4",
22049
+ version: "0.7.5",
21848
22050
  description: "Native ACP v2 agent for the OpenAI Codex app-server",
21849
22051
  packageManager: "bun@1.4.0",
21850
22052
  engines: {
@@ -21910,7 +22112,7 @@ var package_default = {
21910
22112
  vitest: "^4.1.11"
21911
22113
  },
21912
22114
  dependencies: {
21913
- "@agentclientprotocol/sdk": "^1.5.1",
22115
+ "@agentclientprotocol/sdk": "^1.7.0",
21914
22116
  diff: "^9.0.0",
21915
22117
  open: "^11.0.2",
21916
22118
  "vscode-jsonrpc": "^9.0.2"
@@ -22104,7 +22306,7 @@ function classifyTurnError(info) {
22104
22306
  }
22105
22307
 
22106
22308
  // src/agent/CodexAgent.ts
22107
- import path7 from "path";
22309
+ import path8 from "path";
22108
22310
 
22109
22311
  // src/util/logger.ts
22110
22312
  import fs from "fs";
@@ -23664,6 +23866,21 @@ function itemSnapshot(item) {
23664
23866
  }
23665
23867
  }
23666
23868
 
23869
+ // src/bridge/turnMetadata.ts
23870
+ function withTurnId(update, turnId, startedAt) {
23871
+ switch (update.sessionUpdate) {
23872
+ case "user_message":
23873
+ case "agent_message":
23874
+ case "agent_message_chunk": {
23875
+ const meta = update._meta;
23876
+ const codex = meta?.["codex"];
23877
+ return { ...update, _meta: { ...meta, codex: { ...codex, turnId, ...startedAt == null ? {} : { turnStartedAt: startedAt * 1000 } } } };
23878
+ }
23879
+ default:
23880
+ return update;
23881
+ }
23882
+ }
23883
+
23667
23884
  // src/bridge/EventBridge.ts
23668
23885
  var TURN_PLAN_ID = "codex-turn-plan";
23669
23886
  var PLAN_STREAM_INTERVAL_MS = 150;
@@ -23675,6 +23892,7 @@ class EventBridge {
23675
23892
  lastError = null;
23676
23893
  completedPlan = null;
23677
23894
  noticeSequence = 0;
23895
+ turnTime = null;
23678
23896
  openToolCalls = new Set;
23679
23897
  announcedTools = new Set;
23680
23898
  messagePhases = new Map;
@@ -23717,17 +23935,21 @@ class EventBridge {
23717
23935
  this.completedPlan = null;
23718
23936
  return plan;
23719
23937
  }
23720
- async restore(items) {
23938
+ async restore(items, turnId) {
23721
23939
  for (const item of items) {
23722
23940
  if (item.type === "commandExecution" && item.status === "inProgress" && usesTerminal(item))
23723
23941
  this.terminalItems.add(item.id);
23724
23942
  for (const update of itemSnapshot(item)) {
23725
23943
  this.trackToolCall(update);
23726
- await this.client.update(update);
23944
+ await this.client.update(withTurnId(update, turnId));
23727
23945
  }
23728
23946
  }
23729
23947
  }
23730
23948
  async handle(notification) {
23949
+ if (notification.method === "turn/started" || notification.method === "turn/completed") {
23950
+ const { id, startedAt } = notification.params.turn;
23951
+ this.turnTime = { id, startedAt };
23952
+ }
23731
23953
  let updates = await this.translate(notification);
23732
23954
  if (notification.method === "item/completed") {
23733
23955
  const snapshots = itemSnapshot(notification.params.item);
@@ -23738,7 +23960,8 @@ class EventBridge {
23738
23960
  }
23739
23961
  for (const update of updates) {
23740
23962
  this.trackToolCall(update);
23741
- await this.client.update(update);
23963
+ const turnId = "turnId" in notification.params ? notification.params.turnId : null;
23964
+ await this.client.update(typeof turnId === "string" ? withTurnId(update, turnId, this.turnTime?.id === turnId ? this.turnTime.startedAt : null) : update);
23742
23965
  }
23743
23966
  }
23744
23967
  async finishOpenToolCalls(status) {
@@ -26630,7 +26853,7 @@ function historyUpdates(turns) {
26630
26853
  const updates = [];
26631
26854
  for (const turn of turns) {
26632
26855
  for (const item of turn.items) {
26633
- updates.push(...itemSnapshot(item));
26856
+ updates.push(...itemSnapshot(item).map((update) => withTurnId(update, turn.id, turn.startedAt)));
26634
26857
  }
26635
26858
  }
26636
26859
  return updates;
@@ -26656,6 +26879,93 @@ function firstLine(text2) {
26656
26879
  return line.length > 120 ? `${line.slice(0, 117)}...` : line;
26657
26880
  }
26658
26881
 
26882
+ // src/agent/forkIndex.ts
26883
+ import { createReadStream } from "fs";
26884
+ import { readdir, realpath } from "fs/promises";
26885
+ import path7 from "path";
26886
+ import { createInterface } from "readline";
26887
+ var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
26888
+ var SOURCES = new Set(["cli", "vscode", "exec", "appServer", "unknown"]);
26889
+ var missing = (error40) => error40?.code === "ENOENT";
26890
+ async function nativeForks(codexHome, archived, cwd, read) {
26891
+ const root = path7.join(codexHome, archived ? "archived_sessions" : "sessions");
26892
+ const wantedCwd = cwd === null ? null : await realpath(cwd).catch((error40) => {
26893
+ if (missing(error40))
26894
+ return cwd;
26895
+ throw error40;
26896
+ });
26897
+ const result = [];
26898
+ for await (const file2 of rolloutFiles(root)) {
26899
+ const header = await firstLine2(file2);
26900
+ if (header === null)
26901
+ continue;
26902
+ let value;
26903
+ try {
26904
+ value = JSON.parse(header);
26905
+ } catch {
26906
+ continue;
26907
+ }
26908
+ if (!value || typeof value !== "object" || !("type" in value) || value.type !== "session_meta" || !("payload" in value))
26909
+ continue;
26910
+ const meta = value.payload;
26911
+ if (!meta || typeof meta["id"] !== "string" || !UUID.test(meta["id"]) || typeof meta["forked_from_id"] !== "string" || !UUID.test(meta["forked_from_id"]) || typeof meta["source"] !== "string" || !SOURCES.has(meta["source"]) || wantedCwd !== null && meta["cwd"] !== wantedCwd && meta["cwd"] !== cwd)
26912
+ continue;
26913
+ const thread = await read(meta["id"]).catch(async (error40) => {
26914
+ try {
26915
+ await realpath(file2);
26916
+ } catch (statError) {
26917
+ if (missing(statError))
26918
+ return null;
26919
+ }
26920
+ throw error40;
26921
+ });
26922
+ if (thread && thread.forkedFromId !== null) {
26923
+ try {
26924
+ await realpath(file2);
26925
+ } catch (error40) {
26926
+ if (missing(error40))
26927
+ continue;
26928
+ throw error40;
26929
+ }
26930
+ result.push(cwd === null ? thread : { ...thread, cwd });
26931
+ }
26932
+ }
26933
+ return result;
26934
+ }
26935
+ async function* rolloutFiles(directory) {
26936
+ let entries;
26937
+ try {
26938
+ entries = await readdir(directory, { withFileTypes: true });
26939
+ } catch (error40) {
26940
+ if (missing(error40))
26941
+ return;
26942
+ throw error40;
26943
+ }
26944
+ for (const entry of entries) {
26945
+ const file2 = path7.join(directory, entry.name);
26946
+ if (entry.isDirectory())
26947
+ yield* rolloutFiles(file2);
26948
+ else if (entry.isFile() && /^rollout-.*\.jsonl$/.test(entry.name))
26949
+ yield file2;
26950
+ }
26951
+ }
26952
+ async function firstLine2(file2) {
26953
+ const stream = createReadStream(file2, { encoding: "utf8" });
26954
+ const lines = createInterface({ input: stream, crlfDelay: Infinity });
26955
+ try {
26956
+ for await (const line of lines)
26957
+ return line;
26958
+ return null;
26959
+ } catch (error40) {
26960
+ if (missing(error40))
26961
+ return null;
26962
+ throw error40;
26963
+ } finally {
26964
+ lines.close();
26965
+ stream.destroy();
26966
+ }
26967
+ }
26968
+
26659
26969
  // src/agent/session.ts
26660
26970
  function createActiveTurn(threadId, clientUserMessageId = null) {
26661
26971
  let resolveStarted = () => {};
@@ -26723,6 +27033,7 @@ class CodexAgent {
26723
27033
  sessions = new Map;
26724
27034
  capabilities = null;
26725
27035
  codexInitialized = false;
27036
+ codexHome = null;
26726
27037
  initializing = null;
26727
27038
  terminalTurns = new WeakSet;
26728
27039
  completedTurns = new WeakMap;
@@ -26773,10 +27084,11 @@ class CodexAgent {
26773
27084
  };
26774
27085
  if (!this.codexInitialized) {
26775
27086
  this.initializing ??= this.withCodex(async () => {
26776
- await this.codex.initialize({
27087
+ const initialized = await this.codex.initialize({
26777
27088
  clientInfo: { name: params.info.name, title: params.info.title ?? null, version: params.info.version },
26778
27089
  capabilities: { experimentalApi: true, requestAttestation: false }
26779
27090
  });
27091
+ this.codexHome = initialized.codexHome;
26780
27092
  this.codexInitialized = true;
26781
27093
  }).finally(() => {
26782
27094
  this.initializing = null;
@@ -26796,7 +27108,7 @@ class CodexAgent {
26796
27108
  additionalDirectories: {}
26797
27109
  },
26798
27110
  providers: {},
26799
- _meta: { alwith: { tools: { version: 1 }, turns: { version: 2 } }, codex: { archive: true, seedHistory: true, skills: true, plugins: true, providerCatalog: true, rename: true, account: true, fuzzyFileSearch: true } }
27111
+ _meta: { alwith: { tools: { version: 1 }, turns: { version: 2 } }, codex: { forkAtTurn: true, sessionLineage: true, archive: true, seedHistory: true, skills: true, plugins: true, providerCatalog: true, rename: true, account: true, fuzzyFileSearch: true } }
26800
27112
  },
26801
27113
  authMethods: authMethods(this.capabilities, this.env)
26802
27114
  };
@@ -26971,16 +27283,16 @@ class CodexAgent {
26971
27283
  }
26972
27284
  async newSession(params, signal) {
26973
27285
  const runtime = await this.openSession({ kind: "new", request: params }, signal);
26974
- return { sessionId: runtime.session.id, configOptions: sessionConfigOptions(runtime.session) };
27286
+ return { sessionId: runtime.session.id, configOptions: sessionConfigOptions(runtime.session), _meta: { codex: runtime.lineage } };
26975
27287
  }
26976
27288
  async resumeSession(params, signal) {
26977
27289
  const runtime = await this.openSession({ kind: "resume", request: params }, signal);
26978
27290
  const configOptions = sessionConfigOptions(runtime.session);
26979
- return runtime.readOnly ? { configOptions, _meta: { codex: { readOnly: true, reason: "active_writer" } } } : { configOptions };
27291
+ return { configOptions, _meta: { codex: { ...runtime.lineage, ...runtime.readOnly ? { readOnly: true, reason: "active_writer" } : {} } } };
26980
27292
  }
26981
27293
  async forkSession(params, signal) {
26982
27294
  const runtime = await this.openSession({ kind: "fork", request: params }, signal);
26983
- return { sessionId: runtime.session.id, configOptions: sessionConfigOptions(runtime.session) };
27295
+ return { sessionId: runtime.session.id, configOptions: sessionConfigOptions(runtime.session), _meta: { codex: runtime.lineage } };
26984
27296
  }
26985
27297
  async openSession(open2, signal) {
26986
27298
  if (signal?.aborted)
@@ -27012,7 +27324,8 @@ class CodexAgent {
27012
27324
  if (open2.kind !== "new")
27013
27325
  this.assertUnsubscribeSettled(open2.request.sessionId);
27014
27326
  const { request } = open2;
27015
- if (typeof request.cwd !== "string" || !path7.isAbsolute(request.cwd)) {
27327
+ const lastTurnId = open2.kind === "fork" ? forkTurnId(request._meta) : undefined;
27328
+ if (typeof request.cwd !== "string" || !path8.isAbsolute(request.cwd)) {
27016
27329
  throw RequestError.invalidParams({ cwd: request.cwd }, "cwd must be an absolute path");
27017
27330
  }
27018
27331
  if (open2.kind === "resume" && open2.request.replayFrom != null && open2.request.replayFrom.type !== "start") {
@@ -27077,7 +27390,7 @@ class CodexAgent {
27077
27390
  return readOnlyThread((await this.codex.threadRead({ threadId: open2.request.sessionId, includeTurns: false })).thread, request.cwd);
27078
27391
  }
27079
27392
  case "fork":
27080
- return await this.codex.threadFork({ ...hostThreadOptions, threadId: open2.request.sessionId, config: config2, cwd: request.cwd, modelProvider, model: startModel, excludeTurns: true });
27393
+ return await this.codex.threadFork({ ...hostThreadOptions, ...lastTurnId === undefined ? {} : { lastTurnId }, threadId: open2.request.sessionId, config: config2, cwd: request.cwd, modelProvider, model: startModel, excludeTurns: true });
27081
27394
  }
27082
27395
  }) }));
27083
27396
  const sessionId = thread.thread.id;
@@ -27127,7 +27440,7 @@ class CodexAgent {
27127
27440
  contextWindow: null,
27128
27441
  closed: false
27129
27442
  };
27130
- const runtime = this.installRuntime(session, capabilities, config2, gatewayId ?? thread.modelProvider, readOnly);
27443
+ const runtime = this.installRuntime(session, capabilities, config2, gatewayId ?? thread.modelProvider, threadLineage(thread.thread), readOnly);
27131
27444
  const cancelOpening = () => {
27132
27445
  runtime.session.closed = true;
27133
27446
  runtime.lifetime.abort();
@@ -27174,7 +27487,7 @@ class CodexAgent {
27174
27487
  stopObservingOpen();
27175
27488
  }
27176
27489
  }
27177
- installRuntime(session, capabilities, config2, modelProvider, readOnly = false) {
27490
+ installRuntime(session, capabilities, config2, modelProvider, lineage, readOnly = false) {
27178
27491
  const client = new ClientSession(session.id, this.link, capabilities);
27179
27492
  const bridge = new EventBridge(client, session);
27180
27493
  const turnContext = new TurnContext(session.id);
@@ -27184,7 +27497,7 @@ class CodexAgent {
27184
27497
  };
27185
27498
  const approval = new CodexApprovalHandler(client, turnContext, signal);
27186
27499
  const elicitation = new CodexElicitationHandler(client, turnContext, signal);
27187
- const runtime = { config: config2, modelProvider, stale: false, readOnly, session, client, bridge, turnContext, elicitation, lifetime: new AbortController, queue: Promise.resolve() };
27500
+ const runtime = { lineage, config: config2, modelProvider, stale: false, readOnly, session, client, bridge, turnContext, elicitation, lifetime: new AbortController, queue: Promise.resolve() };
27188
27501
  const tools = new ClientTools(session, client, AbortSignal.any([runtime.lifetime.signal, this.codex.disconnectSignal]));
27189
27502
  const drained = (operation) => async (params) => {
27190
27503
  await abortable(this.drain(runtime), this.codex.disconnectSignal);
@@ -27271,10 +27584,31 @@ class CodexAgent {
27271
27584
  await publishTitle(firstPage.data);
27272
27585
  return;
27273
27586
  }
27587
+ const parentTurns = new Set;
27588
+ if (thread.forkedFromId !== null) {
27589
+ let parentCursor = null;
27590
+ const seen = new Set;
27591
+ do {
27592
+ const page = await this.withCodex(() => this.codex.threadTurnsList({ threadId: thread.forkedFromId, cursor: parentCursor, limit: HISTORY_PAGE_SIZE, sortDirection: "asc", itemsView: "summary" }));
27593
+ for (const turn of page.data)
27594
+ parentTurns.add(turn.id);
27595
+ parentCursor = page.nextCursor;
27596
+ if (parentCursor !== null) {
27597
+ if (seen.has(parentCursor))
27598
+ throw RequestError.internalError(undefined, "Codex parent history repeated a cursor");
27599
+ seen.add(parentCursor);
27600
+ }
27601
+ } while (parentCursor !== null && !session.closed);
27602
+ runtime.lineage.forkedAtTurnId = null;
27603
+ }
27274
27604
  const cursors = new Set;
27275
27605
  let cursor = null;
27276
27606
  do {
27277
27607
  const page = await this.turnPage(session.id, cursor);
27608
+ for (const turn of page.data) {
27609
+ if (parentTurns.has(turn.id))
27610
+ runtime.lineage.forkedAtTurnId = turn.id;
27611
+ }
27278
27612
  await publishTitle(page.data);
27279
27613
  await client.updateAll(historyUpdates(page.data));
27280
27614
  cursor = page.nextCursor;
@@ -27322,19 +27656,43 @@ class CodexAgent {
27322
27656
  this.requireInitialized("session/list");
27323
27657
  const cwd = params.cwd?.trim() || null;
27324
27658
  const archived = archivedFilter(params._meta);
27325
- const response = await this.withCodex(() => this.codex.threadList({
27326
- cursor: params.cursor ?? null,
27659
+ const list = (cursor) => this.withCodex(() => this.codex.threadList({
27660
+ cursor,
27327
27661
  ...cwd ? { cwd } : {},
27328
27662
  sourceKinds: ["cli", "vscode", "exec", "appServer", "unknown"],
27329
27663
  ...archived ? { archived: true } : {}
27330
27664
  }));
27665
+ const response = await list(params.cursor ?? null);
27666
+ const home = this.codexHome;
27667
+ if (home === null)
27668
+ throw RequestError.internalError(undefined, "Codex home is unavailable after initialize");
27669
+ const forks = await this.withCodex(() => nativeForks(home, archived, cwd, async (id) => (await this.codex.threadRead({ threadId: id, includeTurns: false })).thread));
27670
+ const byId = new Map(forks.map((thread) => [thread.id, thread]));
27671
+ response.data = response.data.map((thread) => byId.get(thread.id) ?? thread);
27672
+ if (!params.cursor) {
27673
+ const missing2 = new Map(byId);
27674
+ for (const thread of response.data)
27675
+ missing2.delete(thread.id);
27676
+ let cursor = response.nextCursor;
27677
+ const cursors = new Set;
27678
+ while (missing2.size > 0 && cursor !== null) {
27679
+ if (cursors.has(cursor))
27680
+ throw RequestError.internalError(undefined, "Codex thread list repeated a cursor");
27681
+ cursors.add(cursor);
27682
+ const page = await list(cursor);
27683
+ for (const thread of page.data)
27684
+ missing2.delete(thread.id);
27685
+ cursor = page.nextCursor;
27686
+ }
27687
+ response.data.push(...missing2.values());
27688
+ }
27331
27689
  return {
27332
27690
  sessions: response.data.map((thread) => ({
27333
27691
  sessionId: thread.id,
27334
27692
  cwd: thread.cwd,
27335
27693
  title: thread.name?.trim() || thread.preview.trim() || null,
27336
27694
  updatedAt: new Date(thread.updatedAt * 1000).toISOString(),
27337
- _meta: { codex: { archived } }
27695
+ _meta: { codex: { archived, ...threadLineage(thread) } }
27338
27696
  })),
27339
27697
  nextCursor: response.nextCursor
27340
27698
  };
@@ -27600,8 +27958,12 @@ class CodexAgent {
27600
27958
  async runPrompt(runtime, turn, params, observed, items = []) {
27601
27959
  const { session, bridge } = runtime;
27602
27960
  bridge.beginTurn();
27603
- if (items.length)
27604
- runtime.queue = runtime.queue.then(() => bridge.restore(items));
27961
+ if (items.length) {
27962
+ const turnId = turn.turnId;
27963
+ if (turnId === null)
27964
+ throw RequestError.internalError(undefined, "Cannot restore items without their turn id");
27965
+ runtime.queue = runtime.queue.then(() => bridge.restore(items, turnId));
27966
+ }
27605
27967
  try {
27606
27968
  const command = parseCommand(params.prompt);
27607
27969
  const outcome = command ? resolveCommand(command, session) : { kind: "prompt" };
@@ -27861,7 +28223,7 @@ ${error40.additionalDetails}` : error40.message;
27861
28223
  }
27862
28224
  withSkillsContext(cwd, additionalDirectories, operation) {
27863
28225
  const run = async () => {
27864
- const roots = additionalDirectories.map((root) => path7.join(root, ".agents", "skills"));
28226
+ const roots = additionalDirectories.map((root) => path8.join(root, ".agents", "skills"));
27865
28227
  if (roots.length !== this.skillRoots.length || roots.some((root, index) => root !== this.skillRoots[index])) {
27866
28228
  this.changingSkillRoots = true;
27867
28229
  try {
@@ -27895,7 +28257,7 @@ ${error40.additionalDetails}` : error40.message;
27895
28257
  }
27896
28258
  async refreshAvailableCommands(runtime) {
27897
28259
  const run = async () => {
27898
- const roots = runtime.session.additionalDirectories.map((root) => path7.join(root, ".agents", "skills"));
28260
+ const roots = runtime.session.additionalDirectories.map((root) => path8.join(root, ".agents", "skills"));
27899
28261
  if (runtime.session.closed || roots.length !== this.skillRoots.length || roots.some((root, i) => root !== this.skillRoots[i]))
27900
28262
  return;
27901
28263
  return await this.loadSkills(runtime.session.cwd, runtime.session.additionalDirectories);
@@ -28130,6 +28492,18 @@ async function within(operation, ms) {
28130
28492
  clearTimeout(timer);
28131
28493
  }
28132
28494
  }
28495
+ function threadLineage(thread) {
28496
+ return { nativeSessionId: thread.sessionId, forkedFromId: thread.forkedFromId };
28497
+ }
28498
+ function forkTurnId(meta) {
28499
+ const value = meta?.codex?.lastTurnId;
28500
+ if (value === undefined)
28501
+ return;
28502
+ if (typeof value !== "string" || value.trim().length === 0) {
28503
+ throw RequestError.invalidParams(undefined, "lastTurnId must be a non-empty Codex turn id");
28504
+ }
28505
+ return value;
28506
+ }
28133
28507
 
28134
28508
  // src/agent/createAgent.ts
28135
28509
  function createAgentApp(options) {
@@ -28608,7 +28982,7 @@ function threadIdOf(notification) {
28608
28982
  // src/codex/process.ts
28609
28983
  import { existsSync, mkdtempSync, readFileSync as readFileSync2, writeFileSync } from "fs";
28610
28984
  import os3 from "os";
28611
- import path8 from "path";
28985
+ import path9 from "path";
28612
28986
  import { spawn, spawnSync } from "child_process";
28613
28987
  import { createRequire } from "module";
28614
28988
 
@@ -28901,11 +29275,11 @@ function resolveCodexLauncher(codexPath) {
28901
29275
  const target = targets[platform2];
28902
29276
  if (!target)
28903
29277
  throw new Error(`Unsupported Codex platform: ${platform2}`);
28904
- let vendor = path8.resolve(path8.dirname(launcher), "..", "vendor");
29278
+ let vendor = path9.resolve(path9.dirname(launcher), "..", "vendor");
28905
29279
  try {
28906
- vendor = path8.join(path8.dirname(platformRequire.resolve(`@openai/codex-${platform2}/package.json`)), "vendor");
29280
+ vendor = path9.join(path9.dirname(platformRequire.resolve(`@openai/codex-${platform2}/package.json`)), "vendor");
28907
29281
  } catch {}
28908
- const command = path8.join(vendor, target, "bin", process.platform === "win32" ? "codex.exe" : "codex");
29282
+ const command = path9.join(vendor, target, "bin", process.platform === "win32" ? "codex.exe" : "codex");
28909
29283
  if (!existsSync(command))
28910
29284
  throw new Error(`Missing Codex platform binary: ${command}`);
28911
29285
  return { command, prefixArgs: [], shell: false };
@@ -28951,7 +29325,7 @@ function mergedModelCatalog(launcher, env) {
28951
29325
  const raw = env[EXTRA_MODEL_CATALOGS_ENV];
28952
29326
  if (raw === undefined || raw.trim() === "")
28953
29327
  return null;
28954
- const files = raw.split(path8.delimiter).filter((file2) => file2.length > 0);
29328
+ const files = raw.split(path9.delimiter).filter((file2) => file2.length > 0);
28955
29329
  const dump = spawnSync(launcher.command, [...launcher.prefixArgs, "debug", "models"], {
28956
29330
  shell: launcher.shell,
28957
29331
  env,
@@ -28979,8 +29353,8 @@ function mergedModelCatalog(launcher, env) {
28979
29353
  models.push({ ...entry, visibility: "hide" });
28980
29354
  }
28981
29355
  }
28982
- const directory = mkdtempSync(path8.join(os3.tmpdir(), "codex-acp-v2-catalog-"));
28983
- const target = path8.join(directory, "models.json");
29356
+ const directory = mkdtempSync(path9.join(os3.tmpdir(), "codex-acp-v2-catalog-"));
29357
+ const target = path9.join(directory, "models.json");
28984
29358
  writeFileSync(target, JSON.stringify({ ...base, models }));
28985
29359
  return target;
28986
29360
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.7.4",
6
+ "version": "0.7.5",
7
7
  "description": "Native ACP v2 agent for the OpenAI Codex app-server",
8
8
  "packageManager": "bun@1.4.0",
9
9
  "engines": {
@@ -69,7 +69,7 @@
69
69
  "vitest": "^4.1.11"
70
70
  },
71
71
  "dependencies": {
72
- "@agentclientprotocol/sdk": "^1.5.1",
72
+ "@agentclientprotocol/sdk": "^1.7.0",
73
73
  "diff": "^9.0.0",
74
74
  "open": "^11.0.2",
75
75
  "vscode-jsonrpc": "^9.0.2"