@skaile/workspaces 3.18.0 → 3.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/dist/{asset-feeds-LT4GI576.js → asset-feeds-V4DZPOVS.js} +7 -7
  3. package/dist/{asset-feeds-LT4GI576.js.map → asset-feeds-V4DZPOVS.js.map} +1 -1
  4. package/dist/asset-manager/catalog-deployer.js +3 -3
  5. package/dist/asset-manager/index.js +6 -6
  6. package/dist/asset-manager/installer.js +4 -4
  7. package/dist/asset-manager/src/index.d.ts +7 -0
  8. package/dist/asset-manager/src/index.d.ts.map +1 -1
  9. package/dist/bridge/codex-app-server.js +1 -1
  10. package/dist/bridge/drivers/claude-sdk.js +4 -4
  11. package/dist/bridge/drivers/codex.js +147 -48
  12. package/dist/bridge/drivers/codex.js.map +1 -1
  13. package/dist/bridge/drivers/continue.js +2 -2
  14. package/dist/bridge/drivers/echo.js +1 -1
  15. package/dist/bridge/drivers/gemini.js +3 -3
  16. package/dist/bridge/drivers/goose.js +2 -2
  17. package/dist/bridge/drivers/omp.js +1 -1
  18. package/dist/bridge/drivers/opencode.js +2 -2
  19. package/dist/bridge/drivers/qwen.js +3 -3
  20. package/dist/bridge/index.js +5 -5
  21. package/dist/bridge/src/codex/managed-driver.d.ts +2 -0
  22. package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
  23. package/dist/bridge/src/codex/native-mcp-approval.d.ts +13 -0
  24. package/dist/bridge/src/codex/native-mcp-approval.d.ts.map +1 -0
  25. package/dist/bridge/src/codex/native-protocol.generated.d.ts +5 -1
  26. package/dist/bridge/src/codex/native-protocol.generated.d.ts.map +1 -1
  27. package/dist/bridge/src/codex/questions.d.ts +2 -2
  28. package/dist/bridge/src/codex/questions.d.ts.map +1 -1
  29. package/dist/bridge/src/codex-app-server.d.ts +2 -0
  30. package/dist/bridge/src/codex-app-server.d.ts.map +1 -1
  31. package/dist/bridge/src/normalizer.d.ts.map +1 -1
  32. package/dist/bridge/src/types.d.ts +7 -1
  33. package/dist/bridge/src/types.d.ts.map +1 -1
  34. package/dist/{chunk-IT42ZT3T.js → chunk-5JTA7HNJ.js} +9 -9
  35. package/dist/{chunk-IT42ZT3T.js.map → chunk-5JTA7HNJ.js.map} +1 -1
  36. package/dist/{chunk-J7VSUGGH.js → chunk-6FZCQT3V.js} +2 -2
  37. package/dist/chunk-6FZCQT3V.js.map +1 -0
  38. package/dist/{chunk-XL45U3C5.js → chunk-6H6HLMWG.js} +3 -3
  39. package/dist/{chunk-XL45U3C5.js.map → chunk-6H6HLMWG.js.map} +1 -1
  40. package/dist/{chunk-AI2PZX4H.js → chunk-74KGZA7R.js} +3 -3
  41. package/dist/{chunk-AI2PZX4H.js.map → chunk-74KGZA7R.js.map} +1 -1
  42. package/dist/{chunk-67KB2A77.js → chunk-AQJ5ZYD6.js} +36 -25
  43. package/dist/chunk-AQJ5ZYD6.js.map +1 -0
  44. package/dist/{chunk-FYVDBIZV.js → chunk-BGURUGZW.js} +6 -6
  45. package/dist/{chunk-FYVDBIZV.js.map → chunk-BGURUGZW.js.map} +1 -1
  46. package/dist/{chunk-BJI7IGZF.js → chunk-CGLJHFQI.js} +7 -7
  47. package/dist/{chunk-BJI7IGZF.js.map → chunk-CGLJHFQI.js.map} +1 -1
  48. package/dist/{chunk-RJOGAEIY.js → chunk-D2TTGUMZ.js} +14 -13
  49. package/dist/chunk-D2TTGUMZ.js.map +1 -0
  50. package/dist/{chunk-GRA4BWCV.js → chunk-DFELEIPJ.js} +5 -5
  51. package/dist/{chunk-GRA4BWCV.js.map → chunk-DFELEIPJ.js.map} +1 -1
  52. package/dist/{chunk-4JDCKPTM.js → chunk-EKFFTOQJ.js} +2 -2
  53. package/dist/{chunk-4JDCKPTM.js.map → chunk-EKFFTOQJ.js.map} +1 -1
  54. package/dist/{chunk-GMMACS5W.js → chunk-F4ORFHB5.js} +4 -4
  55. package/dist/{chunk-GMMACS5W.js.map → chunk-F4ORFHB5.js.map} +1 -1
  56. package/dist/{chunk-H662SXKS.js → chunk-HSRHO7SK.js} +4 -4
  57. package/dist/{chunk-H662SXKS.js.map → chunk-HSRHO7SK.js.map} +1 -1
  58. package/dist/{chunk-DCG4UWJM.js → chunk-IB4XKQMQ.js} +3 -3
  59. package/dist/{chunk-DCG4UWJM.js.map → chunk-IB4XKQMQ.js.map} +1 -1
  60. package/dist/{chunk-2IROGAS7.js → chunk-IUOXPQA3.js} +2 -2
  61. package/dist/{chunk-2IROGAS7.js.map → chunk-IUOXPQA3.js.map} +1 -1
  62. package/dist/{chunk-CQY7XKRV.js → chunk-K5BUXOBH.js} +5 -4
  63. package/dist/chunk-K5BUXOBH.js.map +1 -0
  64. package/dist/{chunk-RPVTPVGX.js → chunk-MBARHWMZ.js} +71 -36
  65. package/dist/chunk-MBARHWMZ.js.map +1 -0
  66. package/dist/{chunk-QEZPFJX3.js → chunk-NCHMJPKN.js} +3 -3
  67. package/dist/{chunk-QEZPFJX3.js.map → chunk-NCHMJPKN.js.map} +1 -1
  68. package/dist/{chunk-JVFZ5R7L.js → chunk-NW65H5EV.js} +3 -3
  69. package/dist/{chunk-JVFZ5R7L.js.map → chunk-NW65H5EV.js.map} +1 -1
  70. package/dist/{chunk-S635WMXH.js → chunk-OHLYKLGJ.js} +4 -4
  71. package/dist/{chunk-S635WMXH.js.map → chunk-OHLYKLGJ.js.map} +1 -1
  72. package/dist/{chunk-FBD5SOIH.js → chunk-OJOK4VKC.js} +3 -3
  73. package/dist/{chunk-FBD5SOIH.js.map → chunk-OJOK4VKC.js.map} +1 -1
  74. package/dist/{chunk-XKSGEYZC.js → chunk-PHBYB4XT.js} +5 -2
  75. package/dist/chunk-PHBYB4XT.js.map +1 -0
  76. package/dist/{chunk-SH7GXS7V.js → chunk-PLLVREB2.js} +59 -26
  77. package/dist/chunk-PLLVREB2.js.map +1 -0
  78. package/dist/{chunk-X3LUB275.js → chunk-PVVPGD7P.js} +4 -4
  79. package/dist/{chunk-X3LUB275.js.map → chunk-PVVPGD7P.js.map} +1 -1
  80. package/dist/{chunk-5T7Y3AZU.js → chunk-SIREWRZE.js} +3 -3
  81. package/dist/{chunk-5T7Y3AZU.js.map → chunk-SIREWRZE.js.map} +1 -1
  82. package/dist/{chunk-QG2ZXU5W.js → chunk-TCHEW3T2.js} +4 -4
  83. package/dist/{chunk-QG2ZXU5W.js.map → chunk-TCHEW3T2.js.map} +1 -1
  84. package/dist/{chunk-SFCVAEJ5.js → chunk-W5LPG3X6.js} +3 -3
  85. package/dist/{chunk-SFCVAEJ5.js.map → chunk-W5LPG3X6.js.map} +1 -1
  86. package/dist/cli/index.js +47 -47
  87. package/dist/connectors/config.js +4 -4
  88. package/dist/connectors/index.js +8 -8
  89. package/dist/core/index.js +3 -3
  90. package/dist/core/runtime-assets.js +2 -2
  91. package/dist/core/src/index.d.ts +2 -2
  92. package/dist/core/src/index.d.ts.map +1 -1
  93. package/dist/core/src/repo-manager.d.ts +30 -1
  94. package/dist/core/src/repo-manager.d.ts.map +1 -1
  95. package/dist/core/workspace-config.js +1 -1
  96. package/dist/deploy/index.js +3 -3
  97. package/dist/{ensure-sources-4BQ6GMYG.js → ensure-sources-HXAPBBA5.js} +9 -9
  98. package/dist/{ensure-sources-4BQ6GMYG.js.map → ensure-sources-HXAPBBA5.js.map} +1 -1
  99. package/dist/factory-assets/connectors/box.js +8 -8
  100. package/dist/factory-assets/connectors/deploy.js +8 -8
  101. package/dist/factory-assets/connectors/devserver.js +8 -8
  102. package/dist/factory-assets/connectors/flow/adapter.js +8 -8
  103. package/dist/factory-assets/connectors/flow/engine.js +4 -4
  104. package/dist/factory-assets/connectors/flow/run-flow.js +9 -9
  105. package/dist/factory-assets/connectors/flow.js +8 -8
  106. package/dist/factory-assets/connectors/git/driver.d.ts.map +1 -1
  107. package/dist/factory-assets/connectors/git.js +8 -8
  108. package/dist/factory-assets/connectors/gmail.js +8 -8
  109. package/dist/factory-assets/connectors/googledrive.js +8 -8
  110. package/dist/factory-assets/connectors/local.js +8 -8
  111. package/dist/factory-assets/connectors/mattermost.js +8 -8
  112. package/dist/factory-assets/connectors/memory.js +8 -8
  113. package/dist/factory-assets/connectors/minio.js +8 -8
  114. package/dist/factory-assets/connectors/postgres.js +8 -8
  115. package/dist/factory-assets/connectors/s3.js +8 -8
  116. package/dist/factory-assets/connectors/sharepoint.js +8 -8
  117. package/dist/factory-assets/connectors/sqlite.js +8 -8
  118. package/dist/factory-assets/connectors/static-server.js +8 -8
  119. package/dist/factory-assets/connectors/tunnel.js +8 -8
  120. package/dist/factory-assets/connectors/webdav.js +8 -8
  121. package/dist/factory-assets/connectors/xstate-store.js +8 -8
  122. package/dist/factory-assets/connectors/xstate.js +8 -8
  123. package/dist/{flows-COBS26MK.js → flows-4DYGXE4A.js} +6 -6
  124. package/dist/{flows-COBS26MK.js.map → flows-4DYGXE4A.js.map} +1 -1
  125. package/dist/{helpers-4UJMSN6T.js → helpers-3VAE3TYQ.js} +9 -9
  126. package/dist/{helpers-4UJMSN6T.js.map → helpers-3VAE3TYQ.js.map} +1 -1
  127. package/dist/library/index.js +4 -4
  128. package/dist/library/install.js +3 -3
  129. package/dist/{library-publish-QHQDN4IC.js → library-publish-Z7QQDGOL.js} +13 -13
  130. package/dist/{library-publish-QHQDN4IC.js.map → library-publish-Z7QQDGOL.js.map} +1 -1
  131. package/dist/{open-library-ZDM6DUKJ.js → open-library-424UBGA7.js} +11 -11
  132. package/dist/{open-library-ZDM6DUKJ.js.map → open-library-424UBGA7.js.map} +1 -1
  133. package/dist/{paths-CZPCCBYX.js → paths-CZEH643M.js} +6 -6
  134. package/dist/{paths-CZPCCBYX.js.map → paths-CZEH643M.js.map} +1 -1
  135. package/dist/{plugin-store-ZEIBSNTO.js → plugin-store-QJNBPIQK.js} +5 -5
  136. package/dist/{plugin-store-ZEIBSNTO.js.map → plugin-store-QJNBPIQK.js.map} +1 -1
  137. package/dist/{project-JJUAAI7N.js → project-HLSVZVAF.js} +10 -10
  138. package/dist/{project-JJUAAI7N.js.map → project-HLSVZVAF.js.map} +1 -1
  139. package/dist/resolver/index.js +3 -3
  140. package/dist/runner/index.js +13 -13
  141. package/dist/runner/src/codex-tools.d.ts.map +1 -1
  142. package/dist/sdk/asset-manager.js +6 -6
  143. package/dist/sdk/bridge.js +5 -5
  144. package/dist/sdk/core.js +3 -3
  145. package/dist/sdk/flow.js +4 -4
  146. package/dist/sdk/index.js +13 -13
  147. package/dist/sdk/resolver.js +3 -3
  148. package/dist/sdk/runner.js +13 -13
  149. package/dist/{setup-PS6ZERZ5.js → setup-WXYQJW56.js} +7 -7
  150. package/dist/{setup-PS6ZERZ5.js.map → setup-WXYQJW56.js.map} +1 -1
  151. package/dist/{skills-LG6IQSSN.js → skills-IE3IWWB7.js} +5 -5
  152. package/dist/{skills-LG6IQSSN.js.map → skills-IE3IWWB7.js.map} +1 -1
  153. package/dist/{source-QLDIZCI3.js → source-SWZRKTKL.js} +12 -12
  154. package/dist/{source-QLDIZCI3.js.map → source-SWZRKTKL.js.map} +1 -1
  155. package/dist/{source-manifest-publish-J3AVCTLX.js → source-manifest-publish-XBRXFOHO.js} +14 -14
  156. package/dist/{source-manifest-publish-J3AVCTLX.js.map → source-manifest-publish-XBRXFOHO.js.map} +1 -1
  157. package/dist/tui/index.js +13 -13
  158. package/dist/types/src/events.d.ts +3 -3
  159. package/dist/types/src/events.d.ts.map +1 -1
  160. package/dist/workspace-plugin/adapters/mcp.js +5 -5
  161. package/dist/workspace-plugin/adapters/omp.js +7 -7
  162. package/dist/workspace-plugin/index.js +1 -1
  163. package/package.json +2 -1
  164. package/dist/chunk-67KB2A77.js.map +0 -1
  165. package/dist/chunk-CQY7XKRV.js.map +0 -1
  166. package/dist/chunk-J7VSUGGH.js.map +0 -1
  167. package/dist/chunk-RJOGAEIY.js.map +0 -1
  168. package/dist/chunk-RPVTPVGX.js.map +0 -1
  169. package/dist/chunk-SH7GXS7V.js.map +0 -1
  170. package/dist/chunk-XKSGEYZC.js.map +0 -1
