@skaile/workspaces 3.17.0 → 3.18.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 (271) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-FQT6GH24.js → asset-feeds-LT4GI576.js} +7 -7
  4. package/dist/{asset-feeds-FQT6GH24.js.map → asset-feeds-LT4GI576.js.map} +1 -1
  5. package/dist/asset-manager/catalog-deployer.js +3 -3
  6. package/dist/asset-manager/index.js +6 -6
  7. package/dist/asset-manager/installer.js +4 -4
  8. package/dist/bridge/codex-app-server.js +2 -203
  9. package/dist/bridge/codex-app-server.js.map +1 -1
  10. package/dist/bridge/drivers/claude-sdk.js +5 -5
  11. package/dist/bridge/drivers/codex.js +1137 -4
  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 +2 -2
  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 +7 -6
  21. package/dist/bridge/src/capability-dispatch.d.ts +1 -1
  22. package/dist/bridge/src/capability-dispatch.d.ts.map +1 -1
  23. package/dist/bridge/src/codex/credentials.d.ts +12 -0
  24. package/dist/bridge/src/codex/credentials.d.ts.map +1 -0
  25. package/dist/bridge/src/codex/inputs.d.ts +8 -0
  26. package/dist/bridge/src/codex/inputs.d.ts.map +1 -0
  27. package/dist/bridge/src/codex/instance-state.d.ts +16 -0
  28. package/dist/bridge/src/codex/instance-state.d.ts.map +1 -0
  29. package/dist/bridge/src/codex/managed-driver.d.ts +71 -0
  30. package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -0
  31. package/dist/bridge/src/codex/native-approvals.d.ts +22 -0
  32. package/dist/bridge/src/codex/native-approvals.d.ts.map +1 -0
  33. package/dist/bridge/src/codex/native-policy.d.ts +38 -0
  34. package/dist/bridge/src/codex/native-policy.d.ts.map +1 -0
  35. package/dist/bridge/src/codex/native-protocol.generated.d.ts +286 -200
  36. package/dist/bridge/src/codex/native-protocol.generated.d.ts.map +1 -1
  37. package/dist/bridge/src/codex/native-state.d.ts +7 -0
  38. package/dist/bridge/src/codex/native-state.d.ts.map +1 -0
  39. package/dist/bridge/src/codex/questions.d.ts +19 -0
  40. package/dist/bridge/src/codex/questions.d.ts.map +1 -0
  41. package/dist/bridge/src/codex-app-server.d.ts +6 -1
  42. package/dist/bridge/src/codex-app-server.d.ts.map +1 -1
  43. package/dist/bridge/src/drivers/codex.d.ts +9 -1
  44. package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
  45. package/dist/bridge/src/index.d.ts +1 -0
  46. package/dist/bridge/src/index.d.ts.map +1 -1
  47. package/dist/bridge/src/normalizer.d.ts.map +1 -1
  48. package/dist/bridge/src/runtime.d.ts +3 -2
  49. package/dist/bridge/src/runtime.d.ts.map +1 -1
  50. package/dist/bridge/src/types.d.ts +77 -4
  51. package/dist/bridge/src/types.d.ts.map +1 -1
  52. package/dist/{chunk-BCOGOM6F.js → chunk-23L3P7IB.js} +4 -4
  53. package/dist/{chunk-BCOGOM6F.js.map → chunk-23L3P7IB.js.map} +1 -1
  54. package/dist/{chunk-NC5YXVZF.js → chunk-2FDKUKDE.js} +3 -3
  55. package/dist/{chunk-NC5YXVZF.js.map → chunk-2FDKUKDE.js.map} +1 -1
  56. package/dist/{chunk-2XGFQKNJ.js → chunk-2IROGAS7.js} +2 -2
  57. package/dist/{chunk-2XGFQKNJ.js.map → chunk-2IROGAS7.js.map} +1 -1
  58. package/dist/{chunk-BUKPS4YL.js → chunk-4JDCKPTM.js} +2 -2
  59. package/dist/{chunk-BUKPS4YL.js.map → chunk-4JDCKPTM.js.map} +1 -1
  60. package/dist/{chunk-5KSIVLOX.js → chunk-5T7Y3AZU.js} +3 -3
  61. package/dist/{chunk-5KSIVLOX.js.map → chunk-5T7Y3AZU.js.map} +1 -1
  62. package/dist/{chunk-SWUVULBU.js → chunk-67KB2A77.js} +7 -7
  63. package/dist/{chunk-SWUVULBU.js.map → chunk-67KB2A77.js.map} +1 -1
  64. package/dist/{chunk-RRVQAE5D.js → chunk-7ZO3MUP3.js} +6 -5
  65. package/dist/chunk-7ZO3MUP3.js.map +1 -0
  66. package/dist/{chunk-EO7IJY3Q.js → chunk-AI2PZX4H.js} +3 -3
  67. package/dist/{chunk-EO7IJY3Q.js.map → chunk-AI2PZX4H.js.map} +1 -1
  68. package/dist/{chunk-CMGYUF5P.js → chunk-BJI7IGZF.js} +7 -7
  69. package/dist/{chunk-CMGYUF5P.js.map → chunk-BJI7IGZF.js.map} +1 -1
  70. package/dist/{chunk-HY6CIKFH.js → chunk-CP62G5PK.js} +8 -7
  71. package/dist/chunk-CP62G5PK.js.map +1 -0
  72. package/dist/{chunk-PBRMY64S.js → chunk-CQY7XKRV.js} +30 -9
  73. package/dist/chunk-CQY7XKRV.js.map +1 -0
  74. package/dist/{chunk-OIDFK7SG.js → chunk-DCG4UWJM.js} +3 -3
  75. package/dist/{chunk-OIDFK7SG.js.map → chunk-DCG4UWJM.js.map} +1 -1
  76. package/dist/{chunk-VT4MPCRK.js → chunk-FBD5SOIH.js} +3 -3
  77. package/dist/{chunk-VT4MPCRK.js.map → chunk-FBD5SOIH.js.map} +1 -1
  78. package/dist/{chunk-HEKLK4NG.js → chunk-FYVDBIZV.js} +6 -6
  79. package/dist/{chunk-HEKLK4NG.js.map → chunk-FYVDBIZV.js.map} +1 -1
  80. package/dist/{chunk-RTM4SFLA.js → chunk-GMKNGIIB.js} +7 -4
  81. package/dist/chunk-GMKNGIIB.js.map +1 -0
  82. package/dist/{chunk-NIQPSQFN.js → chunk-GMMACS5W.js} +4 -4
  83. package/dist/{chunk-NIQPSQFN.js.map → chunk-GMMACS5W.js.map} +1 -1
  84. package/dist/{chunk-QFYEDM63.js → chunk-GRA4BWCV.js} +5 -5
  85. package/dist/{chunk-QFYEDM63.js.map → chunk-GRA4BWCV.js.map} +1 -1
  86. package/dist/{chunk-CIPK5JMJ.js → chunk-H662SXKS.js} +4 -4
  87. package/dist/{chunk-CIPK5JMJ.js.map → chunk-H662SXKS.js.map} +1 -1
  88. package/dist/{chunk-NMAICJUA.js → chunk-IST2V7RU.js} +3 -3
  89. package/dist/{chunk-NMAICJUA.js.map → chunk-IST2V7RU.js.map} +1 -1
  90. package/dist/{chunk-PYX4WZLJ.js → chunk-IT42ZT3T.js} +9 -9
  91. package/dist/{chunk-PYX4WZLJ.js.map → chunk-IT42ZT3T.js.map} +1 -1
  92. package/dist/{chunk-FRER2PEN.js → chunk-J7VSUGGH.js} +16 -3
  93. package/dist/chunk-J7VSUGGH.js.map +1 -0
  94. package/dist/{chunk-ZNCZ7RUO.js → chunk-JVFZ5R7L.js} +3 -3
  95. package/dist/{chunk-ZNCZ7RUO.js.map → chunk-JVFZ5R7L.js.map} +1 -1
  96. package/dist/chunk-LOO5CB5M.js +12 -0
  97. package/dist/chunk-LOO5CB5M.js.map +1 -0
  98. package/dist/{chunk-AL6BU3SP.js → chunk-OJ4N4T4H.js} +12 -4
  99. package/dist/chunk-OJ4N4T4H.js.map +1 -0
  100. package/dist/chunk-QEZPFJX3.js +254 -0
  101. package/dist/chunk-QEZPFJX3.js.map +1 -0
  102. package/dist/{chunk-C4AP3XZB.js → chunk-QG2ZXU5W.js} +4 -4
  103. package/dist/{chunk-C4AP3XZB.js.map → chunk-QG2ZXU5W.js.map} +1 -1
  104. package/dist/{chunk-KCI7DAKE.js → chunk-RJOGAEIY.js} +987 -238
  105. package/dist/chunk-RJOGAEIY.js.map +1 -0
  106. package/dist/{chunk-OZ7UNMTK.js → chunk-RPVTPVGX.js} +7 -5
  107. package/dist/chunk-RPVTPVGX.js.map +1 -0
  108. package/dist/{chunk-S4UA244H.js → chunk-S635WMXH.js} +4 -4
  109. package/dist/{chunk-S4UA244H.js.map → chunk-S635WMXH.js.map} +1 -1
  110. package/dist/{chunk-BQMRUH7J.js → chunk-SFCVAEJ5.js} +4 -4
  111. package/dist/{chunk-BQMRUH7J.js.map → chunk-SFCVAEJ5.js.map} +1 -1
  112. package/dist/{chunk-EXT2LNST.js → chunk-SH7GXS7V.js} +125 -37
  113. package/dist/chunk-SH7GXS7V.js.map +1 -0
  114. package/dist/chunk-T3YLZQS4.js +336 -0
  115. package/dist/chunk-T3YLZQS4.js.map +1 -0
  116. package/dist/{chunk-X7FJ3ES3.js → chunk-X3LUB275.js} +4 -4
  117. package/dist/{chunk-X7FJ3ES3.js.map → chunk-X3LUB275.js.map} +1 -1
  118. package/dist/chunk-XKSGEYZC.js +244 -0
  119. package/dist/chunk-XKSGEYZC.js.map +1 -0
  120. package/dist/{chunk-SUPIVTLX.js → chunk-XL45U3C5.js} +3 -3
  121. package/dist/{chunk-SUPIVTLX.js.map → chunk-XL45U3C5.js.map} +1 -1
  122. package/dist/{chunk-AXEOG4B5.js → chunk-YCMHWNZA.js} +3 -3
  123. package/dist/{chunk-AXEOG4B5.js.map → chunk-YCMHWNZA.js.map} +1 -1
  124. package/dist/cli/index.js +75 -53
  125. package/dist/cli/index.js.map +1 -1
  126. package/dist/cli/src/commands/serve.d.ts.map +1 -1
  127. package/dist/client/index.js +1 -1
  128. package/dist/client/src/client.d.ts +3 -2
  129. package/dist/client/src/client.d.ts.map +1 -1
  130. package/dist/connectors/config.js +4 -4
  131. package/dist/connectors/index.js +12 -11
  132. package/dist/connectors/src/connector-prompt.d.ts +11 -0
  133. package/dist/connectors/src/connector-prompt.d.ts.map +1 -1
  134. package/dist/core/index.js +3 -3
  135. package/dist/core/runtime-assets.js +2 -2
  136. package/dist/core/src/workspace-config.d.ts.map +1 -1
  137. package/dist/core/workspace-config.js +1 -1
  138. package/dist/deploy/index.js +3 -3
  139. package/dist/{ensure-sources-4GBXK6UR.js → ensure-sources-4BQ6GMYG.js} +9 -9
  140. package/dist/{ensure-sources-4GBXK6UR.js.map → ensure-sources-4BQ6GMYG.js.map} +1 -1
  141. package/dist/factory-assets/connectors/box.js +12 -11
  142. package/dist/factory-assets/connectors/deploy.js +12 -11
  143. package/dist/factory-assets/connectors/devserver.js +12 -11
  144. package/dist/factory-assets/connectors/flow/CONNECTOR.md +4 -5
  145. package/dist/factory-assets/connectors/flow/adapter.d.ts +8 -0
  146. package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
  147. package/dist/factory-assets/connectors/flow/adapter.js +12 -11
  148. package/dist/factory-assets/connectors/flow/contract/index.d.ts +1 -1
  149. package/dist/factory-assets/connectors/flow/contract/index.d.ts.map +1 -1
  150. package/dist/factory-assets/connectors/flow/contract/schema.d.ts +50 -17
  151. package/dist/factory-assets/connectors/flow/contract/schema.d.ts.map +1 -1
  152. package/dist/factory-assets/connectors/flow/contract.js +3 -3
  153. package/dist/factory-assets/connectors/flow/engine/index.d.ts +1 -0
  154. package/dist/factory-assets/connectors/flow/engine/index.d.ts.map +1 -1
  155. package/dist/factory-assets/connectors/flow/engine.js +5 -5
  156. package/dist/factory-assets/connectors/flow/run-flow.js +13 -12
  157. package/dist/factory-assets/connectors/flow/subprompt-runner.d.ts +10 -1
  158. package/dist/factory-assets/connectors/flow/subprompt-runner.d.ts.map +1 -1
  159. package/dist/factory-assets/connectors/flow.js +12 -11
  160. package/dist/factory-assets/connectors/git.js +12 -11
  161. package/dist/factory-assets/connectors/gmail.js +12 -11
  162. package/dist/factory-assets/connectors/googledrive.js +12 -11
  163. package/dist/factory-assets/connectors/local.js +12 -11
  164. package/dist/factory-assets/connectors/mattermost.js +12 -11
  165. package/dist/factory-assets/connectors/memory.js +12 -11
  166. package/dist/factory-assets/connectors/minio.js +12 -11
  167. package/dist/factory-assets/connectors/postgres.js +12 -11
  168. package/dist/factory-assets/connectors/s3.js +12 -11
  169. package/dist/factory-assets/connectors/sharepoint.js +12 -11
  170. package/dist/factory-assets/connectors/sqlite.js +12 -11
  171. package/dist/factory-assets/connectors/static-server.js +12 -11
  172. package/dist/factory-assets/connectors/tunnel.js +12 -11
  173. package/dist/factory-assets/connectors/webdav.js +12 -11
  174. package/dist/factory-assets/connectors/xstate-store.js +12 -11
  175. package/dist/factory-assets/connectors/xstate.js +12 -11
  176. package/dist/{flows-2SUFOVVO.js → flows-COBS26MK.js} +6 -6
  177. package/dist/{flows-2SUFOVVO.js.map → flows-COBS26MK.js.map} +1 -1
  178. package/dist/{helpers-26LW4IXY.js → helpers-4UJMSN6T.js} +9 -9
  179. package/dist/{helpers-26LW4IXY.js.map → helpers-4UJMSN6T.js.map} +1 -1
  180. package/dist/library/index.js +4 -4
  181. package/dist/library/install.js +3 -3
  182. package/dist/{library-publish-IYGHOPEK.js → library-publish-QHQDN4IC.js} +14 -14
  183. package/dist/{library-publish-IYGHOPEK.js.map → library-publish-QHQDN4IC.js.map} +1 -1
  184. package/dist/{open-library-HH5LST7Z.js → open-library-ZDM6DUKJ.js} +12 -12
  185. package/dist/{open-library-HH5LST7Z.js.map → open-library-ZDM6DUKJ.js.map} +1 -1
  186. package/dist/{paths-4APA2PKT.js → paths-CZPCCBYX.js} +6 -6
  187. package/dist/{paths-4APA2PKT.js.map → paths-CZPCCBYX.js.map} +1 -1
  188. package/dist/{plugin-store-JQAIKR3R.js → plugin-store-ZEIBSNTO.js} +5 -5
  189. package/dist/{plugin-store-JQAIKR3R.js.map → plugin-store-ZEIBSNTO.js.map} +1 -1
  190. package/dist/{project-U5QRUCBN.js → project-JJUAAI7N.js} +10 -10
  191. package/dist/{project-U5QRUCBN.js.map → project-JJUAAI7N.js.map} +1 -1
  192. package/dist/resolver/index.js +3 -3
  193. package/dist/runner/index.js +25 -16
  194. package/dist/runner/src/capability-registry.d.ts +4 -0
  195. package/dist/runner/src/capability-registry.d.ts.map +1 -1
  196. package/dist/runner/src/codex-init.d.ts +2 -11
  197. package/dist/runner/src/codex-init.d.ts.map +1 -1
  198. package/dist/runner/src/codex-resource-tools.d.ts +16 -0
  199. package/dist/runner/src/codex-resource-tools.d.ts.map +1 -0
  200. package/dist/runner/src/codex-tools.d.ts +12 -0
  201. package/dist/runner/src/codex-tools.d.ts.map +1 -0
  202. package/dist/runner/src/define-capability.d.ts +2 -0
  203. package/dist/runner/src/define-capability.d.ts.map +1 -1
  204. package/dist/runner/src/external-mcp.d.ts +8 -3
  205. package/dist/runner/src/external-mcp.d.ts.map +1 -1
  206. package/dist/runner/src/index.d.ts +2 -0
  207. package/dist/runner/src/index.d.ts.map +1 -1
  208. package/dist/runner/src/managed-codex-bootstrap.d.ts +54 -0
  209. package/dist/runner/src/managed-codex-bootstrap.d.ts.map +1 -0
  210. package/dist/runner/src/resources.d.ts +1 -0
  211. package/dist/runner/src/resources.d.ts.map +1 -1
  212. package/dist/runner/src/serve.d.ts +5 -0
  213. package/dist/runner/src/serve.d.ts.map +1 -1
  214. package/dist/runner/src/session-builder.d.ts +18 -1
  215. package/dist/runner/src/session-builder.d.ts.map +1 -1
  216. package/dist/sdk/asset-manager.js +6 -6
  217. package/dist/sdk/bridge.js +7 -6
  218. package/dist/sdk/client.js +1 -1
  219. package/dist/sdk/core.js +3 -3
  220. package/dist/sdk/flow.js +5 -5
  221. package/dist/sdk/index.js +26 -17
  222. package/dist/sdk/index.js.map +1 -1
  223. package/dist/sdk/resolver.js +3 -3
  224. package/dist/sdk/runner.js +25 -16
  225. package/dist/sdk/session.js +2 -2
  226. package/dist/sdk/store.js +1 -1
  227. package/dist/sdk/types.js +1 -1
  228. package/dist/session/index.js +2 -2
  229. package/dist/{setup-XKTBHRWM.js → setup-PS6ZERZ5.js} +9 -8
  230. package/dist/setup-PS6ZERZ5.js.map +1 -0
  231. package/dist/{skills-Q7PJVB3W.js → skills-LG6IQSSN.js} +5 -5
  232. package/dist/{skills-Q7PJVB3W.js.map → skills-LG6IQSSN.js.map} +1 -1
  233. package/dist/{source-ODR4IU6R.js → source-QLDIZCI3.js} +13 -13
  234. package/dist/{source-ODR4IU6R.js.map → source-QLDIZCI3.js.map} +1 -1
  235. package/dist/{source-manifest-publish-WCJY3GAM.js → source-manifest-publish-J3AVCTLX.js} +15 -15
  236. package/dist/{source-manifest-publish-WCJY3GAM.js.map → source-manifest-publish-J3AVCTLX.js.map} +1 -1
  237. package/dist/store/index.js +1 -1
  238. package/dist/store/react.js +1 -1
  239. package/dist/store/react.js.map +1 -1
  240. package/dist/store/src/react.d.ts +1 -1
  241. package/dist/store/src/react.d.ts.map +1 -1
  242. package/dist/store/src/store.d.ts +2 -1
  243. package/dist/store/src/store.d.ts.map +1 -1
  244. package/dist/tui/index.js +25 -16
  245. package/dist/tui/index.js.map +1 -1
  246. package/dist/types/index.js +1 -1
  247. package/dist/types/src/events.d.ts +14 -1
  248. package/dist/types/src/events.d.ts.map +1 -1
  249. package/dist/types/src/index.d.ts +2 -2
  250. package/dist/types/src/index.d.ts.map +1 -1
  251. package/dist/types/src/protocol.d.ts +18 -0
  252. package/dist/types/src/protocol.d.ts.map +1 -1
  253. package/dist/types/src/runtime.d.ts +3 -1
  254. package/dist/types/src/runtime.d.ts.map +1 -1
  255. package/dist/types/src/version.d.ts +7 -1
  256. package/dist/types/src/version.d.ts.map +1 -1
  257. package/dist/workspace-plugin/adapters/mcp.js +9 -255
  258. package/dist/workspace-plugin/adapters/mcp.js.map +1 -1
  259. package/dist/workspace-plugin/adapters/omp.js +7 -7
  260. package/dist/workspace-plugin/index.js +1 -1
  261. package/package.json +3 -1
  262. package/dist/chunk-AL6BU3SP.js.map +0 -1
  263. package/dist/chunk-EXT2LNST.js.map +0 -1
  264. package/dist/chunk-FRER2PEN.js.map +0 -1
  265. package/dist/chunk-HY6CIKFH.js.map +0 -1
  266. package/dist/chunk-KCI7DAKE.js.map +0 -1
  267. package/dist/chunk-OZ7UNMTK.js.map +0 -1
  268. package/dist/chunk-PBRMY64S.js.map +0 -1
  269. package/dist/chunk-RRVQAE5D.js.map +0 -1
  270. package/dist/chunk-RTM4SFLA.js.map +0 -1
  271. package/dist/setup-XKTBHRWM.js.map +0 -1
@@ -1,22 +1,27 @@
1
- import { WorkspacePlugin } from './chunk-2XGFQKNJ.js';
1
+ import { buildWorkspaceToolDefs } from './chunk-QEZPFJX3.js';
2
+ import { findAiAssetsRoot } from './chunk-7IRJ4K4F.js';
3
+ import { WorkspacePlugin } from './chunk-2IROGAS7.js';
2
4
  import { assembleSystemPrompt, buildCapabilitiesPromptSection } from './chunk-W3UDISS2.js';
3
5
  import { WebSocketServerTransport } from './chunk-WQ7DE5UC.js';
4
- import { resolveFlowPath } from './chunk-HEKLK4NG.js';
5
- import { findAiAssetsRoot, deployCatalogEntry, undeployCatalogEntry } from './chunk-7BUZQVRR.js';
6
- import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, ConnectorStartupError, buildSdkConnectorTools, driveOrchestratorTurn, SessionNodeExecutor, SessionSubpromptRunner, SessionInlineSubFlowRunner, buildSdkFlowTools } from './chunk-EXT2LNST.js';
7
- import { loadConnectorDeclarations, SecretProviderChain, PreMintedSecretProvider, InMemorySecretProvider, resolvedConfigToDeclarations, isKnownSecretRef, deriveSingleMaterializedConnectorDeclaration } from './chunk-5KSIVLOX.js';
8
- import { EventNormalizer } from './chunk-PBRMY64S.js';
6
+ import { prepareNativePolicy, codexInstanceEnvironment, parseCodexCredential, parseCodexRefreshInput, parseCodexRefreshResult } from './chunk-T3YLZQS4.js';
7
+ import { resolveFlowPath } from './chunk-FYVDBIZV.js';
8
+ import { findAiAssetsRoot as findAiAssetsRoot$1, deployCatalogEntry, undeployCatalogEntry } from './chunk-7BUZQVRR.js';
9
+ import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, ConnectorStartupError, buildSdkConnectorTools, buildConnectorToolDefs, buildFlowToolDefs, driveOrchestratorTurn, SessionNodeExecutor, SessionSubpromptRunner, SessionInlineSubFlowRunner, buildSdkFlowTools } from './chunk-SH7GXS7V.js';
10
+ import { loadConnectorDeclarations, SecretProviderChain, PreMintedSecretProvider, InMemorySecretProvider, resolvedConfigToDeclarations, isKnownSecretRef, deriveSingleMaterializedConnectorDeclaration } from './chunk-5T7Y3AZU.js';
11
+ import { EventNormalizer } from './chunk-CQY7XKRV.js';
9
12
  import { SUPPORTED_CLOUDS, probeResumeTranscript, CLOUD_SECRET_ENV_KEYS } from './chunk-3NCGSSCU.js';
13
+ import { CodexNativeStateUnavailable } from './chunk-LOO5CB5M.js';
14
+ import { dispatchCapability } from './chunk-7ZO3MUP3.js';
10
15
  import { classifyClaudeSdkError } from './chunk-GAH4YRCI.js';
11
- import { createDriver } from './chunk-FRER2PEN.js';
12
- import { loadFlow } from './chunk-BQMRUH7J.js';
13
- import { parseFlowDefinition } from './chunk-HY6CIKFH.js';
16
+ import { createDriver } from './chunk-J7VSUGGH.js';
17
+ import { loadFlow } from './chunk-SFCVAEJ5.js';
18
+ import { parseFlowDefinition } from './chunk-CP62G5PK.js';
14
19
  import { renderStimulusPrompt } from './chunk-2D5BYAL6.js';
15
- import { PROTOCOL_VERSION } from './chunk-BCOGOM6F.js';
16
- import { resolveSettings, resolveApiKey, providerEnvKey } from './chunk-CIPK5JMJ.js';
20
+ import { PROTOCOL_VERSION } from './chunk-23L3P7IB.js';
21
+ import { resolveSettings, resolveApiKey, providerEnvKey } from './chunk-H662SXKS.js';
17
22
  import { resolveDriverPaths } from './chunk-K5GBV4SA.js';
18
- import { resolveRuntimeAssets } from './chunk-OIDFK7SG.js';
19
- import { resolveSkWorkspaceConfig, resolveAgentDir, cloudConfigFromProfile, stageMaterializedSkills, loadMcpServerDeclarations, COMPACTION_DEFAULTS, validateAssetRecipeAttr, deriveSingleMaterializedMcpDeclaration } from './chunk-OZ7UNMTK.js';
23
+ import { resolveRuntimeAssets } from './chunk-DCG4UWJM.js';
24
+ import { resolveSkWorkspaceConfig, resolveAgentDir, cloudConfigFromProfile, stageMaterializedSkills, loadMcpServerDeclarations, COMPACTION_DEFAULTS, validateAssetRecipeAttr, deriveSingleMaterializedMcpDeclaration } from './chunk-RPVTPVGX.js';
20
25
  import { withFsDeadline, fsDeadlineMs, FsDeadlineError, tryWithFsDeadline } from './chunk-MKZOK4JU.js';
21
26
  import { parseAssetRef } from './chunk-GEEW6SY2.js';
22
27
  import { resolveLogStoreConfig, createLogStoreFromConfig, OnLogBridgeSink, WsLogSink } from './chunk-FTG7CRFD.js';
@@ -25,15 +30,19 @@ import { __require } from './chunk-NSBPE2FW.js';
25
30
  import pc from 'picocolors';
26
31
  import { Marked } from 'marked';
27
32
  import { markedTerminal } from 'marked-terminal';
28
- import fs4, { readFile, stat, rm, unlink, mkdir, writeFile, readdir, rename } from 'fs/promises';
33
+ import fs4, { readFile, stat, rm, unlink, mkdir, writeFile, readdir, rename, realpath, mkdtemp, lstat } from 'fs/promises';
34
+ import { createHash, randomBytes, timingSafeEqual, randomUUID } from 'crypto';
29
35
  import path4, { join, resolve, relative, sep, isAbsolute, dirname, basename } from 'path';
30
- import { existsSync, readFileSync, mkdirSync, writeFileSync, watch, chmodSync, rmSync } from 'fs';
36
+ import { existsSync, lstatSync, realpathSync, readFileSync, mkdirSync, writeFileSync, watch, chmodSync, accessSync, constants, rmSync } from 'fs';
31
37
  import { homedir } from 'os';
32
- import * as z6 from 'zod';
38
+ import * as z7 from 'zod';
33
39
  import { z } from 'zod';
34
- import { createHash, randomUUID } from 'crypto';
35
40
  import { execFile } from 'child_process';
36
41
  import { promisify } from 'util';
42
+ import { createServer } from 'http';
43
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
44
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
45
+ import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
37
46
  import { parse } from 'yaml';
38
47
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
39
48
  import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
@@ -190,11 +199,11 @@ var MarkdownStreamer = class {
190
199
  }
191
200
  };