@@ -1,14 +1,15 @@
1
- import { CodexAppServerClient } from '../../chunk-XKSGEYZC.js';
2
- import { parseCodexCredential, prepareNativePolicy, prepareCodexInstance, codexInstanceEnvironment, activateNativeApprovalPolicy, parseCodexRefreshResult, isNativeApprovalPolicyActive, allowsNativeApprovalPath } from '../../chunk-T3YLZQS4.js';
1
+ import { CodexAppServerClient } from '../../chunk-PHBYB4XT.js';
2
+ import { parseCodexCredential, prepareNativePolicy, prepareCodexInstance, codexInstanceEnvironment, isNativeApprovalPolicyActive, activateNativeApprovalPolicy, parseCodexRefreshResult, allowsNativeApprovalPath } from '../../chunk-T3YLZQS4.js';
3
3
  import { CodexNativeStateUnavailable } from '../../chunk-LOO5CB5M.js';
4
4
  import { fetchProviderModels } from '../../chunk-GURXUF2J.js';
5
5
  import { classifyGenericErrorMessage } from '../../chunk-GAH4YRCI.js';
6
- import { BUILTIN_DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-J7VSUGGH.js';
6
+ import { BUILTIN_DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-6FZCQT3V.js';
7
7
  import '../../chunk-6E6PKKAD.js';
8
8
  import '../../chunk-FTG7CRFD.js';
9
9
  import '../../chunk-W4IPN3DD.js';
10
10
  import '../../chunk-NSBPE2FW.js';
11
11
  import { join, dirname, isAbsolute, relative } from 'path';
12
+ import { isDeepStrictEqual } from 'util';
12
13
  import { existsSync, readFileSync, mkdirSync, writeFileSync, realpathSync, statSync } from 'fs';
13
14
  import { randomUUID } from 'crypto';
14
15
  import * as z from 'zod';
@@ -54,8 +55,8 @@ function codexPromptInput(input, cwd, skills) {
54
55
  // bridge/src/codex/native-approvals.ts
55
56
  function createCodexNativeApprovalHandlers(options) {
56
57
  const active = (signal, threadId) => !signal.aborted && isNativeApprovalPolicyActive(options.getPolicy(), threadId);
57
- const text = (value) => typeof value === "string" && value.length > 0 && value.length <= 8192;
58
- const scoped = async (path, access, signal, threadId) => active(signal, threadId) && text(path) && allowsNativeApprovalPath(options.getPolicy(), path, access) && active(signal, threadId);
58
+ const text2 = (value) => typeof value === "string" && value.length > 0 && value.length <= 8192;
59
+ const scoped = async (path, access, signal, threadId) => active(signal, threadId) && text2(path) && allowsNativeApprovalPath(options.getPolicy(), path, access) && active(signal, threadId);
59
60
  const permissions = async (value, signal, threadId) => {
60
61
  if (value.network?.enabled || value.network != null && Object.keys(value.network).some((key) => key !== "enabled") || Object.keys(value).some((key) => !["network", "fileSystem"].includes(key)))
61
62
  return false;
@@ -83,7 +84,7 @@ function createCodexNativeApprovalHandlers(options) {
83
84
  return {
84
85
  "item/commandExecution/requestApproval": async (input, signal) => {
85
86
  const params = structuredClone(input);
86
- const allowed = async () => active(signal, params.threadId) && text(params.command) && (params.kind == null || params.kind === "command") && !params.environmentId && !params.networkApprovalContext && (params.availableDecisions == null || params.availableDecisions.includes("accept")) && await scoped(params.cwd, "read", signal, params.threadId) && (!params.additionalPermissions || await permissions(params.additionalPermissions, signal, params.threadId));
87
+ const allowed = async () => active(signal, params.threadId) && text2(params.command) && (params.kind == null || params.kind === "command") && !params.environmentId && !params.networkApprovalContext && (params.availableDecisions == null || params.availableDecisions.includes("accept")) && await scoped(params.cwd, "read", signal, params.threadId) && (!params.additionalPermissions || await permissions(params.additionalPermissions, signal, params.threadId));
87
88
  if (!await allowed()) return { decision: "decline" };
88
89
  const details = [`Command: ${params.command}`, `Directory: ${params.cwd}`];
89
90
  for (const access of ["read", "write"])
@@ -105,7 +106,7 @@ function createCodexNativeApprovalHandlers(options) {
105
106
  if (params.grantRoot != null && !await scoped(params.grantRoot, "write", signal, params.threadId))
106
107
  return false;
107
108
  for (const change of changes) {
108
- if (!text(change.diff) || !await scoped(change.path, "write", signal, params.threadId))
109
+ if (!text2(change.diff) || !await scoped(change.path, "write", signal, params.threadId))
109
110
  return false;
110
111
  if (!["add", "delete", "update"].includes(change.kind.type)) return false;
111
112
  if (change.kind.type === "update" && change.kind.move_path != null && !await scoped(change.kind.move_path, "write", signal, params.threadId))
@@ -138,6 +139,48 @@ function createCodexNativeApprovalHandlers(options) {
138
139
  }
139
140
  };
140
141
  }
142
+
143
+ // bridge/src/codex/native-mcp-approval.ts
144
+ var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
145
+ var text = (value) => typeof value === "string" && value.length > 0 && Buffer.byteLength(value) <= 8192;
146
+ function createCodexMcpApprovalHandler(options) {
147
+ return async (input, signal) => {
148
+ const decline = { action: "decline", content: null, _meta: null };
149
+ try {
150
+ const params = structuredClone(input);
151
+ const active = () => !signal.aborted && options.bindingActive() && isNativeApprovalPolicyActive(options.getPolicy(), params.threadId);
152
+ if (!active() || !text(options.serverName) || params.serverName !== options.serverName || !text(params.threadId) || !text(params.turnId) || params.mode !== "form" || !text(params.message) || Object.keys(params).some(
153
+ (key) => ![
154
+ "threadId",
155
+ "turnId",
156
+ "serverName",
157
+ "mode",
158
+ "message",
159
+ "requestedSchema",
160
+ "_meta"
161
+ ].includes(key)
162
+ ) || !record(params._meta) || params._meta.codex_approval_kind !== "mcp_tool_call" || !record(params.requestedSchema) || params.requestedSchema.type !== "object" || !record(params.requestedSchema.properties) || Object.keys(params.requestedSchema.properties).length !== 0 || Object.keys(params.requestedSchema).some(
163
+ (key) => !["type", "properties", "required"].includes(key)
164
+ ) || params.requestedSchema.required !== void 0 && (!Array.isArray(params.requestedSchema.required) || params.requestedSchema.required.length !== 0) || Buffer.byteLength(JSON.stringify(params._meta)) > 65536)
165
+ return decline;
166
+ const accepted = await options.questions.requestApproval(
167
+ void 0,
168
+ {
169
+ kind: "mcp",
170
+ details: [
171
+ `Configured MCP server: ${options.serverName}`,
172
+ params.message,
173
+ "This is native request presentation, not an independently verified tool identity. Tool permissions are checked again when dispatched."
174
+ ]
175
+ },
176
+ signal
177
+ );
178
+ return accepted && active() ? { action: "accept", content: null, _meta: null } : decline;
179
+ } catch {
180
+ return decline;
181
+ }
182
+ };
183
+ }
141
184
  var CodexQuestions = class {
142
185
  constructor(emit) {
143
186
  this.emit = emit;
@@ -145,7 +188,7 @@ var CodexQuestions = class {
145
188
  emit;
146
189
  pending;
147
190
  request = async (params, signal) => this.park(params, signal);
148
- /** Park one explicit native consent request in the same slot as ordinary questions. */
191
+ /** Park native consent; MCP uses only local correlation because it supplies no native item ID. */
149
192
  async requestApproval(identity, approval, signal) {
150
193
  const result = await this.park(
151
194
  {
@@ -155,7 +198,7 @@ var CodexQuestions = class {
155
198
  {
156
199
  id: "native-approval",
157
200
  header: "Approval",
158
- question: approval.kind === "permissions" ? "Allow these permissions for the current turn?" : "Allow this native action once?",
201
+ question: approval.kind === "permissions" ? "Allow these permissions for the current turn?" : approval.kind === "mcp" ? "Allow this native MCP request once?" : "Allow this native action once?",
159
202
  options: [
160
203
  {
161
204
  label: "Approve once",
@@ -175,7 +218,10 @@ var CodexQuestions = class {
175
218
  signal.throwIfAborted();
176
219
  if (this.pending || !params.isBlocking || !Array.isArray(params.questions) || params.questions.length === 0 || params.questions.length > 16 || params.questions.some((q) => !q.id || !q.question || q.isSecret) || new Set(params.questions.map((q) => q.id)).size !== params.questions.length || new Set(params.questions.map((q) => q.question)).size !== params.questions.length)
177
220
  throw new Error("CODEX_INPUT_UNSUPPORTED");
221
+ params = structuredClone(params);
222
+ approval = approval ? structuredClone(approval) : void 0;
178
223
  const id = randomUUID();
224
+ const eventId = params.itemId ?? `local-consent:${id}`;
179
225
  return new Promise((resolve, reject) => {
180
226
  const abort = () => finish();
181
227
  const finish = (result) => {
@@ -194,8 +240,8 @@ var CodexQuestions = class {
194
240
  };
195
241
  const input = {
196
242
  requestId: id,
197
- questions: params.questions,
198
- ...approval ? { approval } : {}
243
+ questions: structuredClone(params.questions),
244
+ ...approval ? { approval: structuredClone(approval) } : {}
199
245
  };
200
246
  signal.addEventListener("abort", abort, { once: true });
201
247
  if (signal.aborted) {
@@ -210,17 +256,18 @@ var CodexQuestions = class {
210
256
  {
211
257
  type: "tool_use",
212
258
  name: "AskUserQuestion",
213
- id: params.itemId,
259
+ id: eventId,
214
260
  input
215
261
  }
216
262
  ]
217
263
  }
218
264
  });
265
+ if (this.pending?.id !== id || signal.aborted) return;
219
266
  this.emit({
220
267
  type: "tool_call",
221
268
  name: "AskUserQuestion",
222
269
  tool: { name: "AskUserQuestion" },
223
- toolCallId: params.itemId,
270
+ toolCallId: eventId,
224
271
  input
225
272
  });
226
273
  });
@@ -243,7 +290,7 @@ var CodexQuestions = class {
243
290
  };
244
291
 
245
292
  // bridge/src/codex/managed-driver.ts
246
- var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
293
+ var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
247
294
  var failure = (code = "CODEX_RUNTIME_UNSUPPORTED") => new Error(code);
248
295
  var nativeUsage = (value) => ({
249
296
  ...typeof value.inputTokens === "number" ? { inputTokens: value.inputTokens } : {},
@@ -415,6 +462,7 @@ var ManagedCodexDriver = class extends AgentDriver {
415
462
  });
416
463
  this.instance = prepareCodexInstance(this.config, options, this.credential);
417
464
  const generation = ++this.generation;
465
+ const mcpReplies = /* @__PURE__ */ new WeakMap();
418
466
  this.controller = new AbortController();
419
467
  this.startupRefreshUsed = false;
420
468
  this.startupAuthAttempted = false;
@@ -475,6 +523,10 @@ var ManagedCodexDriver = class extends AgentDriver {
475
523
  requestTimeoutMs: timeout,
476
524
  serverRequestTimeoutMs: Math.min(limit(options.interactionTimeoutMs, 3e5), 3e5),
477
525
  onServerRequest: handlers,
526
+ canReplyToServerRequest: (method, params) => {
527
+ if (method !== "mcpServer/elicitation/request") return true;
528
+ return record2(params) && (mcpReplies.get(params)?.() ?? false);
529
+ },
478
530
  onNotification: (method, params) => {
479
531
  if (generation === this.generation) this.notification(method, params);
480
532
  },
@@ -510,7 +562,7 @@ var ManagedCodexDriver = class extends AgentDriver {
510
562
  } catch {
511
563
  throw failure("CODEX_REQUIRED_TOOL_UNAVAILABLE");
512
564
  }
513
- if (!this.tools || !record(this.tools.mcpServers) || typeof this.tools.dispose !== "function" || Object.keys(this.tools.mcpServers).length === 0 && Object.keys(this.tools.onServerRequest ?? {}).length === 0)
565
+ if (!this.tools || !record2(this.tools.mcpServers) || typeof this.tools.dispose !== "function" || Object.keys(this.tools.mcpServers).length === 0 && Object.keys(this.tools.onServerRequest ?? {}).length === 0)
514
566
  throw failure("CODEX_REQUIRED_TOOL_UNAVAILABLE");
515
567
  if (this.tools.onServerRequest?.["item/tool/requestUserInput"])
516
568
  throw failure("AI_PROFILE_INVALID");
@@ -525,21 +577,40 @@ var ManagedCodexDriver = class extends AgentDriver {
525
577
  return snapshot ? JSON.parse(snapshot) : void 0;
526
578
  }
527
579
  });
580
+ const approvalTools = this.tools;
581
+ const approvalServerName = approvalTools.approvalServerName;
582
+ const approvalServer = approvalServerName ? approvalTools.mcpServers[approvalServerName] : void 0;
583
+ const approvalServerSnapshot = structuredClone(approvalServer);
584
+ const mcpBindingActive = () => this.tools === approvalTools && approvalTools.approvalServerName === approvalServerName && Boolean(approvalServerName) && Object.hasOwn(approvalTools.mcpServers, approvalServerName) && record2(approvalServer) && approvalTools.mcpServers[approvalServerName] === approvalServer && isDeepStrictEqual(approvalServer, approvalServerSnapshot);
585
+ const mcpPolicy = () => tuning.approvalPolicy === "never" ? void 0 : this.nativeApprovalPolicy;
586
+ const mcpApproval = createCodexMcpApprovalHandler({
587
+ serverName: approvalServerName,
588
+ questions: this.questions,
589
+ getPolicy: mcpPolicy,
590
+ bindingActive: mcpBindingActive
591
+ });
528
592
  for (const [method, handler] of Object.entries({
529
593
  ...this.tools.onServerRequest,
530
594
  ...nativeApprovals,
531
- "item/tool/requestUserInput": this.questions.request
595
+ "item/tool/requestUserInput": this.questions.request,
596
+ "mcpServer/elicitation/request": mcpApproval
532
597
  })) {
533
598
  if (method === "account/chatgptAuthTokens/refresh" || !handler)
534
599
  throw failure("AI_PROFILE_INVALID");
535
600
  handlers[method] = async (params, signal) => {
536
601
  const active = this.active;
537
- if (generation !== this.generation || !active || !record(params)) throw failure();
602
+ if (generation !== this.generation || !active || !record2(params)) throw failure();
538
603
  await active.ready;
539
604
  if (generation !== this.generation || this.active !== active || params.threadId !== this.threadId || params.turnId !== active.id)
540
605
  throw failure();
541
606
  const cancellation = AbortSignal.any([signal, active.controller.signal]);
542
607
  if (cancellation.aborted) throw failure();
608
+ if (method === "mcpServer/elicitation/request") {
609
+ mcpReplies.set(
610
+ params,
611
+ () => generation === this.generation && this.active === active && !cancellation.aborted && params.threadId === this.threadId && params.turnId === active.id && mcpBindingActive() && isNativeApprovalPolicyActive(mcpPolicy(), this.threadId ?? "")
612
+ );
613
+ }
543
614
  const result = await handler(params, cancellation);
544
615
  if (generation !== this.generation || cancellation.aborted || this.active !== active)
545
616
  throw failure();
@@ -571,14 +642,14 @@ var ManagedCodexDriver = class extends AgentDriver {
571
642
  ...threadParams,
572
643
  allowProviderModelFallback: false
573
644
  });
574
- if (!record(response) || response.model !== this.config.model)
645
+ if (!record2(response) || response.model !== this.config.model)
575
646
  throw failure("CODEX_MODEL_UNAVAILABLE");
576
- if (!record(response.thread) || typeof response.thread.id !== "string" || resuming && response.thread.id !== this.config.resumeSessionId || resuming && !Array.isArray(response.thread.turns) || response.reasoningEffort !== (this.config.effort ?? tuning.reasoningEffort) || response.modelProvider !== "openai" || response.approvalPolicy !== tuning.approvalPolicy)
647
+ if (!record2(response.thread) || typeof response.thread.id !== "string" || resuming && response.thread.id !== this.config.resumeSessionId || resuming && !Array.isArray(response.thread.turns) || response.reasoningEffort !== (this.config.effort ?? tuning.reasoningEffort) || response.modelProvider !== "openai" || response.approvalPolicy !== tuning.approvalPolicy)
577
648
  throw failure("AI_PROFILE_INVALID");
578
649
  if (generation !== this.generation || this.killed) throw failure();
579
650
  this.resumeUsageTurnIds = new Set(
580
651
  resuming && Array.isArray(response.thread.turns) ? response.thread.turns.flatMap(
581
- (turn) => record(turn) && typeof turn.id === "string" ? [turn.id] : []
652
+ (turn) => record2(turn) && typeof turn.id === "string" ? [turn.id] : []
582
653
  ) : []
583
654
  );
584
655
  this.nativeApprovalPolicy = activateNativeApprovalPolicy(
@@ -623,7 +694,7 @@ var ManagedCodexDriver = class extends AgentDriver {
623
694
  }
624
695
  async refresh(params, signal) {
625
696
  const credential = this.credential;
626
- if (!record(params) || params.reason !== "unauthorized" || !credential || credential.kind !== "codex-subscription" || params.previousAccountId != null && params.previousAccountId !== credential.chatgptAccountId || !this.options?.refreshCredential || (this.active ? this.active.refreshUsed : this.startupRefreshUsed))
697
+ if (!record2(params) || params.reason !== "unauthorized" || !credential || credential.kind !== "codex-subscription" || params.previousAccountId != null && params.previousAccountId !== credential.chatgptAccountId || !this.options?.refreshCredential || (this.active ? this.active.refreshUsed : this.startupRefreshUsed))
627
698
  throw failure("CODEX_AUTH_UNAVAILABLE");
628
699
  if (this.active) this.active.refreshUsed = true;
629
700
  else this.startupRefreshUsed = true;
@@ -741,7 +812,7 @@ var ManagedCodexDriver = class extends AgentDriver {
741
812
  effort: this.config.effort ?? this.config.driverOptions.codex.reasoningEffort
742
813
  });
743
814
  if (this.active !== active) return;
744
- if (!record(response.turn) || typeof response.turn.id !== "string") throw failure();
815
+ if (!record2(response.turn) || typeof response.turn.id !== "string") throw failure();
745
816
  active.id = response.turn.id;
746
817
  active.readyNow();
747
818
  for (const event of active.events.splice(0)) this.notification(event.method, event.params);
@@ -812,7 +883,8 @@ var ManagedCodexDriver = class extends AgentDriver {
812
883
  this.pendingPatch = { ...this.pendingPatch, ...patch };
813
884
  }
814
885
  closeGeneration() {
815
- ++this.generation;
886
+ const generation = ++this.generation;
887
+ const finalMcp = { ...this.mcpDiagnostics };
816
888
  this.mcpStartup = "unknown";
817
889
  this.pendingMcpStartup = void 0;
818
890
  this.controller.abort();
@@ -835,14 +907,19 @@ var ManagedCodexDriver = class extends AgentDriver {
835
907
  if (pendingClient && pendingClient !== client) await pendingClient.dispose();
836
908
  if (client && !client.terminationConfirmed || pendingClient && !pendingClient.terminationConfirmed)
837
909
  this.cleanupUncertain = true;
838
- if (tools)
839
- await bounded(
840
- Promise.resolve().then(() => tools.dispose()),
841
- new AbortController().signal,
842
- 1e3
843
- ).catch(() => {
910
+ if (tools) {
911
+ try {
912
+ await bounded(
913
+ Promise.resolve().then(() => tools.dispose()),
914
+ new AbortController().signal,
915
+ 1e3
916
+ );
917
+ if (generation === this.generation && !this.cleanupUncertain)
918
+ this.observeClosedMcp(tools, finalMcp);
919
+ } catch {
844
920
  this.cleanupUncertain = true;
845
- });
921
+ }
922
+ }
846
923
  } finally {
847
924
  instance?.release();
848
925
  }
@@ -852,7 +929,7 @@ var ManagedCodexDriver = class extends AgentDriver {
852
929
  return this.closing;
853
930
  }
854
931
  notification(method, params) {
855
- if (!record(params)) return;
932
+ if (!record2(params)) return;
856
933
  if (method === "mcpServer/startupStatus/updated") {
857
934
  const serverName = this.tools?.diagnostics?.serverName;
858
935
  if (!serverName || params.name !== serverName || typeof params.threadId !== "string" || params.threadId.length > 512 || typeof params.status !== "string" || !["starting", "ready", "failed", "cancelled"].includes(params.status))
@@ -869,7 +946,7 @@ var ManagedCodexDriver = class extends AgentDriver {
869
946
  return;
870
947
  }
871
948
  const active = this.active;
872
- if ((!active || !active.usageCursor && this.resumeUsageTurnIds.has(String(params.turnId))) && method === "thread/tokenUsage/updated" && params.threadId === (this.threadId ?? this.config.resumeSessionId) && record(params.tokenUsage) && record(params.tokenUsage.total)) {
949
+ if ((!active || !active.usageCursor && this.resumeUsageTurnIds.has(String(params.turnId))) && method === "thread/tokenUsage/updated" && params.threadId === (this.threadId ?? this.config.resumeSessionId) && record2(params.tokenUsage) && record2(params.tokenUsage.total)) {
873
950
  this.threadUsageTotal = nativeUsage(params.tokenUsage.total);
874
951
  if (active) active.usageBaseline = this.threadUsageTotal;
875
952
  return;
@@ -883,12 +960,12 @@ var ManagedCodexDriver = class extends AgentDriver {
883
960
  } else active.events.push({ method, params });
884
961
  return;
885
962
  }
886
- const turnId = record(params.turn) ? params.turn.id : params.turnId;
963
+ const turnId = record2(params.turn) ? params.turn.id : params.turnId;
887
964
  if (turnId !== active.id) return;
888
- if (method === "thread/tokenUsage/updated" && record(params.tokenUsage)) {
965
+ if (method === "thread/tokenUsage/updated" && record2(params.tokenUsage)) {
889
966
  const last = params.tokenUsage.last;
890
967
  const total = params.tokenUsage.total;
891
- const cumulativeUsage = record(total) ? nativeUsage(total) : void 0;
968
+ const cumulativeUsage = record2(total) ? nativeUsage(total) : void 0;
892
969
  if (cumulativeUsage) {
893
970
  active.usageBaseline ??= {};
894
971
  this.resumeUsageTurnIds.clear();
@@ -900,7 +977,7 @@ var ManagedCodexDriver = class extends AgentDriver {
900
977
  active.usageCursor = cumulativeUsage;
901
978
  this.threadUsageTotal = cumulativeUsage;
902
979
  }
903
- if (record(last)) {
980
+ if (record2(last)) {
904
981
  if (typeof last.totalTokens === "number") active.contextTokens = last.totalTokens;
905
982
  }
906
983
  if (typeof params.tokenUsage.modelContextWindow === "number")
@@ -908,7 +985,7 @@ var ManagedCodexDriver = class extends AgentDriver {
908
985
  } else if (method === "model/rerouted") {
909
986
  active.actualModel = typeof params.toModel === "string" ? params.toModel : active.actualModel;
910
987
  active.failureCode = "CODEX_MODEL_UNAVAILABLE";
911
- } else if (method === "turn/completed" && record(params.turn)) this.complete(params.turn);
988
+ } else if (method === "turn/completed" && record2(params.turn)) this.complete(params.turn);
912
989
  else if (method === "error" && params.willRetry !== true)
913
990
  active.failureCode = this.nativeErrorCode(params.error);
914
991
  else if (method === "item/agentMessage/delta" && typeof params.itemId === "string" && typeof params.delta === "string") {
@@ -918,14 +995,14 @@ var ManagedCodexDriver = class extends AgentDriver {
918
995
  type: "message_start",
919
996
  message: { role: "assistant", content: [{ type: "text", text: "" }] }
920
997
  });
921
- const text = (previous ?? "") + params.delta;
922
- active.messages.set(params.itemId, text);
998
+ const text2 = (previous ?? "") + params.delta;
999
+ active.messages.set(params.itemId, text2);
923
1000
  this.event({
924
1001
  type: "message_update",
925
- message: { role: "assistant", content: [{ type: "text", text }] },
1002
+ message: { role: "assistant", content: [{ type: "text", text: text2 }] },
926
1003
  _textDelta: params.delta
927
1004
  });
928
- } else if ((method === "item/started" || method === "item/completed") && record(params.item) && typeof params.item.id === "string") {
1005
+ } else if ((method === "item/started" || method === "item/completed") && record2(params.item) && typeof params.item.id === "string") {
929
1006
  this.item(
930
1007
  params.item,
931
1008
  method === "item/completed"
@@ -1009,11 +1086,11 @@ var ManagedCodexDriver = class extends AgentDriver {
1009
1086
  this.finishTurn(this.active?.failureCode ?? this.nativeErrorCode(turn.error));
1010
1087
  }
1011
1088
  nativeErrorCode(error) {
1012
- const info = record(error) ? error.codexErrorInfo : void 0;
1089
+ const info = record2(error) ? error.codexErrorInfo : void 0;
1013
1090
  if (info === "unauthorized") return "CODEX_RECONNECT_REQUIRED";
1014
1091
  if (info === "usageLimitExceeded" || info === "rateLimitExceeded" || info === "serverOverloaded")
1015
1092
  return "CODEX_RATE_LIMITED";
1016
- if (record(info) && [
1093
+ if (record2(info) && [
1017
1094
  "httpConnectionFailed",
1018
1095
  "responseStreamConnectionFailed",
1019
1096
  "responseStreamDisconnected",
@@ -1039,9 +1116,31 @@ var ManagedCodexDriver = class extends AgentDriver {
1039
1116
  this.mcpDiagnostics.startupAtEnd = this.mcpStartup;
1040
1117
  this.mcpDiagnostics.toolsListTotal = Math.max(this.mcpDiagnostics.toolsListBeforeTurn, listed);
1041
1118
  this.mcpDiagnostics.toolsCallTotal = beforeTurn ? called : Math.max(this.mcpDiagnostics.toolsCallTotal, called);
1119
+ this.publishMcp(this.mcpDiagnostics);
1120
+ }
1121
+ observeClosedMcp(tools, snapshot) {
1122
+ try {
1123
+ const counts = tools.diagnostics?.requestCounts();
1124
+ if (!counts || ![counts.toolsListTotal, counts.toolsCallTotal].every(
1125
+ (value) => Number.isSafeInteger(value) && value >= 0
1126
+ ))
1127
+ return;
1128
+ snapshot.toolsListTotal = Math.max(
1129
+ snapshot.toolsListTotal,
1130
+ Math.min(512, counts.toolsListTotal)
1131
+ );
1132
+ snapshot.toolsCallTotal = Math.max(
1133
+ snapshot.toolsCallTotal,
1134
+ Math.min(512, counts.toolsCallTotal)
1135
+ );
1136
+ this.publishMcp(snapshot);
1137
+ } catch {
1138
+ }
1139
+ }
1140
+ publishMcp(snapshot) {
1042
1141
  try {
1043
1142
  void Promise.resolve(
1044
- this.options?.onNativeMcpDiagnostics?.(Object.freeze({ ...this.mcpDiagnostics }))
1143
+ this.options?.onNativeMcpDiagnostics?.(Object.freeze({ ...snapshot }))
1045
1144
  ).catch(() => {
1046
1145
  });
1047
1146
  } catch {
@@ -1056,10 +1155,10 @@ var ManagedCodexDriver = class extends AgentDriver {
1056
1155
  active.controller.abort();
1057
1156
  active.fileChanges.clear();
1058
1157
  active.readyNow();
1059
- for (const text of active.messages.values())
1158
+ for (const text2 of active.messages.values())
1060
1159
  this.event({
1061
1160
  type: "message_end",
1062
- message: { role: "assistant", content: [{ type: "text", text }] }
1161
+ message: { role: "assistant", content: [{ type: "text", text: text2 }] }
1063
1162
  });
1064
1163
  this.event({ type: "turn_end", toolResults: active.toolResults });
1065
1164
  const modelUsage = active.usage ? {
@@ -1546,10 +1645,10 @@ var CodexDriver = class extends AgentDriver {
1546
1645
  });
1547
1646
  this.pendingToolResults = [];
1548
1647
  }
1549
- buildAssistantMessage(text) {
1648
+ buildAssistantMessage(text2) {
1550
1649
  return {
1551
1650
  role: "assistant",
1552
- content: [{ type: "text", text }]
1651
+ content: [{ type: "text", text: text2 }]
1553
1652
  };
1554
1653
  }
1555
1654
  toObject(value) {