192
201
  function defineCapability(args) {
193
- const inputSchema = z6.toJSONSchema(args.input, {
202
+ const inputSchema = z7.toJSONSchema(args.input, {
194
203
  target: "draft-07",
195
204
  io: "input"
196
205
  });
197
- const outputSchema = args.output ? z6.toJSONSchema(args.output, {
206
+ const outputSchema = args.output ? z7.toJSONSchema(args.output, {
198
207
  target: "draft-07",
199
208
  io: "output"
200
209
  }) : void 0;
@@ -241,11 +250,11 @@ async function resolveMixin(ref, defaultKind, agentDir, repos) {
241
250
  return { content: stripFrontmatter(raw).trim(), source: entry.source };
242
251
  }
243
252
  async function resolveAgentMixins(manifest, agentDir, repos) {
244
- const resolve4 = (refs, kind) => Promise.all((refs ?? []).map((r) => resolveMixin(r, kind, agentDir, repos)));
253
+ const resolve5 = (refs, kind) => Promise.all((refs ?? []).map((r) => resolveMixin(r, kind, agentDir, repos)));
245
254
  const [personaResults, rulesResults, knowledgeResults] = await Promise.all([
246
- resolve4(manifest.persona, "persona"),
247
- resolve4(manifest.rules, "ruleset"),
248
- resolve4(manifest.knowledge, "knowledge")
255
+ resolve5(manifest.persona, "persona"),
256
+ resolve5(manifest.rules, "ruleset"),
257
+ resolve5(manifest.knowledge, "knowledge")
249
258
  ]);
250
259
  return {
251
260
  personas: personaResults.filter((r) => r !== null),
@@ -260,8 +269,8 @@ async function readFileSafe(filePath) {
260
269
  return "";
261
270
  }
262
271
  }
263
- function stripFrontmatter(text) {
264
- return text.replace(/^---\s*\n[\s\S]*?\n---\s*\n?/, "");
272
+ function stripFrontmatter(text2) {
273
+ return text2.replace(/^---\s*\n[\s\S]*?\n---\s*\n?/, "");
265
274
  }
266
275
  function parseRef(ref, defaultKind) {
267
276
  let rest = ref.trim();
@@ -545,7 +554,7 @@ function registerCompositionCapabilities(registry, entries) {
545
554
  scope: "session",
546
555
  kind: "query",
547
556
  userInvokable: false,
548
- input: z6.strictObject({}),
557
+ input: z7.strictObject({}),
549
558
  handler: async (_args, ctx) => {
550
559
  ctx.log.info("loading composed asset content", {
551
560
  ref: entry.ref,
@@ -711,6 +720,363 @@ async function buildEnvironmentSection(projectDir) {
711
720
  lines.push(`**Working directory:** ${projectDir}`);
712
721
  return lines.join("\n");
713
722
  }
723
+ async function cancellable(work, signal) {
724
+ let abort = () => {
725
+ };
726
+ try {
727
+ return await Promise.race([
728
+ work,
729
+ new Promise((_resolve, reject) => {
730
+ abort = () => reject(new Error("CODEX_TOOL_CANCELLED"));
731
+ signal.addEventListener("abort", abort, { once: true });
732
+ if (signal.aborted) abort();
733
+ })
734
+ ]);
735
+ } finally {
736
+ signal.removeEventListener("abort", abort);
737
+ }
738
+ }
739
+ async function prepareCodexTools(options) {
740
+ options.signal.throwIfAborted();
741
+ if (!options.requiredTools.length) throw new Error("CODEX_REQUIRED_TOOL_UNAVAILABLE");
742
+ const { hooks } = options;
743
+ let turnSignal;
744
+ let toolsListTotal = 0;
745
+ let toolsCallTotal = 0;
746
+ const lifetime = new AbortController();
747
+ const signal = AbortSignal.any([options.signal, lifetime.signal]);
748
+ const list = () => hooks.composeTools().filter((tool) => {
749
+ const cap = hooks.resolve(tool.name);
750
+ return cap && (cap.audience ?? ["llm", "user"]).includes("llm") && !tool.name.startsWith("host.") && !tool.name.startsWith("runner.");
751
+ });
752
+ const validate = async () => {
753
+ signal.throwIfAborted();
754
+ const names = new Set(list().map((tool) => tool.name));
755
+ if (options.requiredTools.some((name) => !names.has(name)))
756
+ throw new Error("CODEX_REQUIRED_TOOL_UNAVAILABLE");
757
+ };
758
+ await validate();
759
+ const signature = () => JSON.stringify(list());
760
+ const initialSignature = signature();
761
+ const bearer = randomBytes(32).toString("base64url");
762
+ const authorization = Buffer.from(`Bearer ${bearer}`);
763
+ const peers = /* @__PURE__ */ new Set();
764
+ const transports = /* @__PURE__ */ new Map();
765
+ let closed = false;
766
+ const http = createServer((request, response) => {
767
+ void (async () => {
768
+ const supplied = Buffer.from(request.headers.authorization ?? "");
769
+ if (closed || supplied.length !== authorization.length || !timingSafeEqual(supplied, authorization)) {
770
+ response.writeHead(401).end();
771
+ return;
772
+ }
773
+ if (request.url !== "/mcp") {
774
+ response.writeHead(404).end();
775
+ return;
776
+ }
777
+ const id = request.headers["mcp-session-id"];
778
+ let transport = typeof id === "string" ? transports.get(id) : void 0;
779
+ let allocation;
780
+ try {
781
+ if (!transport) {
782
+ if (id || request.method !== "POST") {
783
+ response.writeHead(400).end();
784
+ return;
785
+ }
786
+ if (peers.size >= 2) {
787
+ response.writeHead(429).end();
788
+ return;
789
+ }
790
+ const server = new Server(
791
+ { name: "skaile-capabilities", version: "1" },
792
+ { capabilities: { tools: { listChanged: true } } }
793
+ );
794
+ transport = new StreamableHTTPServerTransport({
795
+ sessionIdGenerator: randomUUID,
796
+ onsessioninitialized: (sessionId) => {
797
+ transports.set(sessionId, transport);
798
+ }
799
+ });
800
+ peers.add(server);
801
+ allocation = server;
802
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
803
+ toolsListTotal = Math.min(512, toolsListTotal + 1);
804
+ return {
805
+ tools: list().map((tool) => ({
806
+ name: tool.name,
807
+ description: tool.description,
808
+ inputSchema: { ...tool.parameters, type: "object" }
809
+ }))
810
+ };
811
+ });
812
+ server.setRequestHandler(CallToolRequestSchema, async (call, extra) => {
813
+ toolsCallTotal = Math.min(512, toolsCallTotal + 1);
814
+ const currentTurn = turnSignal;
815
+ const cancellation = AbortSignal.any([
816
+ signal,
817
+ extra.signal,
818
+ ...currentTurn ? [currentTurn] : []
819
+ ]);
820
+ try {
821
+ cancellation.throwIfAborted();
822
+ if (!currentTurn || currentTurn !== turnSignal)
823
+ throw new Error("CODEX_TOOL_UNAVAILABLE");
824
+ if (!list().some((tool) => tool.name === call.params.name))
825
+ throw new Error("CODEX_TOOL_UNAVAILABLE");
826
+ const { result } = await cancellable(
827
+ dispatchCapability(
828
+ hooks,
829
+ randomUUID(),
830
+ call.params.name,
831
+ call.params.arguments ?? {},
832
+ () => {
833
+ },
834
+ cancellation
835
+ ),
836
+ cancellation
837
+ );
838
+ cancellation.throwIfAborted();
839
+ if (!currentTurn || currentTurn !== turnSignal)
840
+ throw new Error("CODEX_TOOL_UNAVAILABLE");
841
+ const payload = result === void 0 ? {} : result;
842
+ const isError = typeof payload === "object" && payload !== null && ("error" in payload && typeof payload.error === "string" || "ok" in payload && payload.ok === false || "isError" in payload && payload.isError === true);
843
+ if (typeof payload === "object" && payload !== null && "content" in payload && Array.isArray(payload.content))
844
+ return { content: payload.content, isError };
845
+ return {
846
+ content: [{ type: "text", text: JSON.stringify(payload) }],
847
+ isError
848
+ };
849
+ } catch {
850
+ return {
851
+ content: [
852
+ {
853
+ type: "text",
854
+ text: cancellation.aborted ? "CODEX_TOOL_CANCELLED" : "CODEX_TOOL_FAILED"
855
+ }
856
+ ],
857
+ isError: true
858
+ };
859
+ }
860
+ });
861
+ server.onclose = () => {
862
+ peers.delete(server);
863
+ if (transport?.sessionId) transports.delete(transport.sessionId);
864
+ };
865
+ await server.connect(transport);
866
+ }
867
+ await transport.handleRequest(request, response);
868
+ } finally {
869
+ if (allocation && !transport?.sessionId) {
870
+ peers.delete(allocation);
871
+ await allocation.close();
872
+ }
873
+ }
874
+ })().catch(() => {
875
+ if (!response.headersSent) response.writeHead(500).end();
876
+ else response.destroy();
877
+ });
878
+ });
879
+ const unsubscribe = hooks.onToolsChanged?.(() => {
880
+ for (const peer of peers) void peer.sendToolListChanged().catch(() => {
881
+ });
882
+ });
883
+ let disposal;
884
+ const dispose = () => disposal ??= (async () => {
885
+ closed = true;
886
+ lifetime.abort();
887
+ unsubscribe?.();
888
+ options.signal.removeEventListener("abort", abort);
889
+ await Promise.allSettled([...peers].map((peer) => peer.close()));
890
+ http.closeAllConnections();
891
+ if (http.listening) await new Promise((resolve5) => http.close(() => resolve5()));
892
+ })();
893
+ const abort = () => {
894
+ void dispose();
895
+ };
896
+ options.signal.addEventListener("abort", abort, { once: true });
897
+ try {
898
+ signal.throwIfAborted();
899
+ await new Promise((resolve5, reject) => {
900
+ http.once("error", reject);
901
+ http.listen(0, "127.0.0.1", resolve5);
902
+ });
903
+ signal.throwIfAborted();
904
+ const address = http.address();
905
+ if (!address || typeof address === "string") throw new Error("CODEX_REQUIRED_TOOL_UNAVAILABLE");
906
+ return {
907
+ diagnostics: {
908
+ serverName: "skaile-capabilities",
909
+ requestCounts: () => ({ toolsListTotal, toolsCallTotal })
910
+ },
911
+ mcpServers: {
912
+ "skaile-capabilities": {
913
+ url: `http://127.0.0.1:${address.port}/mcp`,
914
+ http_headers: { Authorization: `Bearer ${bearer}` },
915
+ required: true
916
+ }
917
+ },
918
+ onServerRequest: Object.fromEntries(
919
+ Object.entries(options.approvals).filter(
920
+ ([method, handler]) => [
921
+ "item/commandExecution/requestApproval",
922
+ "item/fileChange/requestApproval",
923
+ "item/permissions/requestApproval"
924
+ ].includes(method) && typeof handler === "function"
925
+ )
926
+ ),
927
+ beginTurn: (next) => {
928
+ turnSignal = next;
929
+ },
930
+ validate,
931
+ needsReload: () => signature() !== initialSignature,
932
+ instructions: `Available Skaile MCP tools: ${list().map((tool) => tool.name).join(", ")}`,
933
+ dispose
934
+ };
935
+ } catch {
936
+ await dispose();
937
+ http.closeAllConnections();
938
+ if (http.listening) await new Promise((resolve5) => http.close(() => resolve5()));
939
+ throw new Error("CODEX_REQUIRED_TOOL_UNAVAILABLE");
940
+ }
941
+ }
942
+ function registerCodexToolDefinitions(registry, namespace, tools) {
943
+ const owned = tools.map(
944
+ (tool) => defineCapability({
945
+ name: `${namespace}.${tool.name}`,
946
+ description: tool.description,
947
+ input: z7.object(tool.inputSchema),
948
+ side: "agent",
949
+ origin: { kind: "framework" },
950
+ audience: ["llm"],
951
+ handler: async (input, ctx) => {
952
+ ctx.signal?.throwIfAborted();
953
+ return tool.handler(input);
954
+ }
955
+ })
956
+ );
957
+ if (owned.some((cap) => registry.resolve(cap.name))) throw new Error("CODEX_TOOL_CONFLICT");
958
+ for (const cap of owned) registry.register(cap, "agent");
959
+ return () => {
960
+ for (const cap of owned) if (registry.resolve(cap.name) === cap) registry.deregister(cap.name);
961
+ };
962
+ }
963
+ function contains(root, target) {
964
+ const path5 = relative(root, target);
965
+ return path5 === "" || !path5.startsWith("..") && !isAbsolute(path5);
966
+ }
967
+ async function canonical(path5) {
968
+ try {
969
+ return await realpath(path5);
970
+ } catch (error) {
971
+ if (error.code !== "ENOENT") throw error;
972
+ const parent = dirname(path5);
973
+ if (parent === path5) throw error;
974
+ return resolve(await canonical(parent), relative(parent, path5));
975
+ }
976
+ }
977
+ async function assertScopedTree(path5, root) {
978
+ let remaining = 1e4;
979
+ async function visit(entry) {
980
+ if (--remaining < 0) throw new Error("CODEX_RESOURCE_SCOPE_INVALID");
981
+ let stat3;
982
+ try {
983
+ stat3 = await lstat(entry);
984
+ } catch (error) {
985
+ if (error.code === "ENOENT") return;
986
+ throw error;
987
+ }
988
+ if (!contains(root, await realpath(entry)) || stat3.isSymbolicLink())
989
+ throw new Error("CODEX_RESOURCE_SCOPE_INVALID");
990
+ if (stat3.isDirectory())
991
+ for (const child of await readdir(entry)) await visit(join(entry, child));
992
+ }
993
+ await visit(path5);
994
+ }
995
+ async function registerCodexResourceTools(options) {
996
+ const project = await realpath(options.projectDir);
997
+ const privateRoot = await canonical(resolve(options.privateDirectory));
998
+ if (contains(project, privateRoot) || contains(privateRoot, project))
999
+ throw new Error("CODEX_RESOURCE_SCOPE_INVALID");
1000
+ const statePath = join(project, ".skaile", "plugin-state.json");
1001
+ const assertStateScope = async () => {
1002
+ if (!contains(project, await canonical(statePath)))
1003
+ throw new Error("CODEX_RESOURCE_SCOPE_INVALID");
1004
+ };
1005
+ await assertStateScope();
1006
+ const plugin = new WorkspacePlugin({
1007
+ projectDir: options.projectDir,
1008
+ connectorManager: options.manager ?? void 0,
1009
+ driver: "codex",
1010
+ provider: "openai",
1011
+ model: options.model
1012
+ });
1013
+ await plugin.store.load();
1014
+ const removals = [];
1015
+ const protectFlow = (tools) => tools.map((tool) => ({
1016
+ ...tool,
1017
+ handler: async (input) => {
1018
+ if (tool.name === "mount_read") {
1019
+ const mount = options.manager?.listConnectors().find((entry) => entry.id === input.mount_id);
1020
+ if (!mount?.mountPath || typeof input.path !== "string")
1021
+ throw new Error("CODEX_RESOURCE_SCOPE_INVALID");
1022
+ const root = await realpath(mount.mountPath);
1023
+ const target = await realpath(resolve(root, input.path));
1024
+ if (!contains(project, root) || !contains(root, target))
1025
+ throw new Error("CODEX_RESOURCE_SCOPE_INVALID");
1026
+ }
1027
+ if (tool.name.startsWith("skill_") || ["flow_list", "flow_show", "flow_find_flow_for_session"].includes(tool.name)) {
1028
+ const assets = await findAiAssetsRoot(project);
1029
+ if (assets) await assertScopedTree(assets, project);
1030
+ }
1031
+ if (tool.name.startsWith("session_") || tool.name.includes("session"))
1032
+ await assertScopedTree(join(project, ".skaile", "sessions"), project);
1033
+ if (tool.name === "connector_exec" && options.manager && typeof input.connector_id === "string" && options.manager.listConnectors().some((entry) => entry.id === input.connector_id && entry.driver === "flow") && !buildFlowToolDefs(options.manager, input.connector_id).some(
1034
+ (operation) => operation.name === input.operation
1035
+ ))
1036
+ throw new Error("CODEX_TOOL_UNAVAILABLE");
1037
+ return tool.handler(input);
1038
+ }
1039
+ }));
1040
+ try {
1041
+ removals.push(
1042
+ registerCodexToolDefinitions(
1043
+ options.registry,
1044
+ "workspace",
1045
+ protectFlow(
1046
+ buildWorkspaceToolDefs(plugin).filter(
1047
+ (tool) => ![
1048
+ "workspace_test_secret",
1049
+ "workspace_validate",
1050
+ "workspace_reload",
1051
+ "skill_check_requirements"
1052
+ ].includes(tool.name)
1053
+ )
1054
+ )
1055
+ )
1056
+ );
1057
+ if (options.manager)
1058
+ removals.push(
1059
+ registerCodexToolDefinitions(
1060
+ options.registry,
1061
+ "connector",
1062
+ protectFlow(buildConnectorToolDefs(options.manager, { shellAccess: false }))
1063
+ )
1064
+ );
1065
+ } catch (error) {
1066
+ for (const remove of removals) remove();
1067
+ throw error;
1068
+ }
1069
+ return async () => {
1070
+ for (const remove of removals) remove();
1071
+ await assertStateScope();
1072
+ await plugin.shutdown();
1073
+ };
1074
+ }
1075
+ function registerCodexFlowTools(registry, manager, connectorId) {
1076
+ const tools = buildFlowToolDefs(manager, connectorId);
1077
+ if (!tools.length) throw new Error("CODEX_REQUIRED_TOOL_UNAVAILABLE");
1078
+ return registerCodexToolDefinitions(registry, "flow", tools);
1079
+ }
714
1080
  async function agentDefinitionExists(agentDir) {
715
1081
  try {
716
1082
  await fs4.access(path4.join(agentDir, "agent.yaml"));
@@ -1043,17 +1409,17 @@ var McpServerAlreadyRegisteredError = class extends Error {
1043
1409
  }
1044
1410
  id;
1045
1411
  };
1046
- function resolveRecordSecrets(record, secrets) {
1047
- if (!secrets) return record;
1412
+ function resolveRecordSecrets(record2, secrets) {
1413
+ if (!secrets) return record2;
1048
1414
  const resolved = {};
1049
- for (const [k, v] of Object.entries(record)) {
1415
+ for (const [k, v] of Object.entries(record2)) {
1050
1416
  resolved[k] = secrets.resolve(v) ?? v;
1051
1417
  }
1052
1418
  return resolved;
1053
1419
  }
1054
- function resolveRecordSecretsStrict(record, secrets, ctx) {
1420
+ function resolveRecordSecretsStrict(record2, secrets, ctx) {
1055
1421
  const resolved = {};
1056
- for (const [k, v] of Object.entries(record)) {
1422
+ for (const [k, v] of Object.entries(record2)) {
1057
1423
  const value = secrets?.resolve(v);
1058
1424
  if (value === void 0 && isKnownSecretRef(v)) {
1059
1425
  throw new Error(
@@ -1069,13 +1435,15 @@ var RESERVED_MCP_SERVER_IDS = /* @__PURE__ */ new Set([
1069
1435
  "skaile-workspace",
1070
1436
  "skaile-capabilities"
1071
1437
  ]);
1072
- async function resolveExternalMcpDeclarations(projectDir, sessionId) {
1438
+ async function resolveExternalMcpDeclarations(projectDir, sessionId, managedCodex = false) {
1073
1439
  const mcpLog = createLogger({
1074
1440
  kind: "mcp",
1075
1441
  subkind: "wiring",
1076
1442
  instance: sessionId ?? "no-session"
1077
1443
  });
1078
1444
  const mcpDeclarations = await loadMcpServerDeclarations(projectDir);
1445
+ if (managedCodex && mcpDeclarations.length > 0)
1446
+ throw new Error("CODEX_MANAGED_PROJECT_MCP_UNSUPPORTED");
1079
1447
  mcpLog.debug("loaded MCP declarations", { count: mcpDeclarations.length });
1080
1448
  const recipeCache = createRecipeCache();
1081
1449
  const nixFlakeRef = process.env.SKAILE_NIX_FLAKE_REF ?? "/etc/skaile/flake";
@@ -1414,37 +1782,40 @@ var ExternalMcpManager = class {
1414
1782
  inputZod: PASSTHROUGH_INPUT_ZOD,
1415
1783
  handler: async (input, ctx) => {
1416
1784
  const call = { name: tool.name, arguments: input ?? {} };
1785
+ const invoke = () => ctx.signal ? server.client.callTool(call, void 0, { signal: ctx.signal }) : server.client.callTool(call);
1417
1786
  let result;
1418
1787
  try {
1419
- result = await server.client.callTool(call);
1788
+ result = await invoke();
1420
1789
  } catch (err) {
1421
- if (isMcpAuthError(err) && await this.reauthAndReconnect(server)) {
1790
+ if (!ctx.signal?.aborted && isMcpAuthError(err) && await this.reauthAndReconnect(server)) {
1422
1791
  ctx.log.info("mcp tool retried after 401 re-mint", { tool: name });
1423
- result = await server.client.callTool(call);
1792
+ result = await invoke();
1424
1793
  } else {
1425
1794
  throw err;
1426
1795
  }
1427
1796
  }
1428
1797
  const content = result.content ?? [];
1429
- const text = content.filter((c) => c.type === "text" && typeof c.text === "string").map((c) => c.text).join("\n");
1798
+ const text2 = content.filter((c) => c.type === "text" && typeof c.text === "string").map((c) => c.text).join("\n");
1430
1799
  if (result.isError) {
1431
- throw new Error(text || `MCP tool ${name} returned an error`);
1800
+ throw new Error(text2 || `MCP tool ${name} returned an error`);
1432
1801
  }
1433
- ctx.log.debug("mcp tool ok", { tool: name, hasText: text.length > 0 });
1434
- return text.length > 0 ? text : content;
1802
+ ctx.log.debug("mcp tool ok", { tool: name, hasText: text2.length > 0 });
1803
+ return text2.length > 0 ? text2 : content;
1435
1804
  }
1436
1805
  };
1437
1806
  }
1438
1807
  /**
1439
1808
  * Deregister every tool and close every client (kills the subprocesses).
1440
- * Best-effort: a failed close on one server does not prevent the rest.
1809
+ * Best-effort by default: a failed close on one server does not prevent the rest.
1810
+ * With strict:true, report close failures after all owned cleanup attempts.
1441
1811
  *
1442
1812
  * Drains any in-flight 401 reconnect first: a `doReauthAndReconnect` resolving
1443
1813
  * after teardown would set `server.client` to a freshly-connected client that
1444
1814
  * nothing then closes (leak). Awaiting `reauthInFlight` guarantees we close the
1445
1815
  * LATEST client.
1446
1816
  */
1447
- async dispose() {
1817
+ async dispose(options = {}) {
1818
+ const failures = [];
1448
1819
  await Promise.allSettled(this.servers.map((s) => s.reauthInFlight).filter(Boolean));
1449
1820
  for (const server of this.servers) {
1450
1821
  for (const toolName of server.toolNames) {
@@ -1453,6 +1824,7 @@ var ExternalMcpManager = class {
1453
1824
  try {
1454
1825
  await server.client.close();
1455
1826
  } catch (err) {
1827
+ failures.push(err);
1456
1828
  this.log.warn("MCP server close failed", {
1457
1829
  id: server.id,
1458
1830
  error: err instanceof Error ? err.message : String(err)
@@ -1460,6 +1832,8 @@ var ExternalMcpManager = class {
1460
1832
  }
1461
1833
  }
1462
1834
  this.servers.length = 0;
1835
+ if (options.strict && failures.length > 0)
1836
+ throw new AggregateError(failures, "MCP server cleanup failed");
1463
1837
  }
1464
1838
  };
1465
1839
 
@@ -1486,6 +1860,7 @@ function buildMcpPromptSection(declarations, connected) {
1486
1860
 
1487
1861
  // runner/src/resources.ts
1488
1862
  async function buildAgentResources(projectDir, driverType, _onLog, watch, secretProvider, sessionMeta, tokenMediator, preMintedSecrets, deferFilesystemMounts, capabilityRegistry, fallbackConnectorDeclarations, extraMcpDeclarations) {
1863
+ const managedProjectMcp = sessionMeta?.managedCodex ? await resolveExternalMcpDeclarations(projectDir, sessionMeta.sessionId, true) : void 0;
1489
1864
  const resLog = createLogger({
1490
1865
  kind: "runner",
1491
1866
  subkind: "resources",
@@ -1512,7 +1887,8 @@ async function buildAgentResources(projectDir, driverType, _onLog, watch, secret
1512
1887
  for (const w of runtimeAssets.warnings) {
1513
1888
  resLog.warn("runtime asset warning", { code: w.code, message: w.message });
1514
1889
  }
1515
- await maybeInstallNpmPeerDeps(runtimeAssets, projectDir, resLog);
1890
+ if (!sessionMeta?.managedCodex)
1891
+ await maybeInstallNpmPeerDeps(runtimeAssets, projectDir, resLog);
1516
1892
  const diskDeclarations = loadConnectorDeclarations(projectDir);
1517
1893
  const connectorDeclarations = diskDeclarations.length > 0 ? diskDeclarations : fallbackConnectorDeclarations ?? [];
1518
1894
  if (diskDeclarations.length === 0 && connectorDeclarations.length > 0) {
@@ -1571,7 +1947,7 @@ async function buildAgentResources(projectDir, driverType, _onLog, watch, secret
1571
1947
  }
1572
1948
  if (capabilityRegistry) {
1573
1949
  externalMcpDeclarations = mergeExtraMcpDeclarations(
1574
- await resolveExternalMcpDeclarations(projectDir, sessionMeta?.sessionId),
1950
+ managedProjectMcp ?? await resolveExternalMcpDeclarations(projectDir, sessionMeta?.sessionId),
1575
1951
  extraMcpDeclarations
1576
1952
  );
1577
1953
  externalMcpManager = await startExternalMcpServers(
@@ -1832,6 +2208,9 @@ function toSdkMcpServerConfig(decl, secrets) {
1832
2208
 
1833
2209
  // runner/src/session-builder.ts
1834
2210
  async function createAgentSession(config) {
2211
+ const managed = config.managedCodex;
2212
+ if (managed && (config.driver !== "codex" || config.provider !== "openai" || !config.model || !config.aiProviderConfigId || !config.capabilityRegistry || !config.capabilities || config.apiKey || config.cloud && config.cloud !== "default" || config.cloudConfig || config.cloudSecrets))
2213
+ throw new Error("AI_PROFILE_INVALID");
1835
2214
  const {
1836
2215
  projectDir,
1837
2216
  cwd: cwdOverride,
@@ -1850,7 +2229,17 @@ async function createAgentSession(config) {
1850
2229
  telemetry,
1851
2230
  trace
1852
2231
  } = config;
2232
+ const managedWorkspaceConfig = managed ? wsConfigOverride ?? resolveSkWorkspaceConfig(projectDir) : void 0;
2233
+ if (managedWorkspaceConfig?.agent?.["prompt-extensions"]?.length)
2234
+ throw new Error("CODEX_MANAGED_PROMPT_EXTENSIONS_UNSUPPORTED");
1853
2235
  const agentCwd = cwdOverride ?? projectDir;
2236
+ if (managed)
2237
+ prepareNativePolicy({
2238
+ cwd: agentCwd,
2239
+ privateRoot: managed.runtime.privateRoot,
2240
+ privateDirectory: managed.runtime.privateDirectory,
2241
+ sandboxMode: managed.sandboxMode
2242
+ });
1854
2243
  const sessionLog = createLogger({
1855
2244
  kind: "runner",
1856
2245
  subkind: "session",
@@ -1861,12 +2250,12 @@ async function createAgentSession(config) {
1861
2250
  provider: providerOverride,
1862
2251
  model: modelOverride
1863
2252
  });
1864
- const driverType = settings.driver ?? "omp";
1865
- const provider = settings.provider;
1866
- const model = settings.model;
1867
- const cloud = config.cloud ?? settings.cloud ?? "default";
1868
- const cloudConfig = config.cloudConfig ?? settings.cloudConfig;
1869
- const apiKey = cloud === "bedrock" || cloud === "vertex" || cloud === "azure" ? config.apiKey : config.apiKey ?? resolveApiKey(provider ?? "anthropic", settings);
2253
+ const driverType = managed ? "codex" : settings.driver ?? "omp";
2254
+ const provider = managed ? config.provider : settings.provider;
2255
+ const model = managed ? config.model : settings.model;
2256
+ const cloud = managed ? "default" : config.cloud ?? settings.cloud ?? "default";
2257
+ const cloudConfig = managed ? void 0 : config.cloudConfig ?? settings.cloudConfig;
2258
+ const apiKey = managed ? void 0 : cloud === "bedrock" || cloud === "vertex" || cloud === "azure" ? config.apiKey : config.apiKey ?? resolveApiKey(provider ?? "anthropic", settings);
1870
2259
  const manifest = agentDir ? await loadAgentManifest(agentDir) : void 0;
1871
2260
  const {
1872
2261
  resourceManager,
@@ -1887,7 +2276,8 @@ async function createAgentSession(config) {
1887
2276
  {
1888
2277
  provider,
1889
2278
  model,
1890
- sessionId
2279
+ sessionId,
2280
+ ...managed ? { managedCodex: true } : {}
1891
2281
  },
1892
2282
  config.tokenMediator,
1893
2283
  config.preMintedSecrets,
@@ -1896,7 +2286,7 @@ async function createAgentSession(config) {
1896
2286
  config.fallbackConnectorDeclarations,
1897
2287
  config.getExtraMcpDeclarations?.()
1898
2288
  );
1899
- const wsConfig = wsConfigOverride ?? resolveSkWorkspaceConfig(projectDir);
2289
+ const wsConfig = managedWorkspaceConfig ?? wsConfigOverride ?? resolveSkWorkspaceConfig(projectDir);
1900
2290
  const contextSection = buildContextSection(wsConfig.agent?.context);
1901
2291
  const userPromptSection = wsConfig.agent?.prompt?.trim();
1902
2292
  const environmentSection = await buildEnvironmentSection(projectDir);
@@ -1912,6 +2302,20 @@ async function createAgentSession(config) {
1912
2302
  }
1913
2303
  const composition = await resolveSessionComposition(agentDir, manifest, projectDir, sessionLog);
1914
2304
  const compositionBlocks = composition?.inlineBlocks ?? [];
2305
+ const disposeManagedTools = managed ? await registerCodexResourceTools({
2306
+ registry: config.capabilityRegistry,
2307
+ manager: resourceManager,
2308
+ projectDir,
2309
+ model: config.model,
2310
+ privateDirectory: managed.runtime.privateRoot
2311
+ }) : void 0;
2312
+ const disposeSessionResources = async () => {
2313
+ try {
2314
+ await disposeManagedTools?.();
2315
+ } finally {
2316
+ await dispose();
2317
+ }
2318
+ };
1915
2319
  const additionalSections = config.additionalPromptSections ?? [];
1916
2320
  const systemPromptSections = buildSystemPromptSections({
1917
2321
  contextSection,
@@ -1935,27 +2339,39 @@ async function createAgentSession(config) {
1935
2339
  ]);
1936
2340
  logAssembledSystemPrompt(systemPrompt, sessionLog);
1937
2341
  const thinking = config.thinking ?? wsConfig.agent_config?.default?.thinking;
1938
- const effort = config.effort ?? wsConfig.agent_config?.default?.effort;
2342
+ const effort = config.effort ?? (managed ? void 0 : wsConfig.agent_config?.default?.effort);
1939
2343
  const maxTurns = maxTurnsOverride ?? manifest?.runtime?.max_turns;
1940
- const driver = await createSessionDriver({
1941
- config,
1942
- driverType,
1943
- agentCwd,
1944
- provider,
1945
- model,
1946
- cloud,
1947
- cloudConfig,
1948
- manifest,
1949
- maxTurns,
1950
- apiKey,
1951
- systemPrompt,
1952
- thinking,
1953
- effort,
1954
- sessionId,
1955
- resumeSessionId,
1956
- mcpServers,
1957
- agentDir
1958
- });
2344
+ let driver;
2345
+ try {
2346
+ driver = await createSessionDriver({
2347
+ config,
2348
+ driverType,
2349
+ agentCwd,
2350
+ provider,
2351
+ model,
2352
+ cloud,
2353
+ cloudConfig,
2354
+ manifest,
2355
+ maxTurns,
2356
+ apiKey,
2357
+ systemPrompt,
2358
+ thinking,
2359
+ effort,
2360
+ sessionId,
2361
+ resumeSessionId,
2362
+ mcpServers,
2363
+ agentDir
2364
+ });
2365
+ } catch (error) {
2366
+ try {
2367
+ await disposeSessionResources();
2368
+ } catch (cleanupError) {
2369
+ throw new AggregateError([error, cleanupError], "Session creation and cleanup failed", {
2370
+ cause: error
2371
+ });
2372
+ }
2373
+ throw error;
2374
+ }
1959
2375
  if (telemetry && trace) {
1960
2376
  driver.setTelemetry(telemetry, trace);
1961
2377
  }
@@ -1968,7 +2384,7 @@ async function createAgentSession(config) {
1968
2384
  driverType,
1969
2385
  provider,
1970
2386
  model,
1971
- dispose,
2387
+ dispose: disposeSessionResources,
1972
2388
  startWatching,
1973
2389
  getOrCreateExternalMcpManager,
1974
2390
  getExternalMcpManager,
@@ -1976,6 +2392,45 @@ async function createAgentSession(config) {
1976
2392
  systemPromptSections
1977
2393
  };
1978
2394
  }
2395
+ function createManagedCodexSubpromptDriver(config, model, cwd, privateDirectory) {
2396
+ const managed = config.managedCodex;
2397
+ if (!managed || !model || !config.sessionId || !config.aiProviderConfigId || !config.capabilities)
2398
+ return Promise.reject(new Error("AI_PROFILE_INVALID"));
2399
+ prepareNativePolicy({
2400
+ cwd,
2401
+ privateRoot: managed.runtime.privateRoot,
2402
+ privateDirectory,
2403
+ sandboxMode: managed.sandboxMode
2404
+ });
2405
+ return createDriver("codex", {
2406
+ cwd,
2407
+ provider: "openai",
2408
+ model,
2409
+ sessionId: `${config.sessionId}:subprompt:${randomUUID()}`,
2410
+ maxTurns: 1,
2411
+ aiProviderConfigId: config.aiProviderConfigId,
2412
+ driverOptions: {
2413
+ codex: {
2414
+ authSource: "managed",
2415
+ approvalPolicy: managed.approvalPolicy,
2416
+ sandboxMode: managed.sandboxMode,
2417
+ reasoningEffort: managed.reasoningEffort,
2418
+ managedRuntime: {
2419
+ ...managed.runtime,
2420
+ privateDirectory,
2421
+ nativeTurnBudget: 1,
2422
+ credential: structuredClone(managed.runtime.credential),
2423
+ prepareTools: (signal) => prepareCodexTools({
2424
+ hooks: config.capabilities,
2425
+ requiredTools: managed.requiredTools,
2426
+ approvals: managed.approvals,
2427
+ signal
2428
+ })
2429
+ }
2430
+ }
2431
+ }
2432
+ });
2433
+ }
1979
2434
  async function loadPromptExtensions(paths, projectDir, log) {
1980
2435
  if (!paths?.length) return [];
1981
2436
  const loaded = await Promise.all(
@@ -2079,6 +2534,25 @@ function createSessionDriver(args) {
2079
2534
  agentDir
2080
2535
  } = args;
2081
2536
  return createDriver(driverType, {
2537
+ ...config.managedCodex ? {
2538
+ driverOptions: {
2539
+ codex: {
2540
+ authSource: "managed",
2541
+ approvalPolicy: config.managedCodex.approvalPolicy,
2542
+ sandboxMode: config.managedCodex.sandboxMode,
2543
+ reasoningEffort: config.managedCodex.reasoningEffort,
2544
+ managedRuntime: {
2545
+ ...config.managedCodex.runtime,
2546
+ prepareTools: (signal) => prepareCodexTools({
2547
+ hooks: config.capabilities,
2548
+ requiredTools: config.managedCodex.requiredTools,
2549
+ approvals: config.managedCodex.approvals,
2550
+ signal
2551
+ })
2552
+ }
2553
+ }
2554
+ }
2555
+ } : {},
2082
2556
  cwd: agentCwd,
2083
2557
  provider,
2084
2558
  model: model ?? manifest?.model?.preferred,
@@ -2149,14 +2623,14 @@ async function runAgentChat(opts) {
2149
2623
  ${message}`;
2150
2624
  }
2151
2625
  try {
2152
- await new Promise((resolve4, reject) => {
2626
+ await new Promise((resolve5, reject) => {
2153
2627
  const onEvent = (event) => {
2154
2628
  if (event.type === "agent_end") {
2155
2629
  driver.off("agent-event", onEvent);
2156
2630
  mdStream.end();
2157
2631
  process.stdout.write("\n");
2158
2632
  driver.kill();
2159
- resolve4();
2633
+ resolve5();
2160
2634
  } else if (event.type === "error") {
2161
2635
  driver.off("agent-event", onEvent);
2162
2636
  const err = Object.assign(new Error(String(event.error)), {
@@ -2206,10 +2680,10 @@ function keywordSearch(capabilities, query, limit) {
2206
2680
  return scored.slice(0, limit).map((x) => x.cap);
2207
2681
  }
2208
2682
  function builtinCapabilities(registry) {
2209
- const listFilterSchema = z6.strictObject({
2210
- side: z6.enum(["client", "agent"]).optional(),
2211
- originKind: z6.enum(["framework", "client", "agent", "flow", "skill", "mcp", "connector", "mount"]).optional(),
2212
- scope: z6.enum(["session", "turn"]).optional()
2683
+ const listFilterSchema = z7.strictObject({
2684
+ side: z7.enum(["client", "agent"]).optional(),
2685
+ originKind: z7.enum(["framework", "client", "agent", "flow", "skill", "mcp", "connector", "mount"]).optional(),
2686
+ scope: z7.enum(["session", "turn"]).optional()
2213
2687
  });
2214
2688
  return [
2215
2689
  defineCapability({
@@ -2235,9 +2709,9 @@ function builtinCapabilities(registry) {
2235
2709
  origin: { kind: "framework" },
2236
2710
  kind: "query",
2237
2711
  userInvokable: false,
2238
- input: z6.strictObject({
2239
- query: z6.string(),
2240
- limit: z6.number().int().positive().optional()
2712
+ input: z7.strictObject({
2713
+ query: z7.string(),
2714
+ limit: z7.number().int().positive().optional()
2241
2715
  }),
2242
2716
  handler: async ({ query, limit }) => keywordSearch(registry.list(), query, limit ?? 10)
2243
2717
  }),
@@ -2249,7 +2723,7 @@ function builtinCapabilities(registry) {
2249
2723
  origin: { kind: "framework" },
2250
2724
  kind: "query",
2251
2725
  userInvokable: false,
2252
- input: z6.strictObject({ name: z6.string() }),
2726
+ input: z7.strictObject({ name: z7.string() }),
2253
2727
  handler: async ({ name }) => {
2254
2728
  const cap = registry.resolve(name);
2255
2729
  if (!cap) return null;
@@ -2293,6 +2767,22 @@ var CapabilityRegistry = class {
2293
2767
  byName = /* @__PURE__ */ new Map();
2294
2768
  logger;
2295
2769
  remoteInvoker;
2770
+ toolListeners = /* @__PURE__ */ new Set();
2771
+ /** Observe inventory changes without caching a second tool registry. */
2772
+ onToolsChanged(listener) {
2773
+ this.toolListeners.add(listener);
2774
+ return () => {
2775
+ this.toolListeners.delete(listener);
2776
+ };
2777
+ }
2778
+ toolsChanged() {
2779
+ for (const listener of this.toolListeners) {
2780
+ try {
2781
+ listener();
2782
+ } catch {
2783
+ }
2784
+ }
2785
+ }
2296
2786
  constructor(logger) {
2297
2787
  this.logger = logger ?? createLogger({ kind: "runner", subkind: "capability-registry" });
2298
2788
  }
@@ -2359,6 +2849,7 @@ var CapabilityRegistry = class {
2359
2849
  return;
2360
2850
  }
2361
2851
  this.byName.set(cap.name, cap);
2852
+ this.toolsChanged();
2362
2853
  this.logger.info("capability registered", {
2363
2854
  name: cap.name,
2364
2855
  side: cap.side,
@@ -2372,6 +2863,7 @@ var CapabilityRegistry = class {
2372
2863
  */
2373
2864
  deregister(name) {
2374
2865
  if (this.byName.delete(name)) {
2866
+ this.toolsChanged();
2375
2867
  this.logger.info("capability deregistered", { name });
2376
2868
  }
2377
2869
  }
@@ -2473,6 +2965,7 @@ var CapabilityRegistry = class {
2473
2965
  handler: HYDRATED_REJECT_HANDLER
2474
2966
  };
2475
2967
  this.byName.set(cap.name, stub);
2968
+ this.toolsChanged();
2476
2969
  hydrated++;
2477
2970
  }
2478
2971
  this.logger.info("capability registry hydrated", { count: hydrated, total: snapshot.length });
@@ -2486,6 +2979,7 @@ var CapabilityRegistry = class {
2486
2979
  * @throws when the capability is unknown or the input fails validation
2487
2980
  */
2488
2981
  async invoke(name, input, baseCtx) {
2982
+ baseCtx.signal?.throwIfAborted();
2489
2983
  const cap = this.resolve(name);
2490
2984
  if (!cap) {
2491
2985
  throw new Error(`Unknown capability: ${name}`);
@@ -2539,12 +3033,12 @@ var CapabilityRegistry = class {
2539
3033
  }
2540
3034
  };
2541
3035
  function computeCapabilitySignature(caps) {
2542
- const canonical = caps.slice().sort((a, b) => a.name.localeCompare(b.name)).map((c) => ({
3036
+ const canonical2 = caps.slice().sort((a, b) => a.name.localeCompare(b.name)).map((c) => ({
2543
3037
  name: c.name,
2544
3038
  origin: c.origin.kind,
2545
3039
  schemaSha256: sha256(JSON.stringify(c.inputSchema ?? {}))
2546
3040
  }));
2547
- return sha256(JSON.stringify(canonical));
3041
+ return sha256(JSON.stringify(canonical2));
2548
3042
  }
2549
3043
  function sha256(input) {
2550
3044
  return createHash("sha256").update(input).digest("hex");
@@ -2583,7 +3077,7 @@ function buildClientCapabilityHandler(args) {
2583
3077
  });
2584
3078
  return {};
2585
3079
  }
2586
- return new Promise((resolve4, reject) => {
3080
+ return new Promise((resolve5, reject) => {
2587
3081
  const timer = setTimeout(() => {
2588
3082
  args.pending.delete(callId);
2589
3083
  reject(
@@ -2592,7 +3086,7 @@ function buildClientCapabilityHandler(args) {
2592
3086
  )
2593
3087
  );
2594
3088
  }, timeoutMs);
2595
- args.pending.set(callId, { resolve: resolve4, reject, timer });
3089
+ args.pending.set(callId, { resolve: resolve5, reject, timer });
2596
3090
  args.emit({
2597
3091
  type: "capability_invoked",
2598
3092
  callId,
@@ -2832,38 +3326,8 @@ async function handleMountResourceRequest(command, manager, emit) {
2832
3326
  });
2833
3327
  }
2834
3328
  }
2835
- var identifier = z6.string().min(1).max(4096);
2836
- var timestamp = z6.iso.datetime({ offset: true });
2837
- var common = {
2838
- configId: identifier,
2839
- credentialVersion: z6.number().int().nonnegative().safe(),
2840
- mintedAt: timestamp
2841
- };
2842
- var subscription = z6.strictObject({
2843
- ...common,
2844
- kind: z6.literal("codex-subscription"),
2845
- accessToken: z6.string().min(1).max(65536),
2846
- chatgptAccountId: identifier,
2847
- chatgptPlanType: identifier.optional(),
2848
- expiresAt: timestamp
2849
- });
2850
- var delivery = z6.discriminatedUnion("kind", [
2851
- subscription,
2852
- z6.strictObject({
2853
- ...common,
2854
- kind: z6.literal("openai-api-key"),
2855
- apiKey: z6.string().min(1).max(65536)
2856
- })
2857
- ]);
2858
- function parseCodexCredential(value, now = Date.now()) {
2859
- const parsed = delivery.safeParse(value);
2860
- if (!parsed.success) throw new Error("Invalid managed AI credential");
2861
- const credential = parsed.data;
2862
- const mintedAt = Date.parse(credential.mintedAt);
2863
- if (mintedAt > now || credential.kind === "codex-subscription" && (Date.parse(credential.expiresAt) <= now || Date.parse(credential.expiresAt) <= mintedAt))
2864
- throw new Error("Invalid managed AI credential timestamps");
2865
- return credential;
2866
- }
3329
+
3330
+ // runner/src/codex-init.ts
2867
3331
  function validateCodexInit(cmd, supported, previous) {
2868
3332
  const requirements = cmd.requiredRuntimeFeatures;
2869
3333
  if (requirements !== void 0 && (!Array.isArray(requirements) || requirements.some((item) => typeof item !== "string" || !supported.includes(item))))
@@ -2885,6 +3349,111 @@ function validateCodexInit(cmd, supported, previous) {
2885
3349
  if (cmd.secrets && Object.keys(cmd.secrets).some((key) => /openai|codex/i.test(key)))
2886
3350
  throw new Error("Conflicting managed AI credential delivery");
2887
3351
  }
3352
+ var text = z7.string().min(1).max(4096);
3353
+ var timeout = z7.number().int().positive().max(18e5).optional();
3354
+ var zHost = z7.object({
3355
+ schemaVersion: z7.literal(1),
3356
+ sessionId: z7.string().min(1).max(128),
3357
+ runtime: z7.object({
3358
+ executable: text,
3359
+ executableArgs: z7.array(text).max(64).optional(),
3360
+ privateDirectory: text,
3361
+ privateRoot: text,
3362
+ environment: z7.record(z7.string(), z7.string()),
3363
+ instructionFiles: z7.array(text).max(64).optional(),
3364
+ skillsDirectory: text.optional(),
3365
+ requestTimeoutMs: timeout,
3366
+ turnTimeoutMs: timeout,
3367
+ interactionTimeoutMs: timeout
3368
+ }).strict(),
3369
+ requiredTools: z7.array(z7.string().min(1).max(256)).min(1).max(1024),
3370
+ approvalPolicy: z7.enum(["never", "on-request", "untrusted"]),
3371
+ sandboxMode: z7.enum(["read-only", "workspace-write"]),
3372
+ reasoningEffort: z7.enum(["minimal", "low", "medium", "high", "xhigh"]),
3373
+ subpromptModels: z7.object({
3374
+ small: text,
3375
+ deep: text,
3376
+ available: z7.array(text).min(1).max(1024)
3377
+ }).strict()
3378
+ }).strict();
3379
+ var refused = () => new Error("CODEX_MANAGED_BOOTSTRAP_INVALID");
3380
+ var overlaps = (a, b) => {
3381
+ const within = (child, parent) => {
3382
+ const rel = relative(parent, child);
3383
+ return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
3384
+ };
3385
+ return within(a, b) || within(b, a);
3386
+ };
3387
+ var denyNativeGrants = {
3388
+ "item/commandExecution/requestApproval": async () => ({ decision: "decline" }),
3389
+ "item/fileChange/requestApproval": async () => ({ decision: "decline" }),
3390
+ "item/permissions/requestApproval": async () => ({ permissions: {}, scope: "turn" })
3391
+ };
3392
+ function validateManagedCodexHost(input, projectDir) {
3393
+ try {
3394
+ const { approvals, ...config } = input;
3395
+ const parsed = zHost.parse(config);
3396
+ const runtime = parsed.runtime;
3397
+ if (!isAbsolute(runtime.executable) || !isAbsolute(runtime.privateDirectory)) throw refused();
3398
+ prepareNativePolicy({
3399
+ cwd: projectDir,
3400
+ privateRoot: runtime.privateRoot,
3401
+ privateDirectory: runtime.privateDirectory,
3402
+ sandboxMode: parsed.sandboxMode
3403
+ });
3404
+ const state = lstatSync(runtime.privateDirectory);
3405
+ if (!state.isDirectory() || state.isSymbolicLink() || state.mode & 63) throw refused();
3406
+ if (process.getuid && state.uid !== process.getuid()) throw refused();
3407
+ if (overlaps(realpathSync(runtime.privateDirectory), realpathSync(projectDir))) throw refused();
3408
+ if (!lstatSync(realpathSync(runtime.executable)).isFile()) throw refused();
3409
+ accessSync(runtime.executable, constants.X_OK);
3410
+ codexInstanceEnvironment(runtime.environment, runtime.privateDirectory);
3411
+ for (const key of ["HTTP_PROXY", "HTTPS_PROXY"]) {
3412
+ const value = runtime.environment[key];
3413
+ if (value && (new URL(value).username || new URL(value).password)) throw refused();
3414
+ }
3415
+ return { ...parsed, approvals: { ...approvals ?? denyNativeGrants } };
3416
+ } catch {
3417
+ throw refused();
3418
+ }
3419
+ }
3420
+ function loadManagedCodexHostConfig(file, projectDir) {
3421
+ try {
3422
+ if (!isAbsolute(file)) throw refused();
3423
+ const stat3 = lstatSync(file);
3424
+ if (!stat3.isFile() || stat3.isSymbolicLink() || stat3.size > 64 * 1024 || stat3.mode & 63)
3425
+ throw refused();
3426
+ if (process.getuid && stat3.uid !== 0 && stat3.uid !== process.getuid()) throw refused();
3427
+ if (overlaps(realpathSync(file), realpathSync(projectDir))) throw refused();
3428
+ return validateManagedCodexHost(
3429
+ zHost.parse(JSON.parse(readFileSync(file, "utf8"))),
3430
+ projectDir
3431
+ );
3432
+ } catch {
3433
+ throw refused();
3434
+ }
3435
+ }
3436
+ function bindManagedCodexInit(host, cmd, refreshCredential) {
3437
+ const profile = cmd.resolvedConfig.agentConfig;
3438
+ const credential = parseCodexCredential(cmd.credentials.ai);
3439
+ if (!profile?.authMode || !["subscription", "api-key"].includes(profile.authMode) || cmd.identity.sessionId !== host.sessionId || profile?.driver !== "codex" || profile.provider !== "openai" || profile.cloud !== void 0 && profile.cloud !== "default" || profile.cloudConfig || !profile.model || !host.subpromptModels.available.includes(profile.model) || credential.configId !== cmd.resolvedConfig.aiProviderConfigId || profile.authMode === "subscription" !== (credential.kind === "codex-subscription"))
3440
+ throw refused();
3441
+ const reasoningEffort = profile.effort ?? host.reasoningEffort;
3442
+ if (!["minimal", "low", "medium", "high", "xhigh"].includes(reasoningEffort)) throw refused();
3443
+ return {
3444
+ runtime: {
3445
+ ...host.runtime,
3446
+ credential,
3447
+ ...credential.kind === "codex-subscription" ? { refreshCredential } : {}
3448
+ },
3449
+ approvals: host.approvals ?? denyNativeGrants,
3450
+ requiredTools: [...host.requiredTools],
3451
+ approvalPolicy: host.approvalPolicy,
3452
+ sandboxMode: host.sandboxMode,
3453
+ reasoningEffort,
3454
+ subpromptModels: { ...host.subpromptModels, available: [...host.subpromptModels.available] }
3455
+ };
3456
+ }
2888
3457
  var MINT_RETRY_MAX_ATTEMPTS = 3;
2889
3458
  var MINT_RETRY_BASE_DELAY_MS = 2e3;
2890
3459
  var MINT_RETRY_MAX_DELAY_MS = 5e3;
@@ -3199,8 +3768,8 @@ var CompactionGate = class {
3199
3768
  begin() {
3200
3769
  const hold = /* @__PURE__ */ Symbol("compaction");
3201
3770
  if (this.held.size === 0) {
3202
- this.opened = new Promise((resolve4) => {
3203
- this.release = resolve4;
3771
+ this.opened = new Promise((resolve5) => {
3772
+ this.release = resolve5;
3204
3773
  });
3205
3774
  }
3206
3775
  this.held.add(hold);
@@ -3253,8 +3822,8 @@ var CompactionGate = class {
3253
3822
  };
3254
3823
  async function raceDeadline(opened, ms) {
3255
3824
  let timer;
3256
- const expired = new Promise((resolve4) => {
3257
- timer = setTimeout(() => resolve4("timeout"), ms);
3825
+ const expired = new Promise((resolve5) => {
3826
+ timer = setTimeout(() => resolve5("timeout"), ms);
3258
3827
  timer.unref?.();
3259
3828
  });
3260
3829
  try {
@@ -3292,8 +3861,8 @@ var DriverSwapGate = class {
3292
3861
  */
3293
3862
  beginTurn() {
3294
3863
  let resolveTurn;
3295
- const turn = new Promise((resolve4) => {
3296
- resolveTurn = resolve4;
3864
+ const turn = new Promise((resolve5) => {
3865
+ resolveTurn = resolve5;
3297
3866
  });
3298
3867
  this.turnTail = this.turnTail.then(() => turn);
3299
3868
  let ended = false;
@@ -3481,12 +4050,12 @@ tighter prose, never from leaving material out.`;
3481
4050
  var ABORT_SETTLE_GRACE_MS = 5e3;
3482
4051
  var MAX_CARRIED_SUMMARY_CHARS = 24e3;
3483
4052
  var MAX_FAILURE_DIAGNOSTIC_CHARS = 4e3;
3484
- function truncateTo(text, max) {
3485
- if (text.length <= max) return text;
3486
- return `${text.slice(0, max)}... [truncated]`;
4053
+ function truncateTo(text2, max) {
4054
+ if (text2.length <= max) return text2;
4055
+ return `${text2.slice(0, max)}... [truncated]`;
3487
4056
  }
3488
- function truncateDiagnostic(text) {
3489
- return truncateTo(text, MAX_FAILURE_DIAGNOSTIC_CHARS);
4057
+ function truncateDiagnostic(text2) {
4058
+ return truncateTo(text2, MAX_FAILURE_DIAGNOSTIC_CHARS);
3490
4059
  }
3491
4060
  var RATE_LIMIT_TEXT_MAX_CHARS = 1500;
3492
4061
  var RATE_LIMIT_TEXT_PATTERNS = [
@@ -3510,14 +4079,14 @@ function resolveContextWindow(driverWindow, model) {
3510
4079
  }
3511
4080
  return driverWindow || DEFAULT_CONTEXT_WINDOW;
3512
4081
  }
3513
- function detectRateLimitInSummary(text) {
3514
- if (text.length > RATE_LIMIT_TEXT_MAX_CHARS) return false;
3515
- return RATE_LIMIT_TEXT_PATTERNS.some((p) => p.test(text));
4082
+ function detectRateLimitInSummary(text2) {
4083
+ if (text2.length > RATE_LIMIT_TEXT_MAX_CHARS) return false;
4084
+ return RATE_LIMIT_TEXT_PATTERNS.some((p) => p.test(text2));
3516
4085
  }
3517
- function validateCompactionOutput(text, tokensBefore, tokensAfter) {
3518
- if (!text.trim()) return { ok: false, errorCode: "empty" };
3519
- if (detectRateLimitInSummary(text)) return { ok: false, errorCode: "rate_limit" };
3520
- if (text.length < MIN_SUMMARY_CHARS) return { ok: false, errorCode: "too_short" };
4086
+ function validateCompactionOutput(text2, tokensBefore, tokensAfter) {
4087
+ if (!text2.trim()) return { ok: false, errorCode: "empty" };
4088
+ if (detectRateLimitInSummary(text2)) return { ok: false, errorCode: "rate_limit" };
4089
+ if (text2.length < MIN_SUMMARY_CHARS) return { ok: false, errorCode: "too_short" };
3521
4090
  if (tokensBefore > 0 && tokensAfter / tokensBefore > MAX_COMPRESSION_RATIO) {
3522
4091
  return { ok: false, errorCode: "poor_ratio" };
3523
4092
  }
@@ -3775,8 +4344,8 @@ var CompactionOrchestrator = class {
3775
4344
  try {
3776
4345
  this.driver.on("agent-event", captureHandler);
3777
4346
  const running = this.driver.prompt(prompt);
3778
- const expiry = new Promise((resolve4) => {
3779
- timer = setTimeout(() => resolve4("expired"), timeoutMs);
4347
+ const expiry = new Promise((resolve5) => {
4348
+ timer = setTimeout(() => resolve5("expired"), timeoutMs);
3780
4349
  });
3781
4350
  const outcome = await Promise.race([running.then(() => "settled"), expiry]);
3782
4351
  if (outcome === "expired") {
@@ -3792,8 +4361,8 @@ var CompactionOrchestrator = class {
3792
4361
  this.opts.onLog?.(`[compaction] abort after timeout failed: ${String(abortErr)}`);
3793
4362
  });
3794
4363
  let settleTimer;
3795
- const graceExpired = new Promise((resolve4) => {
3796
- settleTimer = setTimeout(resolve4, ABORT_SETTLE_GRACE_MS);
4364
+ const graceExpired = new Promise((resolve5) => {
4365
+ settleTimer = setTimeout(resolve5, ABORT_SETTLE_GRACE_MS);
3797
4366
  settleTimer.unref?.();
3798
4367
  });
3799
4368
  await Promise.race([Promise.all([aborted, settled]), graceExpired]);
@@ -4204,8 +4773,8 @@ function toPreMinted(token) {
4204
4773
  function buildSessionResourceHandlers(deps) {
4205
4774
  const { getResourceManager, getPreMintedSecrets, emitResourcesAvailable, log, getProjectDir } = deps;
4206
4775
  async function add(kind, input) {
4207
- const rm2 = getResourceManager();
4208
- if (!rm2) return { ok: false, code: "no_session", message: "session resources not ready" };
4776
+ const rm3 = getResourceManager();
4777
+ if (!rm3) return { ok: false, code: "no_session", message: "session resources not ready" };
4209
4778
  const decl = asDeclaration(input.declaration);
4210
4779
  if (!decl) {
4211
4780
  return { ok: false, code: "invalid_declaration", message: "declaration missing id/driver" };
@@ -4219,7 +4788,7 @@ function buildSessionResourceHandlers(deps) {
4219
4788
  );
4220
4789
  }
4221
4790
  try {
4222
- await rm2.connect(decl);
4791
+ await rm3.connect(decl);
4223
4792
  } catch (err) {
4224
4793
  if (input.preMintedToken) {
4225
4794
  getPreMintedSecrets()?.unset(kind, decl.id);
@@ -4256,8 +4825,8 @@ function buildSessionResourceHandlers(deps) {
4256
4825
  message: `no materialized connector at ${join(root, name)}`
4257
4826
  };
4258
4827
  }
4259
- const rm2 = getResourceManager();
4260
- if (!rm2) return { ok: false, code: "no_session", message: "session resources not ready" };
4828
+ const rm3 = getResourceManager();
4829
+ if (!rm3) return { ok: false, code: "no_session", message: "session resources not ready" };
4261
4830
  if (preMintedToken) {
4262
4831
  const ps = getPreMintedSecrets();
4263
4832
  if (ps) ps.set("connector", decl.id, toPreMinted(preMintedToken));
@@ -4267,7 +4836,7 @@ function buildSessionResourceHandlers(deps) {
4267
4836
  );
4268
4837
  }
4269
4838
  try {
4270
- await rm2.connect(decl);
4839
+ await rm3.connect(decl);
4271
4840
  } catch (err) {
4272
4841
  if (preMintedToken) {
4273
4842
  getPreMintedSecrets()?.unset("connector", decl.id);
@@ -4285,13 +4854,13 @@ function buildSessionResourceHandlers(deps) {
4285
4854
  addMount: (input) => add("mount", input),
4286
4855
  attachConnectorInstance,
4287
4856
  removeResource: async (input) => {
4288
- const rm2 = getResourceManager();
4289
- if (!rm2) return { ok: false, code: "no_session", message: "session resources not ready" };
4290
- if (!rm2.has(input.id)) {
4857
+ const rm3 = getResourceManager();
4858
+ if (!rm3) return { ok: false, code: "no_session", message: "session resources not ready" };
4859
+ if (!rm3.has(input.id)) {
4291
4860
  return { ok: false, code: "not_found", message: `no resource with id ${input.id}` };
4292
4861
  }
4293
4862
  try {
4294
- await rm2.disconnect(input.id);
4863
+ await rm3.disconnect(input.id);
4295
4864
  } catch (err) {
4296
4865
  const message = err instanceof Error ? err.message : String(err);
4297
4866
  log(`[session-resource] runner.remove_resource failed for ${input.id}: ${message}`);
@@ -4307,8 +4876,8 @@ function buildSessionResourceHandlers(deps) {
4307
4876
  updateCredential: async (input) => {
4308
4877
  const ps = getPreMintedSecrets();
4309
4878
  if (!ps) return { ok: false, code: "no_session", message: "session resources not ready" };
4310
- const rm2 = getResourceManager();
4311
- if (rm2 && !rm2.has(input.id)) {
4879
+ const rm3 = getResourceManager();
4880
+ if (rm3 && !rm3.has(input.id)) {
4312
4881
  return { ok: false, code: "not_found", message: `no resource with id ${input.id}` };
4313
4882
  }
4314
4883
  ps.set(input.kind, input.id, input.mint);
@@ -4429,54 +4998,54 @@ function notImplemented(name) {
4429
4998
  message: `${name} handler not configured`
4430
4999
  };
4431
5000
  }
4432
- var requiredUnknown = z6.unknown().refine(() => true);
4433
- var preMintedTokenSchema = z6.object({
4434
- token: z6.string(),
4435
- expiresAt: z6.string().nullable().optional()
5001
+ var requiredUnknown = z7.unknown().refine(() => true);
5002
+ var preMintedTokenSchema = z7.object({
5003
+ token: z7.string(),
5004
+ expiresAt: z7.string().nullable().optional()
4436
5005
  }).optional();
4437
- var mountDeclarationInput = z6.strictObject({
5006
+ var mountDeclarationInput = z7.strictObject({
4438
5007
  declaration: requiredUnknown,
4439
5008
  preMintedToken: preMintedTokenSchema,
4440
5009
  // The platform attaches a workspace-migration directive on add_mount; the
4441
5010
  // handler ignores it for now (replace-workspace hot-migration is a follow-up).
4442
5011
  // Accepted here so a real platform add_mount payload validates.
4443
- migration: z6.unknown().optional()
5012
+ migration: z7.unknown().optional()
4444
5013
  });
4445
- var connectorDeclarationInput = z6.strictObject({
5014
+ var connectorDeclarationInput = z7.strictObject({
4446
5015
  declaration: requiredUnknown,
4447
5016
  preMintedToken: preMintedTokenSchema
4448
5017
  });
4449
- var addMcpServerInputSchema = z6.strictObject({
5018
+ var addMcpServerInputSchema = z7.strictObject({
4450
5019
  declaration: requiredUnknown,
4451
5020
  preMintedToken: preMintedTokenSchema
4452
5021
  });
4453
- var attachInstanceInputSchema = z6.strictObject({
4454
- kind: z6.string(),
4455
- name: z6.string(),
5022
+ var attachInstanceInputSchema = z7.strictObject({
5023
+ kind: z7.string(),
5024
+ name: z7.string(),
4456
5025
  preMintedToken: preMintedTokenSchema
4457
5026
  });
4458
- var removeResourceInput = z6.strictObject({
4459
- id: z6.string()
5027
+ var removeResourceInput = z7.strictObject({
5028
+ id: z7.string()
4460
5029
  });
4461
- var updateCredentialInput = z6.strictObject({
4462
- kind: z6.enum(["mount", "connector"]),
4463
- id: z6.string(),
5030
+ var updateCredentialInput = z7.strictObject({
5031
+ kind: z7.enum(["mount", "connector"]),
5032
+ id: z7.string(),
4464
5033
  // `CredentialMint` is a discriminated union from `@skaile/workspaces/types`.
4465
5034
  // We accept it as `z.unknown()` here because Zod can't easily mirror
4466
5035
  // a discriminated TypeScript union without duplicating the schema —
4467
5036
  // the platform side has already validated the shape before sending.
4468
5037
  mint: requiredUnknown
4469
5038
  });
4470
- var setLogLevelInput = z6.strictObject({
4471
- level: z6.enum(["silent", "error", "warn", "info", "debug", "trace"])
5039
+ var setLogLevelInput = z7.strictObject({
5040
+ level: z7.enum(["silent", "error", "warn", "info", "debug", "trace"])
4472
5041
  });
4473
- var setStateInput = z6.strictObject({
4474
- store: z6.string(),
4475
- key: z6.string(),
5042
+ var setStateInput = z7.strictObject({
5043
+ store: z7.string(),
5044
+ key: z7.string(),
4476
5045
  value: requiredUnknown
4477
5046
  });
4478
- var lifecycleInput = z6.strictObject({
4479
- phase: z6.enum(["hibernate", "close", "compact"])
5047
+ var lifecycleInput = z7.strictObject({
5048
+ phase: z7.enum(["hibernate", "close", "compact"])
4480
5049
  });
4481
5050
  var VALID_LOG_STORE_LEVELS = /* @__PURE__ */ new Set(["debug", "info", "warn", "error"]);
4482
5051
  function buildRunnerCapabilities(handlers) {
@@ -4774,9 +5343,9 @@ function createSessionStimulusBus(opts) {
4774
5343
  connectorId,
4775
5344
  fragmentLength: sig.promptFragment.length
4776
5345
  });
4777
- return new Promise((resolve4, reject) => {
5346
+ return new Promise((resolve5, reject) => {
4778
5347
  const q = getQueue(connectorId);
4779
- q.pending.push({ signal: sig, resolve: resolve4, reject });
5348
+ q.pending.push({ signal: sig, resolve: resolve5, reject });
4780
5349
  startTimerIfNeeded(connectorId, q, coalesceMs);
4781
5350
  });
4782
5351
  }
@@ -4861,6 +5430,9 @@ function pickRepointedManager(next, current, disposed) {
4861
5430
  if (current !== null && current === disposed) return null;
4862
5431
  return current;
4863
5432
  }
5433
+ function supportsLiveToolUpdates(driverType, managedCodex = false) {
5434
+ return driverType !== "claude-sdk" && !(driverType === "codex" && managedCodex);
5435
+ }
4864
5436
  function buildResourcesAvailablePayload(manager, mcpManager, driverLive, bakedServerIds) {
4865
5437
  const { mounts, connectors } = splitConnectorsForWire(manager);
4866
5438
  const mcp_servers = (mcpManager?.listServers() ?? []).map((s) => ({
@@ -5106,19 +5678,19 @@ function createFlowConnectorReadiness(isReady) {
5106
5678
  wait(timeoutMs, isSatisfied) {
5107
5679
  const satisfied = isSatisfied ?? isReady;
5108
5680
  if (satisfied()) return Promise.resolve(true);
5109
- return new Promise((resolve4) => {
5681
+ return new Promise((resolve5) => {
5110
5682
  let timer;
5111
5683
  const waiter = {
5112
5684
  satisfied,
5113
5685
  release: () => {
5114
5686
  clearTimeout(timer);
5115
- resolve4(true);
5687
+ resolve5(true);
5116
5688
  }
5117
5689
  };
5118
5690
  timer = setTimeout(() => {
5119
5691
  const idx = waiters.indexOf(waiter);
5120
5692
  if (idx >= 0) waiters.splice(idx, 1);
5121
- resolve4(false);
5693
+ resolve5(false);
5122
5694
  }, timeoutMs);
5123
5695
  timer.unref?.();
5124
5696
  waiters.push(waiter);
@@ -5469,10 +6041,20 @@ function stimulusFromMetas(metas) {
5469
6041
  return { kind: "state_changed" };
5470
6042
  }
5471
6043
  async function startAgentServer(opts) {
6044
+ const managedHost = opts.managedCodex ? validateManagedCodexHost(opts.managedCodex, opts.projectDir) : void 0;
6045
+ if (managedHost && opts.sessionId && opts.sessionId !== managedHost.sessionId)
6046
+ throw new Error("CODEX_MANAGED_BOOTSTRAP_INVALID");
6047
+ const authToken = opts.authToken ?? process.env.SKAILE_WS_AUTH_TOKEN;
6048
+ if (managedHost && !opts.transport && !authToken)
6049
+ throw new Error("CODEX_MANAGED_BOOTSTRAP_INVALID");
6050
+ const supportedRuntimeFeatures = managedHost ? ["codex-app-server-v1"] : [];
6051
+ let managedBootstrapClosed = false;
5472
6052
  const port = opts.port ?? 8080;
5473
- const sessionId = opts.sessionId ?? process.env.SKAILE_SESSION_ID ?? "session-unknown";
6053
+ const sessionId = managedHost?.sessionId ?? opts.sessionId ?? process.env.SKAILE_SESSION_ID ?? "session-unknown";
5474
6054
  const resumeSessionId = opts.resumeSessionId ?? process.env.SKAILE_RESUME_SESSION_ID;
5475
6055
  const wsConfig = resolveSkWorkspaceConfig(opts.projectDir);
6056
+ if (managedHost && wsConfig.agent?.["prompt-extensions"]?.length)
6057
+ throw new Error("CODEX_MANAGED_PROMPT_EXTENSIONS_UNSUPPORTED");
5476
6058
  const { store: logStore, dispose: disposeLogStore } = bootstrapRunnerLogStore({
5477
6059
  sessionId,
5478
6060
  projectDir: opts.projectDir,
@@ -5498,7 +6080,6 @@ async function startAgentServer(opts) {
5498
6080
  } else {
5499
6081
  serverLog.warn("no agent definition found in skaile.yaml");
5500
6082
  }
5501
- const authToken = opts.authToken ?? process.env.SKAILE_WS_AUTH_TOKEN;
5502
6083
  const transport = opts.transport ?? new WebSocketServerTransport({ port, onLog: log, ...authToken ? { authToken } : {} });
5503
6084
  logStore.addSink(
5504
6085
  new WsLogSink({
@@ -5521,30 +6102,45 @@ async function startAgentServer(opts) {
5521
6102
  );
5522
6103
  bootstrapCapabilityRegistry(capabilityRegistry);
5523
6104
  const pendingCapabilityCalls = /* @__PURE__ */ new Map();
5524
- const remoteCapabilityInvoker = (name, input, timeoutMs) => {
6105
+ const remoteCapabilityInvoker = (name, input, timeoutMs, signal) => {
5525
6106
  const callId = typeof crypto?.randomUUID === "function" ? crypto.randomUUID() : `rcap-${Date.now()}-${Math.floor(Math.random() * 1e9)}`;
5526
- return new Promise((resolve4, reject) => {
6107
+ return new Promise((resolve5, reject) => {
5527
6108
  if (!transport.connected) {
5528
6109
  reject(new Error(`Transport disconnected; cannot invoke remote capability ${name}`));
5529
6110
  return;
5530
6111
  }
5531
- const timer = setTimeout(() => {
6112
+ if (signal?.aborted) {
6113
+ reject(signal.reason);
6114
+ return;
6115
+ }
6116
+ const finish = (error, value) => {
6117
+ clearTimeout(timer);
6118
+ signal?.removeEventListener("abort", abort);
5532
6119
  pendingCapabilityCalls.delete(callId);
5533
- reject(new Error(`Remote capability ${name} (callId=${callId}) timed out`));
5534
- }, timeoutMs ?? DEFAULT_CAPABILITY_CALL_TIMEOUT_MS);
5535
- pendingCapabilityCalls.set(callId, { resolve: resolve4, reject, timer });
5536
- transport.send({
5537
- type: "capability_invoked",
5538
- callId,
5539
- name,
5540
- input,
5541
- invokedBy: "agent"
6120
+ if (error) reject(error);
6121
+ else resolve5(value);
6122
+ };
6123
+ const abort = () => finish(signal?.reason ?? new Error("Remote capability aborted"));
6124
+ const timer = setTimeout(
6125
+ () => finish(new Error(`Remote capability ${name} (callId=${callId}) timed out`)),
6126
+ timeoutMs ?? DEFAULT_CAPABILITY_CALL_TIMEOUT_MS
6127
+ );
6128
+ pendingCapabilityCalls.set(callId, {
6129
+ resolve: (value) => finish(null, value),
6130
+ reject: (error) => finish(error),
6131
+ timer
5542
6132
  });
6133
+ signal?.addEventListener("abort", abort, { once: true });
6134
+ try {
6135
+ transport.send({ type: "capability_invoked", callId, name, input, invokedBy: "agent" });
6136
+ } catch (error) {
6137
+ finish(error);
6138
+ }
5543
6139
  });
5544
6140
  };
5545
6141
  let aiProviderConfigId;
5546
- const sleep = (ms) => new Promise((resolve4) => {
5547
- const t = setTimeout(resolve4, ms);
6142
+ const sleep = (ms) => new Promise((resolve5) => {
6143
+ const t = setTimeout(resolve5, ms);
5548
6144
  t.unref?.();
5549
6145
  });
5550
6146
  async function mintAndPersistAiCredential(args) {
@@ -5695,11 +6291,12 @@ async function startAgentServer(opts) {
5695
6291
  if (!cap) return null;
5696
6292
  return capabilityRegistry.list().find((c) => c.name === name) ?? null;
5697
6293
  },
5698
- invoke: (name, input) => capabilityRegistry.invoke(name, input, { sessionId }),
6294
+ invoke: (name, input, signal) => capabilityRegistry.invoke(name, input, { sessionId, signal }),
6295
+ onToolsChanged: (listener) => capabilityRegistry.onToolsChanged(listener),
5699
6296
  emitRender: (event) => sendEvent(event),
5700
- emitText: (text) => sendEvent({
6297
+ emitText: (text2) => sendEvent({
5701
6298
  type: "text",
5702
- content: text
6299
+ content: text2
5703
6300
  })
5704
6301
  };
5705
6302
  }
@@ -5711,7 +6308,7 @@ async function startAgentServer(opts) {
5711
6308
  );
5712
6309
  }
5713
6310
  }
5714
- const secretsMode = wsConfig.secrets?.provider ?? "env";
6311
+ const secretsMode = managedHost ? "provisioned" : wsConfig.secrets?.provider ?? "env";
5715
6312
  wsConfig.secrets?.timeoutMs ?? 3e4;
5716
6313
  const rawCloud = profile?.cloud ?? "default";
5717
6314
  const effectiveCloud = SUPPORTED_CLOUDS.includes(rawCloud) ? rawCloud : "default";
@@ -5723,6 +6320,7 @@ async function startAgentServer(opts) {
5723
6320
  const effectiveCloudConfig = cloudConfigFromProfile(profile);
5724
6321
  const diskProfileHasAgentSettings = (p) => !!p && !!(p.driver || p.provider || p.model || p.cloud || p.cloud_config || p.thinking || p.effort);
5725
6322
  function resolveEffectiveCloudForSession() {
6323
+ if (managedCodex) return { cloud: "default" };
5726
6324
  if (effectiveCloud !== "default" || !wireAgentConfig) {
5727
6325
  return { cloud: effectiveCloud, cloudConfig: effectiveCloudConfig };
5728
6326
  }
@@ -5735,17 +6333,18 @@ async function startAgentServer(opts) {
5735
6333
  return {
5736
6334
  projectDir: opts.projectDir,
5737
6335
  agentDir,
5738
- driver: opts.driver ?? wireAgentConfig?.driver,
5739
- model: opts.model ?? wireAgentConfig?.model,
5740
- provider: opts.provider ?? wireAgentConfig?.provider,
6336
+ driver: managedCodex ? "codex" : opts.driver ?? wireAgentConfig?.driver,
6337
+ model: managedCodex ? wireAgentConfig?.model : opts.model ?? wireAgentConfig?.model,
6338
+ provider: managedCodex ? "openai" : opts.provider ?? wireAgentConfig?.provider,
5741
6339
  promptsDir: opts.promptsDir,
5742
6340
  sessionId,
5743
- resumeSessionId,
6341
+ resumeSessionId: managedCodex ? void 0 : resumeSessionId,
6342
+ ...managedCodex ? { managedCodex } : {},
5744
6343
  maxTurns,
5745
6344
  wsConfig,
5746
- externalPromptFile: process.env.SKAILE_SYSTEM_PROMPT_FILE,
6345
+ externalPromptFile: managedCodex ? void 0 : process.env.SKAILE_SYSTEM_PROMPT_FILE,
5747
6346
  secretProvider: secretProvider2,
5748
- onAuthError,
6347
+ onAuthError: managedCodex ? void 0 : onAuthError,
5749
6348
  onLimitBlocked,
5750
6349
  onProviderResponse,
5751
6350
  ...apiKey ? { apiKey } : {},
@@ -5830,8 +6429,8 @@ async function startAgentServer(opts) {
5830
6429
  }
5831
6430
  let resolveSessionReady;
5832
6431
  let rejectSessionReady;
5833
- const sessionReady = new Promise((resolve4, reject) => {
5834
- resolveSessionReady = resolve4;
6432
+ const sessionReady = new Promise((resolve5, reject) => {
6433
+ resolveSessionReady = resolve5;
5835
6434
  rejectSessionReady = reject;
5836
6435
  });
5837
6436
  let sessionConfig;
@@ -5841,10 +6440,14 @@ async function startAgentServer(opts) {
5841
6440
  let preMintedSecrets;
5842
6441
  const liveAttachedMcpDeclarations = /* @__PURE__ */ new Map();
5843
6442
  let wireAgentConfig;
6443
+ let managedCodex;
6444
+ let managedInitFingerprint;
6445
+ let managedInitComplete = false;
5844
6446
  let appliedWireAgentConfigKey;
5845
6447
  const stagedSkillDirs = /* @__PURE__ */ new Set();
5846
6448
  await restageMaterializedSkills(false);
5847
6449
  async function restageMaterializedSkills(allowRestart) {
6450
+ if (managedHost) return;
5848
6451
  try {
5849
6452
  const { skillsDir } = resolveDriverPaths({
5850
6453
  driver: opts.driver ?? wsConfig.agent_config?.default?.driver ?? wireAgentConfig?.driver ?? "claude-sdk"
@@ -5894,7 +6497,7 @@ async function startAgentServer(opts) {
5894
6497
  captureBakedMcpServers();
5895
6498
  }
5896
6499
  let resourceManager = secretsMode === "env" ? agentSession.resourceManager : null;
5897
- const driverPicksUpToolsLive = () => agentSession?.driverType !== "claude-sdk";
6500
+ const driverPicksUpToolsLive = () => supportsLiveToolUpdates(agentSession?.driverType, !!sessionConfig?.managedCodex);
5898
6501
  const emitResourcesAvailable = () => sendEvent(
5899
6502
  buildResourcesAvailablePayload(
5900
6503
  resourceManager,
@@ -6079,6 +6682,7 @@ async function startAgentServer(opts) {
6079
6682
  rebuildCompactionOrchestrator();
6080
6683
  }
6081
6684
  const activeFlows = /* @__PURE__ */ new Map();
6685
+ let removeCodexFlowTools;
6082
6686
  let stimulusBus = null;
6083
6687
  const FLOW_TURN_TIMEOUT_MS = 4 * 60 * 60 * 1e3;
6084
6688
  function getOnlyActiveFlow() {
@@ -6151,7 +6755,7 @@ async function startAgentServer(opts) {
6151
6755
  return stimulusBus;
6152
6756
  }
6153
6757
  function awaitFlowAgentEnd(prompt, timeoutMs) {
6154
- return new Promise((resolve4, reject) => {
6758
+ return new Promise((resolve5, reject) => {
6155
6759
  let settled = false;
6156
6760
  const onEvent = (event) => {
6157
6761
  if (event.type === "agent_end") done();
@@ -6169,7 +6773,7 @@ async function startAgentServer(opts) {
6169
6773
  onEvent
6170
6774
  ) ?? driver.removeListener("agent-event", onEvent);
6171
6775
  if (err) reject(err);
6172
- else resolve4();
6776
+ else resolve5();
6173
6777
  };
6174
6778
  const timer = setTimeout(
6175
6779
  () => done(new Error(`Flow turn timed out after ${timeoutMs / 1e3}s`)),
@@ -6202,6 +6806,8 @@ async function startAgentServer(opts) {
6202
6806
  async function createActiveFlow(flowDef, seedOrExecution) {
6203
6807
  const bus = getOrCreateStimulusBus();
6204
6808
  const nodeExecutor = new SessionNodeExecutor({ workspaceDir: opts.projectDir });
6809
+ const managedSubprompts = sessionConfig.managedCodex?.subpromptModels;
6810
+ if (sessionConfig.managedCodex && !managedSubprompts) throw new Error("AI_PROFILE_INVALID");
6205
6811
  const subpromptRunner = new SessionSubpromptRunner({
6206
6812
  driverType: agentSession.driverType,
6207
6813
  provider: agentSession.provider,
@@ -6210,7 +6816,34 @@ async function startAgentServer(opts) {
6210
6816
  apiKey: sessionConfig.apiKey,
6211
6817
  cloud: sessionConfig.cloud,
6212
6818
  cloudConfig: sessionConfig.cloudConfig,
6213
- cloudSecrets: sessionConfig.cloudSecrets
6819
+ cloudSecrets: sessionConfig.cloudSecrets,
6820
+ ...managedSubprompts ? {
6821
+ modelTierOverrides: {
6822
+ small: managedSubprompts.small,
6823
+ default: agentSession.model,
6824
+ deep: managedSubprompts.deep
6825
+ },
6826
+ availableModels: managedSubprompts.available,
6827
+ createIsolatedDriver: async (model) => {
6828
+ const parentPrivate = sessionConfig.managedCodex.runtime.privateDirectory;
6829
+ const privateDirectory = await mkdtemp(join(dirname(parentPrivate), ".subprompt-"));
6830
+ try {
6831
+ const child = await createManagedCodexSubpromptDriver(
6832
+ sessionConfig,
6833
+ model,
6834
+ opts.projectDir,
6835
+ privateDirectory
6836
+ );
6837
+ return {
6838
+ driver: child,
6839
+ dispose: () => rm(privateDirectory, { recursive: true, force: true })
6840
+ };
6841
+ } catch (error) {
6842
+ await rm(privateDirectory, { recursive: true, force: true });
6843
+ throw error;
6844
+ }
6845
+ }
6846
+ } : {}
6214
6847
  });
6215
6848
  const inlineSubFlowRunner = new SessionInlineSubFlowRunner({
6216
6849
  resolveFlow: (flowId) => loadFlow(resolveFlowPath(flowId, opts.projectDir)),
@@ -6286,6 +6919,10 @@ async function startAgentServer(opts) {
6286
6919
  log(`[serve] failed to rebuild MCP tools for flow: ${errMsg}`);
6287
6920
  }
6288
6921
  }
6922
+ if (agentSession?.driverType === "codex" && !driver.acceptsReplyAsPrompt) {
6923
+ removeCodexFlowTools?.();
6924
+ removeCodexFlowTools = registerCodexFlowTools(capabilityRegistry, manager, connectorId);
6925
+ }
6289
6926
  emitAvailability();
6290
6927
  const entry = {
6291
6928
  runId,
@@ -6351,18 +6988,20 @@ async function startAgentServer(opts) {
6351
6988
  });
6352
6989
  }
6353
6990
  async function cleanup() {
6991
+ if (managedHost) managedBootstrapClosed = true;
6354
6992
  try {
6355
6993
  await Promise.race([
6356
6994
  sessionReady,
6357
- new Promise((resolve4) => {
6358
- const t = setTimeout(resolve4, 2e3);
6995
+ new Promise((resolve5) => {
6996
+ const t = setTimeout(resolve5, 2e3);
6359
6997
  t.unref?.();
6360
6998
  })
6361
6999
  ]);
6362
7000
  } catch {
6363
7001
  }
6364
7002
  try {
6365
- driver?.kill();
7003
+ if (managedHost) await driver?.dispose();
7004
+ else driver?.kill();
6366
7005
  } catch {
6367
7006
  }
6368
7007
  aiCredentialRefreshScheduler.cancel();
@@ -6453,11 +7092,11 @@ async function startAgentServer(opts) {
6453
7092
  let apiKeyFromSecrets;
6454
7093
  let cloudSecrets;
6455
7094
  const { cloud: initCloud } = resolveEffectiveCloudForSession();
6456
- if (initCloud === "default") {
7095
+ if (!managedCodex && initCloud === "default") {
6457
7096
  const effectiveProvider = opts.provider ?? wireAgentConfig?.provider ?? "anthropic";
6458
7097
  const envKey = providerEnvKey(effectiveProvider);
6459
7098
  apiKeyFromSecrets = secrets?.[envKey];
6460
- } else {
7099
+ } else if (!managedCodex) {
6461
7100
  ({ cloudSecrets } = resolveCloudSecretBundle({
6462
7101
  cloud: initCloud,
6463
7102
  secrets,
@@ -6473,7 +7112,12 @@ async function startAgentServer(opts) {
6473
7112
  let needsWireFallbackRecreate = false;
6474
7113
  const agentSessionExistedBeforeThisInit = !!agentSession;
6475
7114
  if (!agentSession) {
7115
+ if (managedHost && managedBootstrapClosed) throw new Error("CODEX_RUNTIME_UNSUPPORTED");
6476
7116
  agentSession = await createAgentSession(sessionConfig);
7117
+ if (managedHost && managedBootstrapClosed) {
7118
+ await agentSession.dispose();
7119
+ throw new Error("CODEX_RUNTIME_UNSUPPORTED");
7120
+ }
6477
7121
  emitSystemPromptComposed(agentSession, sendEvent);
6478
7122
  resourceManager = agentSession.resourceManager;
6479
7123
  driver = agentSession.driver;
@@ -6519,8 +7163,8 @@ async function startAgentServer(opts) {
6519
7163
  async function recreateAgentSession(overrides) {
6520
7164
  let markSwapDone;
6521
7165
  driverSwapGate.beginSwap(
6522
- new Promise((resolve4) => {
6523
- markSwapDone = resolve4;
7166
+ new Promise((resolve5) => {
7167
+ markSwapDone = resolve5;
6524
7168
  })
6525
7169
  );
6526
7170
  try {
@@ -6534,8 +7178,13 @@ async function startAgentServer(opts) {
6534
7178
  const disposedManager = agentSession.resourceManager;
6535
7179
  const disposeStartedAt = Date.now();
6536
7180
  await agentSession.dispose();
7181
+ if (managedHost && managedBootstrapClosed) throw new Error("CODEX_RUNTIME_UNSUPPORTED");
6537
7182
  const createStartedAt = Date.now();
6538
7183
  agentSession = await createAgentSession({ ...sessionConfig, ...overrides });
7184
+ if (managedHost && managedBootstrapClosed) {
7185
+ await agentSession.dispose();
7186
+ throw new Error("CODEX_RUNTIME_UNSUPPORTED");
7187
+ }
6539
7188
  logPhase("session_rebuild", disposeStartedAt, {
6540
7189
  disposeMs: createStartedAt - disposeStartedAt,
6541
7190
  createMs: Date.now() - createStartedAt,
@@ -6676,7 +7325,7 @@ async function startAgentServer(opts) {
6676
7325
  log(`[serve] aiResources catalog actions: ${catalogActions.length}`);
6677
7326
  try {
6678
7327
  const skillsDir = join(sessionConfig.projectDir ?? process.cwd(), ".claude", "skills");
6679
- const assetsRoot = process.env.SKAILE_ASSETS_ROOT ?? await findAiAssetsRoot(sessionConfig.projectDir ?? process.cwd()) ?? "/app/ai-assets";
7328
+ const assetsRoot = process.env.SKAILE_ASSETS_ROOT ?? await findAiAssetsRoot$1(sessionConfig.projectDir ?? process.cwd()) ?? "/app/ai-assets";
6680
7329
  for (const res of catalogActions) {
6681
7330
  await applyCatalogAction(res, { assetsRoot, skillsDir });
6682
7331
  }
@@ -6790,7 +7439,53 @@ async function startAgentServer(opts) {
6790
7439
  return;
6791
7440
  }
6792
7441
  try {
6793
- validateCodexInit(cmd, [], runtimeIdentity ?? void 0);
7442
+ validateCodexInit(cmd, supportedRuntimeFeatures, runtimeIdentity ?? void 0);
7443
+ const wantsManaged = cmd.resolvedConfig.agentConfig?.driver === "codex";
7444
+ if (managedHost && !wantsManaged) throw new Error("AI_PROFILE_INVALID");
7445
+ if (managedHost && wantsManaged) {
7446
+ if (managedBootstrapClosed || agentSession && !managedInitFingerprint || cmd.secrets && CLAUDE_CODE_CREDENTIALS_KEY in cmd.secrets)
7447
+ throw new Error("AI_PROFILE_INVALID");
7448
+ const profile2 = cmd.resolvedConfig.agentConfig;
7449
+ if (opts.driver && opts.driver !== "codex" || opts.provider && opts.provider !== "openai" || opts.model && opts.model !== profile2.model)
7450
+ throw new Error("AI_PROFILE_INVALID");
7451
+ const initialCredential = parseCodexCredential(cmd.credentials.ai);
7452
+ const binding = bindManagedCodexInit(managedHost, cmd, async (input, signal) => {
7453
+ signal.throwIfAborted();
7454
+ if (initialCredential.kind !== "codex-subscription")
7455
+ throw new Error("AI_PROFILE_INVALID");
7456
+ const pinned = { ...initialCredential, credentialVersion: input.credentialVersion };
7457
+ const result = await remoteCapabilityInvoker(
7458
+ "host.refresh_credential",
7459
+ parseCodexRefreshInput(input, pinned),
7460
+ void 0,
7461
+ signal
7462
+ );
7463
+ signal.throwIfAborted();
7464
+ return parseCodexRefreshResult(result, pinned);
7465
+ });
7466
+ const credential = binding.runtime.credential;
7467
+ const fingerprint = JSON.stringify([
7468
+ cmd.identity,
7469
+ // A repeated init is idempotent only for the same host capability contract.
7470
+ // Keep all policy fields, not only the narrower resume signature.
7471
+ cmd.capabilities ?? [],
7472
+ profile2,
7473
+ credential.configId,
7474
+ credential.kind,
7475
+ credential.kind === "codex-subscription" ? credential.chatgptAccountId : null
7476
+ ]);
7477
+ if (managedInitFingerprint) {
7478
+ if (managedInitFingerprint !== fingerprint) throw new Error("AI_PROFILE_INVALID");
7479
+ if (managedInitComplete)
7480
+ sendEvent({
7481
+ type: "session_init_ack",
7482
+ capabilitySignature: computeCapabilitySignature(capabilityRegistry.list())
7483
+ });
7484
+ return;
7485
+ }
7486
+ managedInitFingerprint = fingerprint;
7487
+ managedCodex = binding;
7488
+ }
6794
7489
  } catch {
6795
7490
  runtimeRejected = true;
6796
7491
  sendEvent({
@@ -6821,23 +7516,29 @@ async function startAgentServer(opts) {
6821
7516
  }
6822
7517
  runtimeIdentity = cmd.identity;
6823
7518
  registerInitClientCapabilities(cmd.capabilities ?? []);
6824
- sendEvent({ type: "protocol_info", version: PROTOCOL_VERSION });
7519
+ sendEvent({
7520
+ type: "protocol_info",
7521
+ version: PROTOCOL_VERSION,
7522
+ ...managedHost ? { runtimeFeatures: supportedRuntimeFeatures } : {}
7523
+ });
6825
7524
  preMintedSecrets = new PreMintedSecretProvider(cmd.credentials);
6826
7525
  const initialAiCredentialExpiresAt = await provisionInitSecrets(cmd.secrets);
7526
+ if (managedCodex) secretsProvisioned = true;
6827
7527
  if (cmd.resolvedConfig.aiProviderConfigId) {
6828
7528
  aiProviderConfigId = cmd.resolvedConfig.aiProviderConfigId;
6829
7529
  log(`[serve] stashed aiProviderConfigId=${aiProviderConfigId}`);
6830
7530
  }
6831
- wireAgentConfig = diskProfileHasAgentSettings(profile) ? void 0 : cmd.resolvedConfig.agentConfig ?? wireAgentConfig;
6832
- if (aiProviderConfigId && initialAiCredentialExpiresAt) {
7531
+ wireAgentConfig = managedCodex ? cmd.resolvedConfig.agentConfig : diskProfileHasAgentSettings(profile) ? void 0 : cmd.resolvedConfig.agentConfig ?? wireAgentConfig;
7532
+ if (!managedCodex && aiProviderConfigId && initialAiCredentialExpiresAt) {
6833
7533
  aiCredentialRefreshScheduler.schedule(initialAiCredentialExpiresAt);
6834
7534
  }
6835
- const resumeProbe = cmd.resume?.sessionId ? await probeResumeTranscript(cmd.resume.sessionId) : void 0;
6836
- sendEvent({
6837
- type: "session_init_ack",
6838
- capabilitySignature: computeCapabilitySignature(capabilityRegistry.list()),
6839
- ...resumeProbe ? { resumeProbe } : {}
6840
- });
7535
+ const resumeProbe = !managedCodex && cmd.resume?.sessionId ? await probeResumeTranscript(cmd.resume.sessionId) : void 0;
7536
+ if (!managedCodex)
7537
+ sendEvent({
7538
+ type: "session_init_ack",
7539
+ capabilitySignature: computeCapabilitySignature(capabilityRegistry.list()),
7540
+ ...resumeProbe ? { resumeProbe } : {}
7541
+ });
6841
7542
  const buildSession = async () => {
6842
7543
  const firstBuildStartedAt = Date.now();
6843
7544
  const { needsWireFallbackRecreate, needsWireAgentConfigRecreate } = await buildSessionFromInit(cmd.secrets, resolvedConfigToDeclarations(cmd.resolvedConfig));
@@ -6855,7 +7556,7 @@ async function startAgentServer(opts) {
6855
7556
  log(
6856
7557
  `[serve] configure cfg keys=${Object.keys(cfg).join(",")} sharedState=${cfg.sharedState ? cfg.sharedState.length : "undefined"} resourceManager=${resourceManager ? "set" : "null"}`
6857
7558
  );
6858
- if (aiProviderConfigId) {
7559
+ if (!managedCodex && aiProviderConfigId) {
6859
7560
  aiCredentialRefreshScheduler.ensureArmed();
6860
7561
  }
6861
7562
  let pendingResumeSessionId;
@@ -6901,6 +7602,33 @@ async function startAgentServer(opts) {
6901
7602
  ready: true,
6902
7603
  resumeRequested: !!cmd.resume?.sessionId
6903
7604
  });
7605
+ if (managedCodex) {
7606
+ if (managedBootstrapClosed) throw new Error("CODEX_RUNTIME_UNSUPPORTED");
7607
+ try {
7608
+ await ensureDriverStarted();
7609
+ } catch (error) {
7610
+ if (!(error instanceof CodexNativeStateUnavailable) || !pendingResumeSessionId || managedBootstrapClosed)
7611
+ throw error;
7612
+ await recreateAgentSession({ resumeSessionId: void 0 });
7613
+ if (cfg.sharedState && !await applyInitSharedState(cfg.sharedState))
7614
+ throw new Error("session_init: shared-state setup failed");
7615
+ if (cfg.aiResources) await applyInitAiResources(cfg.aiResources);
7616
+ await ensureDriverStarted();
7617
+ if (managedBootstrapClosed || !driverStarted)
7618
+ throw new Error("CODEX_RUNTIME_UNSUPPORTED");
7619
+ sendEvent({
7620
+ type: "resume_failed",
7621
+ resumeSessionId: pendingResumeSessionId,
7622
+ reason: "native_state_unavailable"
7623
+ });
7624
+ }
7625
+ if (managedBootstrapClosed || !driverStarted) throw new Error("CODEX_RUNTIME_UNSUPPORTED");
7626
+ managedInitComplete = true;
7627
+ sendEvent({
7628
+ type: "session_init_ack",
7629
+ capabilitySignature: computeCapabilitySignature(capabilityRegistry.list())
7630
+ });
7631
+ }
6904
7632
  resolveSessionReady();
6905
7633
  };
6906
7634
  void buildSession().catch((err) => {
@@ -6909,6 +7637,14 @@ async function startAgentServer(opts) {
6909
7637
  log(`[serve] session_init failed to build session: ${errMsg}`);
6910
7638
  sendEvent({ type: "error", message: errMsg, fatal: true });
6911
7639
  rejectSessionReady(err instanceof Error ? err : new Error(errMsg));
7640
+ if (managedHost) {
7641
+ runtimeRejected = true;
7642
+ void cleanup().finally(async () => {
7643
+ teardownProcessHandlers();
7644
+ disposeLogStore();
7645
+ await transport.close();
7646
+ });
7647
+ }
6912
7648
  });
6913
7649
  }
6914
7650
  const awaitCompactionIdle = (what) => guardTurnAgainstCompaction({ gate: compactionGate, what, log, sendEvent });
@@ -6973,7 +7709,7 @@ async function startAgentServer(opts) {
6973
7709
  sendEvent({ type: "status", phase: "thinking" });
6974
7710
  const endTurn = driverSwapGate.beginTurn();
6975
7711
  try {
6976
- await driver.prompt(cmd.prompt);
7712
+ await driver.promptInput({ text: cmd.prompt, attachments: cmd.attachments });
6977
7713
  } catch (err) {
6978
7714
  const errMsg = err instanceof Error ? err.message : String(err);
6979
7715
  log(`[serve] prompt failed: ${errMsg}`);
@@ -6986,7 +7722,9 @@ async function startAgentServer(opts) {
6986
7722
  if (!await awaitSessionReadyOrFail()) return;
6987
7723
  log(`[serve] reply: ${cmd.answer.slice(0, 80)}...`);
6988
7724
  await driverSwapGate.awaitSwap();
6989
- if (driver.hasPendingQuestion() && driver.answerQuestion(cmd.answer, cmd.question)) return;
7725
+ if (driver.hasPendingQuestion() && driver.answerQuestion(cmd.answer, cmd.question, cmd.requestId))
7726
+ return;
7727
+ if (!driver.acceptsReplyAsPrompt) return;
6990
7728
  if (!await awaitCompactionIdle("reply")) return;
6991
7729
  const endTurn = driverSwapGate.beginTurn();
6992
7730
  try {
@@ -7229,9 +7967,10 @@ async function startAgentServer(opts) {
7229
7967
  }
7230
7968
  }
7231
7969
  async function handleCommand(cmd) {
7232
- if (runtimeRejected) return;
7970
+ if (runtimeRejected || managedHost && managedBootstrapClosed) return;
7233
7971
  const inbound = cmd;
7234
7972
  if (isCredentialRotatedSignal(cmd)) {
7973
+ if (managedCodex) return;
7235
7974
  await handleCredentialRotatedSignal({
7236
7975
  configId: readCredentialRotatedConfigId(cmd),
7237
7976
  repull: async (configId) => (await aiProviderConfigSwitcher.repull({
@@ -7322,6 +8061,14 @@ async function startAgentServer(opts) {
7322
8061
  transport.onCommand((cmd) => {
7323
8062
  void handleCommand(cmd);
7324
8063
  });
8064
+ transport.onConnect(() => {
8065
+ if (managedHost && !managedBootstrapClosed)
8066
+ sendEvent({
8067
+ type: "protocol_info",
8068
+ version: PROTOCOL_VERSION,
8069
+ runtimeFeatures: supportedRuntimeFeatures
8070
+ });
8071
+ });
7325
8072
  await transport.listen();
7326
8073
  if (secretsMode === "env" && agentSession) {
7327
8074
  agentSession.startWatching();
@@ -7346,7 +8093,9 @@ async function startAgentServer(opts) {
7346
8093
  sendEvent({ type: "commands_available", commands });
7347
8094
  }
7348
8095
  }
7349
- transport.onConnect(emitAvailability);
8096
+ transport.onConnect(() => {
8097
+ emitAvailability();
8098
+ });
7350
8099
  async function replayStoreSnapshots() {
7351
8100
  if (!resourceManager) return;
7352
8101
  for (const event of await buildStoreSnapshotReplay(resourceManager, activeFlows.values())) {
@@ -7526,6 +8275,6 @@ function touchSession(state) {
7526
8275
  return { ...state, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
7527
8276
  }
7528
8277
 
7529
- export { CLAUDE_CODE_CREDENTIALS_KEY, COMPILE_MANIFEST_FILENAME, CapabilityRegistry, DEFAULT_CAPABILITY_CALL_TIMEOUT_MS, DEFAULT_COALESCE_MS, DEFAULT_FLOW_MUTATE_CONNECTOR_WAIT_MS, MOUNT_LIST_MAX_DEPTH, MOUNT_LIST_MAX_ENTRIES, MOUNT_READ_DEADLINE_FACTOR, MOUNT_TREE_OP_DEADLINE_FACTOR, MarkdownStreamer, PreInitRingSink, agentDefinitionExists, bootstrapCapabilityRegistry, bootstrapRunnerLogStore, buildAgentResources, buildClientCapabilityHandler, buildConnectorTokenMediator, buildContextSection, buildEnvironmentSection, buildResourcesAvailablePayload, buildStoreSnapshotReplay, builtinCapabilities, capabilityLogInstance, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, connectorRefreshKind, createAgentSession, createFlowConnectorReadiness, createSessionStimulusBus, defineCapability, deleteSession, dispatchRunnerCapabilityInvocation, emitSystemPromptComposed, ensureClaudeSettingsDisablesConnectors, ensureGitConfigInclude, executeConnectorMutate, extractClaudeAiOauthExpiresAt, getPreInitRingSink, handleMountResourceRequest, handleResourceRequest, hasNonTerminalFlow, hostOpResumeStimulus, installPreInitRingSink, isTerminalFlowStatus, listSessions, loadAgentManifest, loadCompileManifest, loadCompileManifestFromDir, loadSession, loadSessionById, mcpAuthSecretKey, newSession, nulTailPaddingLength, pickRepointedManager, planFlowMutate, reconcilePendingDecisions, registerActiveFlow, registerCompositionCapabilities, rejectCapabilityOnApprovalDeny, resetRunnerLogStore, resolveAgentComposition, resolveAgentMixins, resolveBinding, resolveCapabilityCallTimeoutMs, resolveCapabilityResult, resolveComposition, resolveFlowMutateConnectorWaitMs, resolveMixin, runAgentChat, saveSession, setCurrentSession, setUpFlowConnector, startAgentServer, stimulusFromMetas, touchSession, validateInputResponse, writeClaudeCodeCredentialsFile };
7530
- //# sourceMappingURL=chunk-KCI7DAKE.js.map
7531
- //# sourceMappingURL=chunk-KCI7DAKE.js.map
8278
+ export { CLAUDE_CODE_CREDENTIALS_KEY, COMPILE_MANIFEST_FILENAME, CapabilityRegistry, DEFAULT_CAPABILITY_CALL_TIMEOUT_MS, DEFAULT_COALESCE_MS, DEFAULT_FLOW_MUTATE_CONNECTOR_WAIT_MS, MOUNT_LIST_MAX_DEPTH, MOUNT_LIST_MAX_ENTRIES, MOUNT_READ_DEADLINE_FACTOR, MOUNT_TREE_OP_DEADLINE_FACTOR, MarkdownStreamer, PreInitRingSink, agentDefinitionExists, bootstrapCapabilityRegistry, bootstrapRunnerLogStore, buildAgentResources, buildClientCapabilityHandler, buildConnectorTokenMediator, buildContextSection, buildEnvironmentSection, buildResourcesAvailablePayload, buildStoreSnapshotReplay, builtinCapabilities, capabilityLogInstance, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, connectorRefreshKind, createAgentSession, createFlowConnectorReadiness, createManagedCodexSubpromptDriver, createSessionStimulusBus, defineCapability, deleteSession, dispatchRunnerCapabilityInvocation, emitSystemPromptComposed, ensureClaudeSettingsDisablesConnectors, ensureGitConfigInclude, executeConnectorMutate, extractClaudeAiOauthExpiresAt, getPreInitRingSink, handleMountResourceRequest, handleResourceRequest, hasNonTerminalFlow, hostOpResumeStimulus, installPreInitRingSink, isTerminalFlowStatus, listSessions, loadAgentManifest, loadCompileManifest, loadCompileManifestFromDir, loadManagedCodexHostConfig, loadSession, loadSessionById, mcpAuthSecretKey, newSession, nulTailPaddingLength, pickRepointedManager, planFlowMutate, prepareCodexTools, reconcilePendingDecisions, registerActiveFlow, registerCompositionCapabilities, rejectCapabilityOnApprovalDeny, resetRunnerLogStore, resolveAgentComposition, resolveAgentMixins, resolveBinding, resolveCapabilityCallTimeoutMs, resolveCapabilityResult, resolveComposition, resolveFlowMutateConnectorWaitMs, resolveMixin, runAgentChat, saveSession, setCurrentSession, setUpFlowConnector, startAgentServer, stimulusFromMetas, supportsLiveToolUpdates, touchSession, validateInputResponse, writeClaudeCodeCredentialsFile };
8279
+ //# sourceMappingURL=chunk-RJOGAEIY.js.map
8280
+ //# sourceMappingURL=chunk-RJOGAEIY.js.map