@skaile/workspaces 4.34.0 → 4.36.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 (245) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/{asset-feeds-EIHLRBUG.js → asset-feeds-SJELMLNK.js} +10 -10
  3. package/dist/{asset-feeds-EIHLRBUG.js.map → asset-feeds-SJELMLNK.js.map} +1 -1
  4. package/dist/asset-manager/catalog-deployer.js +5 -5
  5. package/dist/asset-manager/index.js +10 -10
  6. package/dist/asset-manager/installer.js +7 -7
  7. package/dist/asset-manager/renderers.js +2 -2
  8. package/dist/asset-manager/src/index.d.ts +18 -0
  9. package/dist/asset-manager/src/index.d.ts.map +1 -1
  10. package/dist/asset-manager/src/mcp-config.d.ts.map +1 -1
  11. package/dist/bridge/drivers/claude-sdk.js +12 -9
  12. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  13. package/dist/bridge/drivers/codex.js +7 -7
  14. package/dist/bridge/drivers/continue.js +8 -8
  15. package/dist/bridge/drivers/echo.js +1 -1
  16. package/dist/bridge/drivers/gemini.js +6 -6
  17. package/dist/bridge/drivers/goose.js +8 -8
  18. package/dist/bridge/drivers/omp.js +7 -4
  19. package/dist/bridge/drivers/omp.js.map +1 -1
  20. package/dist/bridge/drivers/opencode.js +8 -8
  21. package/dist/bridge/drivers/qwen.js +6 -6
  22. package/dist/bridge/index.js +9 -9
  23. package/dist/bridge/src/drivers/claude-sdk.d.ts +1 -0
  24. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  25. package/dist/bridge/src/drivers/omp.d.ts +3 -2
  26. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  27. package/dist/bridge/src/types.d.ts +8 -0
  28. package/dist/bridge/src/types.d.ts.map +1 -1
  29. package/dist/{chunk-TGE33MKN.js → chunk-2D3C4AJP.js} +4 -2
  30. package/dist/chunk-2D3C4AJP.js.map +1 -0
  31. package/dist/{chunk-JRSCSYRF.js → chunk-3CLUU45N.js} +7 -7
  32. package/dist/{chunk-JRSCSYRF.js.map → chunk-3CLUU45N.js.map} +1 -1
  33. package/dist/{chunk-T3YUSWVK.js → chunk-3SUWLY3H.js} +3 -3
  34. package/dist/{chunk-T3YUSWVK.js.map → chunk-3SUWLY3H.js.map} +1 -1
  35. package/dist/{chunk-NVQLE4MK.js → chunk-3VUHHDZW.js} +3 -3
  36. package/dist/{chunk-NVQLE4MK.js.map → chunk-3VUHHDZW.js.map} +1 -1
  37. package/dist/{chunk-LA7DCX2U.js → chunk-422WJ2QC.js} +4 -4
  38. package/dist/{chunk-LA7DCX2U.js.map → chunk-422WJ2QC.js.map} +1 -1
  39. package/dist/{chunk-Q6NDQ6BH.js → chunk-5JAO4MXA.js} +3 -3
  40. package/dist/{chunk-Q6NDQ6BH.js.map → chunk-5JAO4MXA.js.map} +1 -1
  41. package/dist/{chunk-ENV5DDQ7.js → chunk-5JJ5KQUM.js} +6 -6
  42. package/dist/{chunk-ENV5DDQ7.js.map → chunk-5JJ5KQUM.js.map} +1 -1
  43. package/dist/{chunk-AKBPLLFB.js → chunk-5L55HNNA.js} +5 -5
  44. package/dist/{chunk-AKBPLLFB.js.map → chunk-5L55HNNA.js.map} +1 -1
  45. package/dist/{chunk-DOF77WEV.js → chunk-BSIHJZKN.js} +6 -6
  46. package/dist/{chunk-DOF77WEV.js.map → chunk-BSIHJZKN.js.map} +1 -1
  47. package/dist/{chunk-VOXFI3XS.js → chunk-DFZDL62S.js} +4 -4
  48. package/dist/{chunk-VOXFI3XS.js.map → chunk-DFZDL62S.js.map} +1 -1
  49. package/dist/{chunk-3ELIPWCH.js → chunk-FJYOQMXT.js} +4 -4
  50. package/dist/{chunk-3ELIPWCH.js.map → chunk-FJYOQMXT.js.map} +1 -1
  51. package/dist/{chunk-7HJ6SFFF.js → chunk-FLGLODDF.js} +3 -3
  52. package/dist/{chunk-7HJ6SFFF.js.map → chunk-FLGLODDF.js.map} +1 -1
  53. package/dist/{chunk-JR2QQLAQ.js → chunk-FQE2NBUH.js} +7 -7
  54. package/dist/{chunk-JR2QQLAQ.js.map → chunk-FQE2NBUH.js.map} +1 -1
  55. package/dist/{chunk-OWN2W2IW.js → chunk-FWZTKSYI.js} +284 -19
  56. package/dist/chunk-FWZTKSYI.js.map +1 -0
  57. package/dist/{chunk-P2DLXBZK.js → chunk-H3KXUUYQ.js} +4 -4
  58. package/dist/{chunk-P2DLXBZK.js.map → chunk-H3KXUUYQ.js.map} +1 -1
  59. package/dist/{chunk-7LZJRVKJ.js → chunk-JRSLMZOT.js} +59 -11
  60. package/dist/chunk-JRSLMZOT.js.map +1 -0
  61. package/dist/{chunk-OS6256B2.js → chunk-KVDXSEQH.js} +317 -30
  62. package/dist/chunk-KVDXSEQH.js.map +1 -0
  63. package/dist/{chunk-FDZL5QVZ.js → chunk-L22WTIIC.js} +3 -3
  64. package/dist/{chunk-FDZL5QVZ.js.map → chunk-L22WTIIC.js.map} +1 -1
  65. package/dist/{chunk-N2UGG6WV.js → chunk-LIS5KT2X.js} +4 -4
  66. package/dist/{chunk-N2UGG6WV.js.map → chunk-LIS5KT2X.js.map} +1 -1
  67. package/dist/{chunk-Z2QI42YH.js → chunk-LVRKJW53.js} +22 -8
  68. package/dist/chunk-LVRKJW53.js.map +1 -0
  69. package/dist/{chunk-TB3LJ6NA.js → chunk-MDBAEEY5.js} +3 -3
  70. package/dist/{chunk-TB3LJ6NA.js.map → chunk-MDBAEEY5.js.map} +1 -1
  71. package/dist/{chunk-MTWZ7KHZ.js → chunk-MQU632EK.js} +11 -2
  72. package/dist/chunk-MQU632EK.js.map +1 -0
  73. package/dist/{chunk-C3256F2F.js → chunk-MRS5YHPI.js} +3 -3
  74. package/dist/{chunk-C3256F2F.js.map → chunk-MRS5YHPI.js.map} +1 -1
  75. package/dist/{chunk-7LBPHRRP.js → chunk-NFECHLV6.js} +3 -3
  76. package/dist/{chunk-7LBPHRRP.js.map → chunk-NFECHLV6.js.map} +1 -1
  77. package/dist/{chunk-GKTFGCQZ.js → chunk-NKYNDLCB.js} +3 -3
  78. package/dist/{chunk-GKTFGCQZ.js.map → chunk-NKYNDLCB.js.map} +1 -1
  79. package/dist/{chunk-LX3FKVLL.js → chunk-NTASYPDN.js} +3 -3
  80. package/dist/{chunk-LX3FKVLL.js.map → chunk-NTASYPDN.js.map} +1 -1
  81. package/dist/{chunk-WFRVQ2RY.js → chunk-NVNKPWL4.js} +10 -10
  82. package/dist/{chunk-WFRVQ2RY.js.map → chunk-NVNKPWL4.js.map} +1 -1
  83. package/dist/{chunk-75LXFKQR.js → chunk-O63QZ6XX.js} +4 -4
  84. package/dist/{chunk-75LXFKQR.js.map → chunk-O63QZ6XX.js.map} +1 -1
  85. package/dist/{chunk-7IH3RKKK.js → chunk-OEBAXTQ4.js} +3 -3
  86. package/dist/{chunk-7IH3RKKK.js.map → chunk-OEBAXTQ4.js.map} +1 -1
  87. package/dist/{chunk-RR4PJZLK.js → chunk-PKGI5QG7.js} +64 -8
  88. package/dist/chunk-PKGI5QG7.js.map +1 -0
  89. package/dist/{chunk-TGJIX77V.js → chunk-Q7SIVPM2.js} +3 -3
  90. package/dist/{chunk-TGJIX77V.js.map → chunk-Q7SIVPM2.js.map} +1 -1
  91. package/dist/{chunk-T762W5CI.js → chunk-QABZZROM.js} +3 -3
  92. package/dist/{chunk-T762W5CI.js.map → chunk-QABZZROM.js.map} +1 -1
  93. package/dist/{chunk-LRCSWOZO.js → chunk-QKXDRBLL.js} +5 -3
  94. package/dist/chunk-QKXDRBLL.js.map +1 -0
  95. package/dist/{chunk-DHLE66FV.js → chunk-S63H4HDH.js} +8 -4
  96. package/dist/chunk-S63H4HDH.js.map +1 -0
  97. package/dist/{chunk-2FBPAR2V.js → chunk-SQ7IN7KR.js} +3 -2
  98. package/dist/chunk-SQ7IN7KR.js.map +1 -0
  99. package/dist/{chunk-2EUW6NZD.js → chunk-TILISP6X.js} +2 -2
  100. package/dist/{chunk-2EUW6NZD.js.map → chunk-TILISP6X.js.map} +1 -1
  101. package/dist/{chunk-5YXKEM7Q.js → chunk-VCLN2IUM.js} +5 -5
  102. package/dist/{chunk-5YXKEM7Q.js.map → chunk-VCLN2IUM.js.map} +1 -1
  103. package/dist/{chunk-JRIU5GA7.js → chunk-VRFKCF3R.js} +4 -4
  104. package/dist/{chunk-JRIU5GA7.js.map → chunk-VRFKCF3R.js.map} +1 -1
  105. package/dist/{chunk-7ERHZQ7O.js → chunk-XN7DAZB7.js} +3 -3
  106. package/dist/{chunk-7ERHZQ7O.js.map → chunk-XN7DAZB7.js.map} +1 -1
  107. package/dist/{chunk-RHESVS7V.js → chunk-YOIENZHA.js} +6 -6
  108. package/dist/{chunk-RHESVS7V.js.map → chunk-YOIENZHA.js.map} +1 -1
  109. package/dist/cli/index.js +69 -61
  110. package/dist/cli/index.js.map +1 -1
  111. package/dist/cli/src/commands/catalog.d.ts +7 -0
  112. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  113. package/dist/cli/src/commands/connector.d.ts.map +1 -1
  114. package/dist/connectors/config.js +3 -3
  115. package/dist/connectors/index.js +12 -12
  116. package/dist/connectors/src/config.d.ts.map +1 -1
  117. package/dist/connectors/src/connect-failure-carry-over.d.ts +38 -0
  118. package/dist/connectors/src/connect-failure-carry-over.d.ts.map +1 -0
  119. package/dist/connectors/src/connector-manager.d.ts +15 -0
  120. package/dist/connectors/src/connector-manager.d.ts.map +1 -1
  121. package/dist/connectors/src/connector-types.d.ts +7 -0
  122. package/dist/connectors/src/connector-types.d.ts.map +1 -1
  123. package/dist/connectors/src/index.d.ts +1 -0
  124. package/dist/connectors/src/index.d.ts.map +1 -1
  125. package/dist/connectors/src/materialized-connectors.d.ts.map +1 -1
  126. package/dist/core/index.js +4 -4
  127. package/dist/core/manifest.js +1 -1
  128. package/dist/core/runtime-assets.js +3 -3
  129. package/dist/core/src/manifest.d.ts.map +1 -1
  130. package/dist/core/src/workspace-config.d.ts +7 -0
  131. package/dist/core/src/workspace-config.d.ts.map +1 -1
  132. package/dist/core/workspace-config.js +2 -2
  133. package/dist/deploy/index.js +4 -4
  134. package/dist/discovery/index.js +3 -3
  135. package/dist/{ensure-sources-JR4QI2MY.js → ensure-sources-SYZO2HNP.js} +13 -13
  136. package/dist/{ensure-sources-JR4QI2MY.js.map → ensure-sources-SYZO2HNP.js.map} +1 -1
  137. package/dist/factory-assets/connectors/box.js +12 -12
  138. package/dist/factory-assets/connectors/deploy.js +12 -12
  139. package/dist/factory-assets/connectors/devserver.js +12 -12
  140. package/dist/factory-assets/connectors/flow/adapter.js +12 -12
  141. package/dist/factory-assets/connectors/flow/engine.js +5 -5
  142. package/dist/factory-assets/connectors/flow/run-flow.js +14 -14
  143. package/dist/factory-assets/connectors/flow.js +12 -12
  144. package/dist/factory-assets/connectors/git/CONNECTOR.md +1 -0
  145. package/dist/factory-assets/connectors/git/driver.d.ts +29 -0
  146. package/dist/factory-assets/connectors/git/driver.d.ts.map +1 -1
  147. package/dist/factory-assets/connectors/git.js +12 -12
  148. package/dist/factory-assets/connectors/gmail.js +12 -12
  149. package/dist/factory-assets/connectors/googledrive.js +12 -12
  150. package/dist/factory-assets/connectors/local.js +12 -12
  151. package/dist/factory-assets/connectors/mattermost.js +12 -12
  152. package/dist/factory-assets/connectors/memory.js +12 -12
  153. package/dist/factory-assets/connectors/minio.js +12 -12
  154. package/dist/factory-assets/connectors/postgres.js +12 -12
  155. package/dist/factory-assets/connectors/s3.js +12 -12
  156. package/dist/factory-assets/connectors/sharepoint.js +12 -12
  157. package/dist/factory-assets/connectors/sqlite.js +12 -12
  158. package/dist/factory-assets/connectors/static-server.js +12 -12
  159. package/dist/factory-assets/connectors/tunnel.js +12 -12
  160. package/dist/factory-assets/connectors/webdav.js +12 -12
  161. package/dist/factory-assets/connectors/xstate-store.js +12 -12
  162. package/dist/factory-assets/connectors/xstate.js +12 -12
  163. package/dist/{flows-X7JFAVRR.js → flows-6MDMBQUZ.js} +9 -9
  164. package/dist/{flows-X7JFAVRR.js.map → flows-6MDMBQUZ.js.map} +1 -1
  165. package/dist/{helpers-HTET53KB.js → helpers-IMUCDNME.js} +13 -13
  166. package/dist/{helpers-HTET53KB.js.map → helpers-IMUCDNME.js.map} +1 -1
  167. package/dist/library/index.js +7 -7
  168. package/dist/{library-publish-T6KHQ3TE.js → library-publish-XAIAHKRL.js} +17 -17
  169. package/dist/{library-publish-T6KHQ3TE.js.map → library-publish-XAIAHKRL.js.map} +1 -1
  170. package/dist/{open-library-O5I2DAEK.js → open-library-6N3XZ2XL.js} +15 -15
  171. package/dist/{open-library-O5I2DAEK.js.map → open-library-6N3XZ2XL.js.map} +1 -1
  172. package/dist/{paths-OI5IIS22.js → paths-4MTICP3T.js} +7 -7
  173. package/dist/{paths-OI5IIS22.js.map → paths-4MTICP3T.js.map} +1 -1
  174. package/dist/{plugin-store-C67RLSPD.js → plugin-store-GQ4WQZJ2.js} +6 -6
  175. package/dist/{plugin-store-C67RLSPD.js.map → plugin-store-GQ4WQZJ2.js.map} +1 -1
  176. package/dist/{project-QIOXU2NS.js → project-HESTMGPU.js} +14 -14
  177. package/dist/{project-QIOXU2NS.js.map → project-HESTMGPU.js.map} +1 -1
  178. package/dist/resolver/index.js +5 -5
  179. package/dist/runner/index.js +21 -21
  180. package/dist/runner/src/capability-registry.d.ts +13 -0
  181. package/dist/runner/src/capability-registry.d.ts.map +1 -1
  182. package/dist/runner/src/compaction/orchestrator.d.ts +8 -0
  183. package/dist/runner/src/compaction/orchestrator.d.ts.map +1 -1
  184. package/dist/runner/src/compaction-gate.d.ts +64 -1
  185. package/dist/runner/src/compaction-gate.d.ts.map +1 -1
  186. package/dist/runner/src/driver-swap-gate.d.ts +17 -0
  187. package/dist/runner/src/driver-swap-gate.d.ts.map +1 -1
  188. package/dist/runner/src/external-mcp.d.ts +6 -0
  189. package/dist/runner/src/external-mcp.d.ts.map +1 -1
  190. package/dist/runner/src/mcp-pinned-ca.d.ts +8 -0
  191. package/dist/runner/src/mcp-pinned-ca.d.ts.map +1 -0
  192. package/dist/runner/src/prompt-turn-queue.d.ts +28 -0
  193. package/dist/runner/src/prompt-turn-queue.d.ts.map +1 -0
  194. package/dist/runner/src/resources.d.ts.map +1 -1
  195. package/dist/runner/src/serve.d.ts +46 -0
  196. package/dist/runner/src/serve.d.ts.map +1 -1
  197. package/dist/runner/src/session-stimulus.d.ts +5 -0
  198. package/dist/runner/src/session-stimulus.d.ts.map +1 -1
  199. package/dist/sdk/asset-manager.js +10 -10
  200. package/dist/sdk/bridge.js +9 -9
  201. package/dist/sdk/core.js +4 -4
  202. package/dist/sdk/flow.js +5 -5
  203. package/dist/sdk/index.js +21 -21
  204. package/dist/sdk/resolver.js +5 -5
  205. package/dist/sdk/runner.js +21 -21
  206. package/dist/sdk/session.js +1 -1
  207. package/dist/sdk/store.js +1 -1
  208. package/dist/session/index.js +1 -1
  209. package/dist/session/src/bounded-subscriber-transport.d.ts +11 -4
  210. package/dist/session/src/bounded-subscriber-transport.d.ts.map +1 -1
  211. package/dist/session/src/dispatcher.d.ts +5 -0
  212. package/dist/session/src/dispatcher.d.ts.map +1 -1
  213. package/dist/session/src/index.d.ts +1 -1
  214. package/dist/session/src/index.d.ts.map +1 -1
  215. package/dist/session/src/types.d.ts +20 -1
  216. package/dist/session/src/types.d.ts.map +1 -1
  217. package/dist/{setup-SSGPDDWL.js → setup-PQG5DH5Z.js} +18 -18
  218. package/dist/{setup-SSGPDDWL.js.map → setup-PQG5DH5Z.js.map} +1 -1
  219. package/dist/{skills-4YTVHMOH.js → skills-JHUY4DFE.js} +10 -10
  220. package/dist/{skills-4YTVHMOH.js.map → skills-JHUY4DFE.js.map} +1 -1
  221. package/dist/{source-NPU7ZWID.js → source-PNYNVVPM.js} +16 -16
  222. package/dist/{source-NPU7ZWID.js.map → source-PNYNVVPM.js.map} +1 -1
  223. package/dist/{source-manifest-publish-4EYDVPR3.js → source-manifest-publish-6O6H4T2P.js} +18 -18
  224. package/dist/{source-manifest-publish-4EYDVPR3.js.map → source-manifest-publish-6O6H4T2P.js.map} +1 -1
  225. package/dist/store/index.js +1 -1
  226. package/dist/store/src/store.d.ts +21 -1
  227. package/dist/store/src/store.d.ts.map +1 -1
  228. package/dist/tui/index.js +21 -21
  229. package/dist/types/manifests.js +1 -1
  230. package/dist/types/src/manifests/mcp-server.d.ts +1 -0
  231. package/dist/types/src/manifests/mcp-server.d.ts.map +1 -1
  232. package/dist/workspace-plugin/adapters/mcp.js +10 -10
  233. package/dist/workspace-plugin/adapters/omp.js +7 -7
  234. package/dist/workspace-plugin/index.js +1 -1
  235. package/package.json +2 -2
  236. package/dist/chunk-2FBPAR2V.js.map +0 -1
  237. package/dist/chunk-7LZJRVKJ.js.map +0 -1
  238. package/dist/chunk-DHLE66FV.js.map +0 -1
  239. package/dist/chunk-LRCSWOZO.js.map +0 -1
  240. package/dist/chunk-MTWZ7KHZ.js.map +0 -1
  241. package/dist/chunk-OS6256B2.js.map +0 -1
  242. package/dist/chunk-OWN2W2IW.js.map +0 -1
  243. package/dist/chunk-RR4PJZLK.js.map +0 -1
  244. package/dist/chunk-TGE33MKN.js.map +0 -1
  245. package/dist/chunk-Z2QI42YH.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../bridge/src/normalizer.ts","../bridge/src/runtime.ts","../bridge/src/validation.ts"],"names":[],"mappings":"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","file":"chunk-NVQLE4MK.js","sourcesContent":["/**\n * EventNormalizer — converts bridge-level AgentEvent (raw driver events) to\n * skaile-agent-types AgentEvent (normalized, human-readable events).\n *\n * Stateful: tracks active subagents and dev-server detection across a session.\n * Call reset() between sessions.\n */\n\nimport {\n type AgentEvent as NormalizedEvent,\n type NativeApprovalDescription,\n stripActivityLabel,\n TOOL_ACTIVITY_LABEL_MAX_CHARS,\n TOOL_ACTIVITY_LABEL_PARAM,\n} from \"@skaile/workspaces/types\";\nimport { classifyClaudeSdkError } from \"./error-classifier.js\";\nimport type { AgentMessage, AgentEvent as BridgeEvent, ContentBlock } from \"./types.js\";\n\n/**\n * The optional usage keys a `result` event carries, in the shape both\n * `finished` and a result-sourced `error` emit them. Absent keys stay absent.\n */\nfunction resultUsageFields(\n event: Pick<\n Extract<BridgeEvent, { type: \"result\" | \"error\" }>,\n \"tokens\" | \"modelUsage\" | \"contextTokens\" | \"contextWindow\"\n >,\n) {\n return {\n ...(event.tokens ? { tokens: event.tokens } : {}),\n ...(event.modelUsage ? { modelUsage: event.modelUsage } : {}),\n ...(typeof event.contextTokens === \"number\" ? { contextTokens: event.contextTokens } : {}),\n ...(typeof event.contextWindow === \"number\" ? { contextWindow: event.contextWindow } : {}),\n };\n}\n\n/**\n * The tool a driver uses to park a turn on a human answer. Both branches that\n * recognise it must use this constant: `message_start` turns it into a\n * `question`, and `tool_call` must then stay silent about it.\n */\nconst QUESTION_TOOL = \"AskUserQuestion\";\n\nconst MAX_ANNOUNCED_TOOL_USES = 64;\n\n/**\n * Bridge `tool_call` inputs are loosely typed: Codex MCP arguments may arrive\n * as a JSON string, and the echo driver passes a bare path.\n */\nfunction toolInputRecord(input: unknown): Record<string, unknown> {\n let value = input;\n if (typeof value === \"string\") {\n try {\n value = JSON.parse(value);\n } catch {\n return { input };\n }\n }\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return value === undefined ? {} : { input };\n}\n\n/**\n * Converts raw bridge-level {@link BridgeEvent} payloads into normalized\n * `@skaile/workspaces/types` `AgentEvent` payloads consumed by the runner and transport.\n *\n * Stateful: tracks active subagents and dev-server detection across a session.\n * Call {@link EventNormalizer.reset} between sessions to clear accumulated state.\n *\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport class EventNormalizer {\n private activeSubagents = new Map<string, string>();\n private devServerStartingEmitted = false;\n private devServerReadyEmitted = false;\n /** True when message_update deltas have been emitted for the current message. */\n private hasStreamedText = false;\n /**\n * True once a `_thinkingDelta` run has been reported as `status: thinking`;\n * cleared by the next text delta or assistant message, so a run reports once.\n */\n private thinkingAnnounced = false;\n /**\n * tool_use blocks `message_start` already reported, awaiting the driver's\n * matching bridge `tool_call` — which must then not report the call again.\n */\n private announcedToolUses: Array<{ id?: string; name: string }> = [];\n\n /**\n * Convert a single bridge event into zero or more normalized events.\n * One bridge event can produce multiple normalized events (e.g., a message_start\n * with text + tool_use blocks produces both text and tool_call events).\n */\n normalize(event: BridgeEvent): NormalizedEvent[] {\n switch (event.type) {\n case \"message_start\":\n return this.handleMessageStart(event.message);\n\n case \"message_update\":\n return this.handleMessageUpdate(event);\n\n case \"message_end\":\n return [];\n\n case \"message_retract\":\n // The replay streams its reply afresh, so its deltas (or, failing\n // those, its message_start text) must count as a new message.\n this.hasStreamedText = false;\n return event.text ? [{ type: \"text_retract\", content: event.text }] : [];\n\n case \"turn_end\":\n return this.handleTurnEnd(event.toolResults);\n\n case \"result\":\n return this.handleResult(event);\n\n case \"error\":\n this.announcedToolUses = [];\n return [\n {\n type: \"error\",\n message: event.error,\n fatal: event.fatal ?? true,\n category: event.detail?.category,\n ...(event.detail?.hint ? { hint: event.detail.hint } : {}),\n ...resultUsageFields(event),\n ...(event.retrying === true\n ? { retrying: true, ...(event.retryReason ? { retryReason: event.retryReason } : {}) }\n : {}),\n },\n ];\n\n case \"tool_call\": {\n // The question tool parks the turn on the user's answer, so reporting\n // work here would undo the idle its `question` event just set, and\n // nothing follows to correct it while the user reads the prompt.\n const toolName = event.name ?? event.tool?.name;\n if (toolName === QUESTION_TOOL) return [];\n // A driver that also sent the call as a `message_start` tool_use block\n // (Claude) was already reported there; the rest only ever send this.\n if (!toolName || this.consumeAnnouncedToolUse(toolName, event.toolCallId)) {\n return [{ type: \"status\", phase: \"working\" }];\n }\n return this.handleToolUse(\n {\n type: \"tool_use\",\n id: typeof event.toolCallId === \"string\" ? event.toolCallId : undefined,\n name: toolName,\n input: toolInputRecord(event.input),\n },\n typeof event.parentToolUseId === \"string\" ? event.parentToolUseId : undefined,\n );\n }\n\n case \"tool_execution_end\":\n return [];\n\n case \"agent_end\":\n this.announcedToolUses = [];\n return [{ type: \"status\", phase: \"idle\" }];\n\n case \"commands_available\":\n // Pass through to transport — the gateway caches this event\n return [event as unknown as NormalizedEvent];\n\n case \"session_info\":\n // Pass through to transport — the forge layer stores the OMP session ID\n return [event as unknown as NormalizedEvent];\n\n case \"ui_render\":\n case \"ui_render_update\":\n case \"ui_clear\":\n // Pass through verbatim — drivers that implement the Agent UI Protocol emit these directly\n return [event as unknown as NormalizedEvent];\n\n default:\n return [];\n }\n }\n\n /** Clear all stateful tracking between sessions. */\n reset(): void {\n this.activeSubagents.clear();\n this.devServerStartingEmitted = false;\n this.devServerReadyEmitted = false;\n this.hasStreamedText = false;\n this.thinkingAnnounced = false;\n this.announcedToolUses = [];\n }\n\n private consumeAnnouncedToolUse(name: string, id: unknown): boolean {\n const callId = typeof id === \"string\" ? id : undefined;\n const index = this.announcedToolUses.findIndex(\n (entry) => entry.name === name && (!callId || !entry.id || entry.id === callId),\n );\n if (index === -1) return false;\n this.announcedToolUses.splice(index, 1);\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // message_start → text, tool_call, question, subagent\n // ---------------------------------------------------------------------------\n\n private handleMessageStart(message: AgentMessage): NormalizedEvent[] {\n // Only process assistant messages. Drivers (e.g. omp) may echo the user's\n // message as a message_start with role:\"user\" before streaming the response.\n // Emitting a text event for that echo would prepend the user's input to the\n // assistant bubble on the frontend.\n if (message.role !== \"assistant\") return [];\n\n // A subagent's message is not the main reply: its text belongs to the\n // subagent's own result, and it must not reset the main stream's state.\n const parentToolUseId = message.parentToolUseId;\n const events: NormalizedEvent[] = [];\n const blocks = this.getContentBlocks(message);\n\n for (const block of blocks) {\n if (block.type === \"text\" && block.text) {\n if (parentToolUseId) continue;\n // Skip full text if we already streamed it via message_update deltas\n if (!this.hasStreamedText) {\n events.push({ type: \"text\", content: block.text });\n }\n } else if (block.type === \"tool_use\" && block.name) {\n if (block.name !== QUESTION_TOOL) {\n this.announcedToolUses.push({ id: block.id, name: block.name });\n // Bounded in case a driver never echoes a block as a tool_call.\n if (this.announcedToolUses.length > MAX_ANNOUNCED_TOOL_USES) {\n this.announcedToolUses.shift();\n }\n }\n events.push(...this.handleToolUse(block, parentToolUseId));\n }\n }\n\n if (!parentToolUseId) this.hasStreamedText = false;\n if (!parentToolUseId) this.thinkingAnnounced = false;\n return events;\n }\n\n private handleToolUse(block: ContentBlock, parentToolUseId?: string): NormalizedEvent[] {\n const name = block.name!;\n const input = (block.input ?? {}) as Record<string, unknown>;\n\n if (name === QUESTION_TOOL) {\n return this.handleAskUserQuestion(input);\n }\n if (name === \"Agent\") {\n return this.handleAgentToolUse(block, input);\n }\n return this.handleGenericToolUse(name, input, parentToolUseId);\n }\n\n private handleAskUserQuestion(input: Record<string, unknown>): NormalizedEvent[] {\n const events: NormalizedEvent[] = [];\n const candidate = input.approval as Partial<NativeApprovalDescription> | undefined;\n const approval =\n candidate &&\n [\"command\", \"file\", \"permissions\", \"mcp\"].includes(candidate.kind ?? \"\") &&\n Array.isArray(candidate.details) &&\n candidate.details.length > 0 &&\n candidate.details.length <= 64 &&\n candidate.details.every((detail) => typeof detail === \"string\" && detail.length <= 8192) &&\n candidate.details.reduce((total, detail) => total + detail.length, 0) <= 65536\n ? (candidate as NativeApprovalDescription)\n : undefined;\n if (Object.hasOwn(input, \"approval\") && !approval) return [];\n // Claude SDK sends { questions: [{ question, header, options: [{ label, description }] }] }\n // Legacy/simple format sends { question: string, options?: string[] }\n const questions = input.questions;\n if (Array.isArray(questions)) {\n for (const q of questions) {\n const qObj = q as Record<string, unknown>;\n const question = String(qObj.question ?? \"\");\n const rawOpts = qObj.options;\n const options = Array.isArray(rawOpts)\n ? rawOpts.map((o: any) => (typeof o === \"string\" ? o : String(o.label ?? o)))\n : undefined;\n events.push({\n type: \"question\",\n question,\n options,\n ...(typeof input.requestId === \"string\" ? { requestId: input.requestId } : {}),\n ...(approval ? { approval } : {}),\n });\n }\n } else {\n const question = String(input.question ?? input.text ?? \"\");\n const rawOptions = input.options;\n const options = Array.isArray(rawOptions) ? rawOptions.map(String) : undefined;\n events.push({\n type: \"question\",\n question,\n options,\n ...(typeof input.requestId === \"string\" ? { requestId: input.requestId } : {}),\n ...(approval ? { approval } : {}),\n });\n }\n return events;\n }\n\n private handleAgentToolUse(\n block: ContentBlock,\n input: Record<string, unknown>,\n ): NormalizedEvent[] {\n const agentName = String(input.subagent_type ?? input.description ?? \"unknown\");\n const description = String(input.description ?? input.prompt ?? \"\").slice(0, 200);\n if (block.id) {\n this.activeSubagents.set(block.id, agentName);\n }\n return [\n { type: \"subagent\", name: agentName, status: \"started\", description },\n { type: \"status\", phase: \"working\" },\n ];\n }\n\n private handleGenericToolUse(\n name: string,\n input: Record<string, unknown>,\n parentToolUseId?: string,\n ): NormalizedEvent[] {\n const events: NormalizedEvent[] = [];\n const label = labelToolCall(name, input);\n events.push({\n type: \"tool_call\",\n tool: name,\n input,\n // Summarize without the label: it would eat the default branch's\n // 100-char argument budget and push the real args out.\n summary: summarizeToolCall(name, stripActivityLabel(input)),\n ...(label ? { label } : {}),\n ...(parentToolUseId ? { parentToolUseId } : {}),\n });\n events.push({ type: \"status\", phase: \"working\" });\n\n if (name === \"Bash\" && typeof input.command === \"string\") {\n const devEvent = this.detectDevServerStarting(input.command);\n if (devEvent) events.push(devEvent);\n }\n\n return events;\n }\n\n // ---------------------------------------------------------------------------\n // message_update → streaming text\n // ---------------------------------------------------------------------------\n\n private handleMessageUpdate(event: BridgeEvent): NormalizedEvent[] {\n // Bridge deltas carry no subagent tag: a driver must drop a subagent's\n // partials itself (claude-sdk does in handleStreamEvent), or they read as main text.\n const delta = (event as any)._textDelta as string | undefined;\n if (delta) {\n this.hasStreamedText = true;\n this.thinkingAnnounced = false;\n return [{ type: \"text\", content: delta }];\n }\n // The protocol has no thinking-content event, so reasoning surfaces as the\n // existing `thinking` phase, once per run. The text is never forwarded as\n // `text`; a driver keeps it out of `_textDelta`.\n const thinking: unknown = \"_thinkingDelta\" in event ? event._thinkingDelta : undefined;\n if (typeof thinking === \"string\" && thinking && !this.thinkingAnnounced) {\n this.thinkingAnnounced = true;\n return [{ type: \"status\", phase: \"thinking\" }];\n }\n return [];\n }\n\n // ---------------------------------------------------------------------------\n // turn_end → tool_result, subagent finished, file_changed, dev_server\n // ---------------------------------------------------------------------------\n\n private handleTurnEnd(toolResults?: AgentMessage[]): NormalizedEvent[] {\n if (!toolResults?.length) return [];\n\n const events: NormalizedEvent[] = [];\n\n for (const result of toolResults) {\n const toolName = result.toolName ?? \"unknown\";\n const outputData = result.data ?? result.content;\n const output = typeof outputData === \"string\" ? outputData : JSON.stringify(outputData);\n\n // Check if this is a subagent result\n if (toolName === \"Agent\" || this.isSubagentResult(result)) {\n events.push(...this.handleSubagentResult(result, output));\n } else {\n events.push(...this.handleToolResult(toolName, outputData, output, result.parentToolUseId));\n }\n }\n\n return events;\n }\n\n private handleSubagentResult(result: AgentMessage, output: string): NormalizedEvent[] {\n const events: NormalizedEvent[] = [];\n const agentName = this.resolveSubagentName(result);\n const description = output.slice(0, 200);\n events.push({ type: \"subagent\", name: agentName, status: \"finished\", description });\n\n if (agentName === \"dev-server\") {\n const devEvent = this.detectDevServerReady(output);\n if (devEvent) events.push(devEvent);\n }\n return events;\n }\n\n private handleToolResult(\n toolName: string,\n outputData: unknown,\n output: string,\n parentToolUseId?: string,\n ): NormalizedEvent[] {\n const events: NormalizedEvent[] = [];\n events.push({\n type: \"tool_result\",\n tool: toolName,\n output: outputData,\n summary: summarizeToolResult(toolName, outputData),\n ...(parentToolUseId ? { parentToolUseId } : {}),\n });\n\n // Detect file changes from Write/Edit results\n const fileEvents = detectFileChanges(toolName, outputData);\n if (fileEvents.length > 0) events.push(...fileEvents);\n\n // Detect dev server from Bash output\n if (toolName === \"Bash\") {\n const devEvent = this.detectDevServerReady(output);\n if (devEvent) events.push(devEvent);\n }\n return events;\n }\n\n private isSubagentResult(result: AgentMessage): boolean {\n // Check if the tool result's id maps to a tracked subagent\n if (result.toolName && this.activeSubagents.has(result.toolName)) return true;\n return false;\n }\n\n private resolveSubagentName(result: AgentMessage): string {\n // toolName on bridge AgentMessage is resolved from toolIdToName in the driver\n const name = result.toolName ? this.activeSubagents.get(result.toolName) : undefined;\n if (name) {\n this.activeSubagents.delete(result.toolName!);\n return name;\n }\n return result.toolName ?? \"unknown\";\n }\n\n // ---------------------------------------------------------------------------\n // result → finished or error\n // ---------------------------------------------------------------------------\n\n private handleResult(event: BridgeEvent & { type: \"result\" }): NormalizedEvent[] {\n const usage = resultUsageFields(event);\n if (event.subtype === \"success\") {\n return [\n {\n type: \"finished\",\n summary: event.summary ?? \"Task completed\",\n costUsd: event.costUsd ?? 0,\n ...usage,\n },\n ];\n }\n\n const errors = event.errors ?? [];\n // Run the same classifier the claude-sdk driver uses on its `error`\n // event so the result-error path also surfaces a category and hint\n // (drivers other than claude-sdk emit `result` without a paired\n // `error`, so this is the only place they get classified).\n const detail = classifyClaudeSdkError({ errors, subtype: event.subtype });\n // The turn billed even though it failed: carry its usage so a ledger\n // that only writes on `finished` can write here too. Unlike the finished\n // branch, no `costUsd: 0` fallback — an absent figure stays absent.\n return [\n {\n type: \"error\",\n message: `Agent stopped: ${event.subtype}${errors.length ? ` — ${errors.join(\"; \")}` : \"\"}`,\n fatal: event.subtype === \"error_during_execution\",\n category: detail.category,\n ...(detail.hint ? { hint: detail.hint } : {}),\n ...(typeof event.costUsd === \"number\" ? { costUsd: event.costUsd } : {}),\n ...usage,\n },\n ];\n }\n\n // ---------------------------------------------------------------------------\n // Dev server detection\n // ---------------------------------------------------------------------------\n\n private detectDevServerStarting(command: string): NormalizedEvent | null {\n if (this.devServerStartingEmitted) return null;\n const cmd = command.toLowerCase();\n const isFrontendStart =\n (cmd.includes(\"pnpm run dev\") || cmd.includes(\"pnpm dev\") || cmd.includes(\"vite\")) &&\n (cmd.includes(\"frontend\") || cmd.includes(\"dev:preview\"));\n if (isFrontendStart) {\n this.devServerStartingEmitted = true;\n return { type: \"dev_server\", url: \"http://localhost:3000\", status: \"starting\" };\n }\n return null;\n }\n\n private detectDevServerReady(text: string): NormalizedEvent | null {\n if (this.devServerReadyEmitted) return null;\n\n const explicitMatch = text.match(/DEVSERVER_READY:(https?:\\/\\/[^\\s\"\\\\]+)/);\n if (explicitMatch) {\n this.devServerReadyEmitted = true;\n return { type: \"dev_server\", url: explicitMatch[1]!, status: \"ready\" };\n }\n\n const viteMatch = text.match(/Local:\\s+(https?:\\/\\/localhost:\\d+)/);\n if (viteMatch) {\n this.devServerReadyEmitted = true;\n return { type: \"dev_server\", url: viteMatch[1]!, status: \"ready\" };\n }\n\n if (text.includes(\"FRONTEND_READY\")) {\n this.devServerReadyEmitted = true;\n return { type: \"dev_server\", url: \"http://localhost:3000\", status: \"ready\" };\n }\n\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n private getContentBlocks(message: AgentMessage): ContentBlock[] {\n if (Array.isArray(message.content)) return message.content;\n if (typeof message.content === \"string\" && message.content) {\n return [{ type: \"text\", text: message.content }];\n }\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pure helper functions (exported for reuse)\n// ---------------------------------------------------------------------------\n\n/**\n * Produce a human-readable one-line summary of a tool call for the activity log.\n *\n * Returns a string like `$ git status` for Bash, `Read src/index.ts` for Read, etc.\n * Falls back to `ToolName({...input...})` for unrecognised tools.\n *\n * @param tool - Tool name (e.g. `\"Bash\"`, `\"Write\"`, `\"Grep\"`).\n * @param input - Tool input record passed to the call.\n * @returns A short display string suitable for the activity feed.\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport function summarizeToolCall(tool: string, input: Record<string, unknown>): string {\n // A driver that sent a bare value instead of named args has it under `input`.\n const arg = (key: string) => String(input[key] ?? input.input);\n switch (tool) {\n case \"Bash\":\n return `$ ${String(input.command ?? input.input ?? \"\").slice(0, 200)}`;\n case \"Write\":\n return `Create ${arg(\"file_path\")}`;\n case \"Edit\":\n return `Edit ${arg(\"file_path\")}`;\n case \"Read\":\n return `Read ${arg(\"file_path\")}`;\n case \"Glob\":\n return `Find ${arg(\"pattern\")}`;\n case \"Grep\":\n return `Search for ${arg(\"pattern\")}`;\n case \"ApplyPatch\": {\n // Paths only: stringifying the input would serialize every full diff.\n const changes = Array.isArray(input.changes) ? input.changes : [];\n const paths = changes\n .map((change) => (change as { path?: unknown } | null)?.path)\n .filter((path): path is string => typeof path === \"string\");\n return `Edit ${paths.join(\", \").slice(0, 200) || \"files\"}`;\n }\n default:\n return `${tool}(${JSON.stringify(input).slice(0, 100)})`;\n }\n}\n\n/**\n * Produce the plain-language label shown to non-technical users while a tool\n * call runs: the agent's own `activity_label`, Bash's `description`, else a\n * derived phrase for Claude Code built-ins. `undefined` for any other tool —\n * the UI then falls back to a generic \"working\" line rather than raw input.\n *\n * @param tool - Tool name as the model called it.\n * @param input - Tool input record, still carrying `activity_label`.\n * @returns A trimmed label capped at `TOOL_ACTIVITY_LABEL_MAX_CHARS`, or `undefined`.\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport function labelToolCall(tool: string, input: Record<string, unknown>): string | undefined {\n const authored =\n nonEmpty(input[TOOL_ACTIVITY_LABEL_PARAM]) ??\n (tool === \"Bash\" ? nonEmpty(input.description) : undefined);\n const label = authored ?? builtinToolLabel(tool, input);\n if (!label) return undefined;\n return label.length > TOOL_ACTIVITY_LABEL_MAX_CHARS\n ? `${label.slice(0, TOOL_ACTIVITY_LABEL_MAX_CHARS - 1).trimEnd()}…`\n : label;\n}\n\nfunction nonEmpty(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.replace(/\\s+/g, \" \").trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction builtinToolLabel(tool: string, input: Record<string, unknown>): string | undefined {\n switch (tool) {\n case \"Read\":\n return withTarget(\"Reading\", baseName(input.file_path));\n case \"Edit\":\n case \"MultiEdit\":\n case \"NotebookEdit\":\n return withTarget(\"Editing\", baseName(input.file_path ?? input.notebook_path));\n case \"Write\":\n return withTarget(\"Creating\", baseName(input.file_path));\n case \"Grep\":\n case \"Glob\":\n return \"Searching files\";\n case \"WebSearch\":\n return \"Searching the web\";\n case \"WebFetch\":\n return withTarget(\"Fetching\", hostOf(input.url), \"a web page\");\n case \"TodoWrite\":\n return \"Updating the task list\";\n case \"ApplyPatch\":\n return \"Editing files\";\n default:\n return undefined;\n }\n}\n\nfunction withTarget(verb: string, target: string | undefined, fallback = \"a file\"): string {\n return `${verb} ${target ?? fallback}`;\n}\n\nfunction baseName(value: unknown): string | undefined {\n if (typeof value !== \"string\" || value.length === 0) return undefined;\n return value.split(/[\\\\/]/).filter(Boolean).pop();\n}\n\nfunction hostOf(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n try {\n return new URL(value).host || undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Extract plain text from an Anthropic content-block array (e.g. tool results returned by Claude SDK). */\nfunction extractContentBlockText(blocks: unknown[]): string | null {\n const textBlocks = blocks.filter(\n (b): b is { type: \"text\"; text: string } =>\n typeof b === \"object\" &&\n b !== null &&\n (b as Record<string, unknown>).type === \"text\" &&\n typeof (b as Record<string, unknown>).text === \"string\",\n );\n if (textBlocks.length === 0) return null;\n return textBlocks.map((b) => b.text).join(\"\\n\");\n}\n\n/**\n * Produce a human-readable one-line summary of a tool result for the activity log.\n *\n * Handles Bash stdout/stderr, Write/Edit file paths, ApplyPatch change counts, and\n * Anthropic content-block arrays. Falls back to `JSON.stringify` for unknown shapes.\n *\n * @param tool - Tool name.\n * @param result - Raw tool result payload.\n * @returns A short display string, truncated to 200 characters.\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport function summarizeToolResult(tool: string, result: unknown): string {\n // Handle Anthropic content-block arrays: [{ type: \"text\", text: \"...\" }, ...]\n if (Array.isArray(result)) {\n const text = extractContentBlockText(result);\n return (text ?? JSON.stringify(result)).slice(0, 200);\n }\n if (typeof result !== \"object\" || !result) {\n return String(result).slice(0, 200);\n }\n const r = result as Record<string, unknown>;\n switch (tool) {\n case \"Bash\": {\n const stderr = String(r.stderr ?? \"\").trim();\n if (stderr) return `stderr: ${stderr.slice(0, 200)}`;\n return (\n String(r.stdout ?? \"\")\n .trim()\n .slice(0, 200) || \"(no output)\"\n );\n }\n case \"Write\":\n return `${String(r.type)}: ${String(r.filePath)}`;\n case \"Edit\":\n return `Edited ${String(r.filePath)}`;\n case \"ApplyPatch\":\n return `${Array.isArray(r.changes) ? r.changes.length : 0} file changes`;\n default:\n return JSON.stringify(result).slice(0, 200);\n }\n}\n\n/**\n * Detect file-change events from a tool result, returning zero or more `file_changed` events.\n *\n * Handles `Write` (single create/edit), `Edit` (single edit), and `ApplyPatch` (multi-file\n * patch with per-change `kind` classification). Returns an empty array for all other tools.\n *\n * @param toolName - Name of the tool that produced the result.\n * @param result - Raw tool result payload.\n * @returns Array of `file_changed` normalized events.\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport function detectFileChanges(toolName: string, result: unknown): NormalizedEvent[] {\n if (typeof result !== \"object\" || !result) return [];\n const r = result as Record<string, unknown>;\n\n if (toolName === \"Write\" && r.filePath) {\n return [\n {\n type: \"file_changed\",\n path: String(r.filePath),\n action: r.type === \"create\" ? \"create\" : \"edit\",\n },\n ];\n }\n if (toolName === \"Edit\" && r.filePath) {\n return [{ type: \"file_changed\", path: String(r.filePath), action: \"edit\" }];\n }\n if (toolName === \"ApplyPatch\" && Array.isArray(r.changes)) {\n return r.changes\n .filter(\n (change): change is { path: string; kind: \"add\" | \"delete\" | \"update\" } =>\n typeof change === \"object\" &&\n change !== null &&\n typeof (change as Record<string, unknown>).path === \"string\" &&\n typeof (change as Record<string, unknown>).kind === \"string\",\n )\n .map((change) => ({\n type: \"file_changed\" as const,\n path: change.path,\n action: change.kind === \"add\" ? \"create\" : change.kind === \"delete\" ? \"delete\" : \"edit\",\n }));\n }\n\n return [];\n}\n\n/**\n * Backward-compatible single-event helper; returns the first `file_changed` event or `null`.\n *\n * Prefer {@link detectFileChanges} for multi-file patches (e.g. `ApplyPatch`).\n *\n * @param toolName - Name of the tool that produced the result.\n * @param result - Raw tool result payload.\n * @returns First detected `file_changed` event, or `null`.\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport function detectFileChange(toolName: string, result: unknown): NormalizedEvent | null {\n return detectFileChanges(toolName, result)[0] ?? null;\n}\n","/**\n * BridgeRuntime — implements IAgentRuntime from @skaile/workspaces/types by wrapping\n * an AgentDriver + EventNormalizer. This is the primary integration point for\n * consumers that want normalized events from any driver.\n */\n\nimport type {\n AgentEvent,\n AgentPromptInput,\n AgentReconfigureOptions,\n AgentRuntimeConfig,\n IAgentRuntime,\n} from \"@skaile/workspaces/types\";\n\nimport { EventNormalizer } from \"./normalizer.js\";\nimport { toMergedRegistry } from \"./provider-registry-derive.js\";\nimport { createDriver } from \"./registry.js\";\nimport type { AgentConfig, AgentDriver } from \"./types.js\";\n\n/**\n * Implements `IAgentRuntime` from `@skaile/workspaces/types` by wrapping an {@link AgentDriver}\n * and an {@link EventNormalizer}.\n *\n * This is the primary integration point for consumers that want normalized `AgentEvent`\n * payloads from any driver without managing the driver lifecycle directly. Create via\n * {@link createRuntime} to avoid coupling to `BridgeRuntime` directly.\n *\n * @docLink packages/bridge/api-reference#runtime\n */\nexport class BridgeRuntime implements IAgentRuntime {\n private driver: AgentDriver | null = null;\n private normalizer = new EventNormalizer();\n private handlers = new Set<(event: AgentEvent) => void>();\n private boundEventHandler: ((event: any) => void) | null = null;\n private driverId: string;\n\n constructor(driverId: string = \"claude-sdk\") {\n this.driverId = driverId;\n }\n\n async start(config: AgentRuntimeConfig): Promise<void> {\n // Dispose previous driver if any\n if (this.driver) {\n await this.dispose();\n }\n\n this.normalizer.reset();\n\n const bridgeConfig: AgentConfig = {\n cwd: config.cwd,\n model: config.model,\n systemPrompt: config.systemPrompt,\n env: config.env,\n agentDir: config.agentDir,\n sessionId: config.sessionId,\n resumeSessionId: config.resumeSessionId,\n maxTurns: config.maxTurns,\n ...(config.registry ? { registry: toMergedRegistry(config.registry, \"runtime\") } : {}),\n ...(config.modelRef ? { modelRef: config.modelRef } : {}),\n };\n\n this.driver = await createDriver(this.driverId, bridgeConfig);\n\n // Wire bridge events through normalizer to handlers\n this.boundEventHandler = (bridgeEvent: any) => {\n const normalized = this.normalizer.normalize(bridgeEvent);\n for (const event of normalized) {\n for (const handler of this.handlers) {\n handler(event);\n }\n }\n };\n this.driver.on(\"agent-event\", this.boundEventHandler);\n\n await this.driver.start();\n }\n\n async configure(_config: AgentReconfigureOptions): Promise<void> {\n // Runtime reconfiguration for BridgeRuntime is a no-op for now.\n // Future: reconnect connectors, reload ai-assets, update subagents.\n }\n\n async prompt(message: string): Promise<void> {\n if (!this.driver) throw new Error(\"Runtime not started — call start() first\");\n await this.driver.prompt(message);\n }\n\n async promptInput(input: AgentPromptInput): Promise<void> {\n if (!this.driver) throw new Error(\"Runtime not started — call start() first\");\n await this.driver.promptInput(input);\n }\n\n async reply(answer: string, question?: string, requestId?: string): Promise<void> {\n if (!this.driver) throw new Error(\"Runtime not started — call start() first\");\n // Mirror serve.ts handleReply: an answer must resume the paused turn. Falling through to\n // prompt() would deny the question as superseded and drop the structured answer.\n if (\n this.driver?.hasPendingQuestion() &&\n this.driver.answerQuestion(answer, question, requestId)\n )\n return;\n if (this.driver?.acceptsReplyAsPrompt) await this.prompt(answer);\n }\n\n async abort(): Promise<void> {\n if (this.driver) {\n await this.driver.abort();\n }\n }\n\n async dispose(): Promise<void> {\n if (this.driver) {\n if (this.boundEventHandler) {\n this.driver.off(\"agent-event\", this.boundEventHandler);\n this.boundEventHandler = null;\n }\n this.driver.kill();\n this.driver = null;\n }\n this.normalizer.reset();\n }\n\n onEvent(handler: (event: AgentEvent) => void): void {\n this.handlers.add(handler);\n }\n\n offEvent(handler: (event: AgentEvent) => void): void {\n this.handlers.delete(handler);\n }\n\n get isRunning(): boolean {\n return this.driver?.isRunning ?? false;\n }\n}\n\n/**\n * Factory function to create a {@link BridgeRuntime} with the specified driver.\n *\n * @param driverId - Registered driver id (default: `\"claude-sdk\"`).\n * @returns A new `IAgentRuntime` wrapping the selected driver with event normalization.\n * @docLink packages/bridge/api-reference#runtime\n */\nexport function createRuntime(driverId: string = \"claude-sdk\"): IAgentRuntime {\n return new BridgeRuntime(driverId);\n}\n","/** Provider API key validation — hits each provider's models endpoint to verify the key works. */\n\nimport {\n buildCredentialHeaders,\n expandPreset,\n getProviderPreset,\n resolvePresetBaseUrl,\n resolveProbeUrl,\n} from \"./provider-catalog.js\";\n\n/**\n * Result of an API key validation check performed by {@link validateApiKey}.\n *\n * @docLink packages/bridge/api-reference#validation\n */\nexport interface ValidationResult {\n /** `true` when the API key was accepted by the provider's models endpoint. */\n ok: boolean;\n /** Human-readable error description when `ok` is `false`. */\n error?: string;\n}\n\n/**\n * Validate an API key by sending a lightweight GET request to the provider's models endpoint.\n *\n * Returns `{ ok: true }` when the provider accepts the key (HTTP 2xx). Returns\n * `{ ok: false, error }` on 401/403 (invalid key), other HTTP errors, network failures,\n * or unsupported providers. Requests time out after 8 seconds.\n *\n * @param provider - Catalog preset id (e.g. `\"anthropic\"`, `\"openai\"`, `\"google\"`).\n * @param key - API key to validate.\n * @param options - Optional base-URL / environment overrides; defaults to the\n * provider's own API, or its `base_url_env` value when one is set.\n * @returns Validation result with optional error description.\n * @docLink packages/bridge/api-reference#validation\n */\nexport async function validateApiKey(\n provider: string,\n key: string,\n options: { baseUrl?: string; env?: Record<string, string | undefined> } = {},\n): Promise<ValidationResult> {\n const preset = getProviderPreset(provider);\n if (!preset) return { ok: false, error: `Unknown provider: ${provider}` };\n\n // Validate against the same endpoint discovery/dispatch use: behind a gateway\n // the key is the gateway's, and the provider's public API would reject it.\n const baseUrl = resolvePresetBaseUrl(preset, {\n ...(options.baseUrl ? { baseUrl: options.baseUrl } : {}),\n env: options.env ?? process.env,\n });\n const entry = expandPreset(preset, baseUrl ? { baseUrl } : {});\n const url = resolveProbeUrl(entry);\n if (!url) return { ok: false, error: `Provider ${provider} exposes no models endpoint` };\n // Static non-secret headers (Anthropic's `anthropic-version`) plus the\n // credential carrier the preset's `auth_header` names.\n const headers = { ...entry.headers, ...buildCredentialHeaders(entry, key) };\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 8000);\n\n const response = await fetch(url, {\n method: \"GET\",\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) return { ok: true };\n\n const status = response.status;\n if (status === 401 || status === 403) {\n return { ok: false, error: \"Invalid API key (authentication failed)\" };\n }\n return { ok: false, error: `API returned HTTP ${status}` };\n } catch (err: any) {\n if (err.name === \"AbortError\") return { ok: false, error: \"Request timed out (8s)\" };\n return { ok: false, error: err.message ?? \"Network error\" };\n }\n}\n"]}
1
+ {"version":3,"sources":["../bridge/src/normalizer.ts","../bridge/src/runtime.ts","../bridge/src/validation.ts"],"names":[],"mappings":"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","file":"chunk-3VUHHDZW.js","sourcesContent":["/**\n * EventNormalizer — converts bridge-level AgentEvent (raw driver events) to\n * skaile-agent-types AgentEvent (normalized, human-readable events).\n *\n * Stateful: tracks active subagents and dev-server detection across a session.\n * Call reset() between sessions.\n */\n\nimport {\n type AgentEvent as NormalizedEvent,\n type NativeApprovalDescription,\n stripActivityLabel,\n TOOL_ACTIVITY_LABEL_MAX_CHARS,\n TOOL_ACTIVITY_LABEL_PARAM,\n} from \"@skaile/workspaces/types\";\nimport { classifyClaudeSdkError } from \"./error-classifier.js\";\nimport type { AgentMessage, AgentEvent as BridgeEvent, ContentBlock } from \"./types.js\";\n\n/**\n * The optional usage keys a `result` event carries, in the shape both\n * `finished` and a result-sourced `error` emit them. Absent keys stay absent.\n */\nfunction resultUsageFields(\n event: Pick<\n Extract<BridgeEvent, { type: \"result\" | \"error\" }>,\n \"tokens\" | \"modelUsage\" | \"contextTokens\" | \"contextWindow\"\n >,\n) {\n return {\n ...(event.tokens ? { tokens: event.tokens } : {}),\n ...(event.modelUsage ? { modelUsage: event.modelUsage } : {}),\n ...(typeof event.contextTokens === \"number\" ? { contextTokens: event.contextTokens } : {}),\n ...(typeof event.contextWindow === \"number\" ? { contextWindow: event.contextWindow } : {}),\n };\n}\n\n/**\n * The tool a driver uses to park a turn on a human answer. Both branches that\n * recognise it must use this constant: `message_start` turns it into a\n * `question`, and `tool_call` must then stay silent about it.\n */\nconst QUESTION_TOOL = \"AskUserQuestion\";\n\nconst MAX_ANNOUNCED_TOOL_USES = 64;\n\n/**\n * Bridge `tool_call` inputs are loosely typed: Codex MCP arguments may arrive\n * as a JSON string, and the echo driver passes a bare path.\n */\nfunction toolInputRecord(input: unknown): Record<string, unknown> {\n let value = input;\n if (typeof value === \"string\") {\n try {\n value = JSON.parse(value);\n } catch {\n return { input };\n }\n }\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return value === undefined ? {} : { input };\n}\n\n/**\n * Converts raw bridge-level {@link BridgeEvent} payloads into normalized\n * `@skaile/workspaces/types` `AgentEvent` payloads consumed by the runner and transport.\n *\n * Stateful: tracks active subagents and dev-server detection across a session.\n * Call {@link EventNormalizer.reset} between sessions to clear accumulated state.\n *\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport class EventNormalizer {\n private activeSubagents = new Map<string, string>();\n private devServerStartingEmitted = false;\n private devServerReadyEmitted = false;\n /** True when message_update deltas have been emitted for the current message. */\n private hasStreamedText = false;\n /**\n * True once a `_thinkingDelta` run has been reported as `status: thinking`;\n * cleared by the next text delta or assistant message, so a run reports once.\n */\n private thinkingAnnounced = false;\n /**\n * tool_use blocks `message_start` already reported, awaiting the driver's\n * matching bridge `tool_call` — which must then not report the call again.\n */\n private announcedToolUses: Array<{ id?: string; name: string }> = [];\n\n /**\n * Convert a single bridge event into zero or more normalized events.\n * One bridge event can produce multiple normalized events (e.g., a message_start\n * with text + tool_use blocks produces both text and tool_call events).\n */\n normalize(event: BridgeEvent): NormalizedEvent[] {\n switch (event.type) {\n case \"message_start\":\n return this.handleMessageStart(event.message);\n\n case \"message_update\":\n return this.handleMessageUpdate(event);\n\n case \"message_end\":\n return [];\n\n case \"message_retract\":\n // The replay streams its reply afresh, so its deltas (or, failing\n // those, its message_start text) must count as a new message.\n this.hasStreamedText = false;\n return event.text ? [{ type: \"text_retract\", content: event.text }] : [];\n\n case \"turn_end\":\n return this.handleTurnEnd(event.toolResults);\n\n case \"result\":\n return this.handleResult(event);\n\n case \"error\":\n this.announcedToolUses = [];\n return [\n {\n type: \"error\",\n message: event.error,\n fatal: event.fatal ?? true,\n category: event.detail?.category,\n ...(event.detail?.hint ? { hint: event.detail.hint } : {}),\n ...resultUsageFields(event),\n ...(event.retrying === true\n ? { retrying: true, ...(event.retryReason ? { retryReason: event.retryReason } : {}) }\n : {}),\n },\n ];\n\n case \"tool_call\": {\n // The question tool parks the turn on the user's answer, so reporting\n // work here would undo the idle its `question` event just set, and\n // nothing follows to correct it while the user reads the prompt.\n const toolName = event.name ?? event.tool?.name;\n if (toolName === QUESTION_TOOL) return [];\n // A driver that also sent the call as a `message_start` tool_use block\n // (Claude) was already reported there; the rest only ever send this.\n if (!toolName || this.consumeAnnouncedToolUse(toolName, event.toolCallId)) {\n return [{ type: \"status\", phase: \"working\" }];\n }\n return this.handleToolUse(\n {\n type: \"tool_use\",\n id: typeof event.toolCallId === \"string\" ? event.toolCallId : undefined,\n name: toolName,\n input: toolInputRecord(event.input),\n },\n typeof event.parentToolUseId === \"string\" ? event.parentToolUseId : undefined,\n );\n }\n\n case \"tool_execution_end\":\n return [];\n\n case \"agent_end\":\n this.announcedToolUses = [];\n return [{ type: \"status\", phase: \"idle\" }];\n\n case \"commands_available\":\n // Pass through to transport — the gateway caches this event\n return [event as unknown as NormalizedEvent];\n\n case \"session_info\":\n // Pass through to transport — the forge layer stores the OMP session ID\n return [event as unknown as NormalizedEvent];\n\n case \"ui_render\":\n case \"ui_render_update\":\n case \"ui_clear\":\n // Pass through verbatim — drivers that implement the Agent UI Protocol emit these directly\n return [event as unknown as NormalizedEvent];\n\n default:\n return [];\n }\n }\n\n /** Clear all stateful tracking between sessions. */\n reset(): void {\n this.activeSubagents.clear();\n this.devServerStartingEmitted = false;\n this.devServerReadyEmitted = false;\n this.hasStreamedText = false;\n this.thinkingAnnounced = false;\n this.announcedToolUses = [];\n }\n\n private consumeAnnouncedToolUse(name: string, id: unknown): boolean {\n const callId = typeof id === \"string\" ? id : undefined;\n const index = this.announcedToolUses.findIndex(\n (entry) => entry.name === name && (!callId || !entry.id || entry.id === callId),\n );\n if (index === -1) return false;\n this.announcedToolUses.splice(index, 1);\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // message_start → text, tool_call, question, subagent\n // ---------------------------------------------------------------------------\n\n private handleMessageStart(message: AgentMessage): NormalizedEvent[] {\n // Only process assistant messages. Drivers (e.g. omp) may echo the user's\n // message as a message_start with role:\"user\" before streaming the response.\n // Emitting a text event for that echo would prepend the user's input to the\n // assistant bubble on the frontend.\n if (message.role !== \"assistant\") return [];\n\n // A subagent's message is not the main reply: its text belongs to the\n // subagent's own result, and it must not reset the main stream's state.\n const parentToolUseId = message.parentToolUseId;\n const events: NormalizedEvent[] = [];\n const blocks = this.getContentBlocks(message);\n\n for (const block of blocks) {\n if (block.type === \"text\" && block.text) {\n if (parentToolUseId) continue;\n // Skip full text if we already streamed it via message_update deltas\n if (!this.hasStreamedText) {\n events.push({ type: \"text\", content: block.text });\n }\n } else if (block.type === \"tool_use\" && block.name) {\n if (block.name !== QUESTION_TOOL) {\n this.announcedToolUses.push({ id: block.id, name: block.name });\n // Bounded in case a driver never echoes a block as a tool_call.\n if (this.announcedToolUses.length > MAX_ANNOUNCED_TOOL_USES) {\n this.announcedToolUses.shift();\n }\n }\n events.push(...this.handleToolUse(block, parentToolUseId));\n }\n }\n\n if (!parentToolUseId) this.hasStreamedText = false;\n if (!parentToolUseId) this.thinkingAnnounced = false;\n return events;\n }\n\n private handleToolUse(block: ContentBlock, parentToolUseId?: string): NormalizedEvent[] {\n const name = block.name!;\n const input = (block.input ?? {}) as Record<string, unknown>;\n\n if (name === QUESTION_TOOL) {\n return this.handleAskUserQuestion(input);\n }\n if (name === \"Agent\") {\n return this.handleAgentToolUse(block, input);\n }\n return this.handleGenericToolUse(name, input, parentToolUseId);\n }\n\n private handleAskUserQuestion(input: Record<string, unknown>): NormalizedEvent[] {\n const events: NormalizedEvent[] = [];\n const candidate = input.approval as Partial<NativeApprovalDescription> | undefined;\n const approval =\n candidate &&\n [\"command\", \"file\", \"permissions\", \"mcp\"].includes(candidate.kind ?? \"\") &&\n Array.isArray(candidate.details) &&\n candidate.details.length > 0 &&\n candidate.details.length <= 64 &&\n candidate.details.every((detail) => typeof detail === \"string\" && detail.length <= 8192) &&\n candidate.details.reduce((total, detail) => total + detail.length, 0) <= 65536\n ? (candidate as NativeApprovalDescription)\n : undefined;\n if (Object.hasOwn(input, \"approval\") && !approval) return [];\n // Claude SDK sends { questions: [{ question, header, options: [{ label, description }] }] }\n // Legacy/simple format sends { question: string, options?: string[] }\n const questions = input.questions;\n if (Array.isArray(questions)) {\n for (const q of questions) {\n const qObj = q as Record<string, unknown>;\n const question = String(qObj.question ?? \"\");\n const rawOpts = qObj.options;\n const options = Array.isArray(rawOpts)\n ? rawOpts.map((o: any) => (typeof o === \"string\" ? o : String(o.label ?? o)))\n : undefined;\n events.push({\n type: \"question\",\n question,\n options,\n ...(typeof input.requestId === \"string\" ? { requestId: input.requestId } : {}),\n ...(approval ? { approval } : {}),\n });\n }\n } else {\n const question = String(input.question ?? input.text ?? \"\");\n const rawOptions = input.options;\n const options = Array.isArray(rawOptions) ? rawOptions.map(String) : undefined;\n events.push({\n type: \"question\",\n question,\n options,\n ...(typeof input.requestId === \"string\" ? { requestId: input.requestId } : {}),\n ...(approval ? { approval } : {}),\n });\n }\n return events;\n }\n\n private handleAgentToolUse(\n block: ContentBlock,\n input: Record<string, unknown>,\n ): NormalizedEvent[] {\n const agentName = String(input.subagent_type ?? input.description ?? \"unknown\");\n const description = String(input.description ?? input.prompt ?? \"\").slice(0, 200);\n if (block.id) {\n this.activeSubagents.set(block.id, agentName);\n }\n return [\n { type: \"subagent\", name: agentName, status: \"started\", description },\n { type: \"status\", phase: \"working\" },\n ];\n }\n\n private handleGenericToolUse(\n name: string,\n input: Record<string, unknown>,\n parentToolUseId?: string,\n ): NormalizedEvent[] {\n const events: NormalizedEvent[] = [];\n const label = labelToolCall(name, input);\n events.push({\n type: \"tool_call\",\n tool: name,\n input,\n // Summarize without the label: it would eat the default branch's\n // 100-char argument budget and push the real args out.\n summary: summarizeToolCall(name, stripActivityLabel(input)),\n ...(label ? { label } : {}),\n ...(parentToolUseId ? { parentToolUseId } : {}),\n });\n events.push({ type: \"status\", phase: \"working\" });\n\n if (name === \"Bash\" && typeof input.command === \"string\") {\n const devEvent = this.detectDevServerStarting(input.command);\n if (devEvent) events.push(devEvent);\n }\n\n return events;\n }\n\n // ---------------------------------------------------------------------------\n // message_update → streaming text\n // ---------------------------------------------------------------------------\n\n private handleMessageUpdate(event: BridgeEvent): NormalizedEvent[] {\n // Bridge deltas carry no subagent tag: a driver must drop a subagent's\n // partials itself (claude-sdk does in handleStreamEvent), or they read as main text.\n const delta = (event as any)._textDelta as string | undefined;\n if (delta) {\n this.hasStreamedText = true;\n this.thinkingAnnounced = false;\n return [{ type: \"text\", content: delta }];\n }\n // The protocol has no thinking-content event, so reasoning surfaces as the\n // existing `thinking` phase, once per run. The text is never forwarded as\n // `text`; a driver keeps it out of `_textDelta`.\n const thinking: unknown = \"_thinkingDelta\" in event ? event._thinkingDelta : undefined;\n if (typeof thinking === \"string\" && thinking && !this.thinkingAnnounced) {\n this.thinkingAnnounced = true;\n return [{ type: \"status\", phase: \"thinking\" }];\n }\n return [];\n }\n\n // ---------------------------------------------------------------------------\n // turn_end → tool_result, subagent finished, file_changed, dev_server\n // ---------------------------------------------------------------------------\n\n private handleTurnEnd(toolResults?: AgentMessage[]): NormalizedEvent[] {\n if (!toolResults?.length) return [];\n\n const events: NormalizedEvent[] = [];\n\n for (const result of toolResults) {\n const toolName = result.toolName ?? \"unknown\";\n const outputData = result.data ?? result.content;\n const output = typeof outputData === \"string\" ? outputData : JSON.stringify(outputData);\n\n // Check if this is a subagent result\n if (toolName === \"Agent\" || this.isSubagentResult(result)) {\n events.push(...this.handleSubagentResult(result, output));\n } else {\n events.push(...this.handleToolResult(toolName, outputData, output, result.parentToolUseId));\n }\n }\n\n return events;\n }\n\n private handleSubagentResult(result: AgentMessage, output: string): NormalizedEvent[] {\n const events: NormalizedEvent[] = [];\n const agentName = this.resolveSubagentName(result);\n const description = output.slice(0, 200);\n events.push({ type: \"subagent\", name: agentName, status: \"finished\", description });\n\n if (agentName === \"dev-server\") {\n const devEvent = this.detectDevServerReady(output);\n if (devEvent) events.push(devEvent);\n }\n return events;\n }\n\n private handleToolResult(\n toolName: string,\n outputData: unknown,\n output: string,\n parentToolUseId?: string,\n ): NormalizedEvent[] {\n const events: NormalizedEvent[] = [];\n events.push({\n type: \"tool_result\",\n tool: toolName,\n output: outputData,\n summary: summarizeToolResult(toolName, outputData),\n ...(parentToolUseId ? { parentToolUseId } : {}),\n });\n\n // Detect file changes from Write/Edit results\n const fileEvents = detectFileChanges(toolName, outputData);\n if (fileEvents.length > 0) events.push(...fileEvents);\n\n // Detect dev server from Bash output\n if (toolName === \"Bash\") {\n const devEvent = this.detectDevServerReady(output);\n if (devEvent) events.push(devEvent);\n }\n return events;\n }\n\n private isSubagentResult(result: AgentMessage): boolean {\n // Check if the tool result's id maps to a tracked subagent\n if (result.toolName && this.activeSubagents.has(result.toolName)) return true;\n return false;\n }\n\n private resolveSubagentName(result: AgentMessage): string {\n // toolName on bridge AgentMessage is resolved from toolIdToName in the driver\n const name = result.toolName ? this.activeSubagents.get(result.toolName) : undefined;\n if (name) {\n this.activeSubagents.delete(result.toolName!);\n return name;\n }\n return result.toolName ?? \"unknown\";\n }\n\n // ---------------------------------------------------------------------------\n // result → finished or error\n // ---------------------------------------------------------------------------\n\n private handleResult(event: BridgeEvent & { type: \"result\" }): NormalizedEvent[] {\n const usage = resultUsageFields(event);\n if (event.subtype === \"success\") {\n return [\n {\n type: \"finished\",\n summary: event.summary ?? \"Task completed\",\n costUsd: event.costUsd ?? 0,\n ...usage,\n },\n ];\n }\n\n const errors = event.errors ?? [];\n // Run the same classifier the claude-sdk driver uses on its `error`\n // event so the result-error path also surfaces a category and hint\n // (drivers other than claude-sdk emit `result` without a paired\n // `error`, so this is the only place they get classified).\n const detail = classifyClaudeSdkError({ errors, subtype: event.subtype });\n // The turn billed even though it failed: carry its usage so a ledger\n // that only writes on `finished` can write here too. Unlike the finished\n // branch, no `costUsd: 0` fallback — an absent figure stays absent.\n return [\n {\n type: \"error\",\n message: `Agent stopped: ${event.subtype}${errors.length ? ` — ${errors.join(\"; \")}` : \"\"}`,\n fatal: event.subtype === \"error_during_execution\",\n category: detail.category,\n ...(detail.hint ? { hint: detail.hint } : {}),\n ...(typeof event.costUsd === \"number\" ? { costUsd: event.costUsd } : {}),\n ...usage,\n },\n ];\n }\n\n // ---------------------------------------------------------------------------\n // Dev server detection\n // ---------------------------------------------------------------------------\n\n private detectDevServerStarting(command: string): NormalizedEvent | null {\n if (this.devServerStartingEmitted) return null;\n const cmd = command.toLowerCase();\n const isFrontendStart =\n (cmd.includes(\"pnpm run dev\") || cmd.includes(\"pnpm dev\") || cmd.includes(\"vite\")) &&\n (cmd.includes(\"frontend\") || cmd.includes(\"dev:preview\"));\n if (isFrontendStart) {\n this.devServerStartingEmitted = true;\n return { type: \"dev_server\", url: \"http://localhost:3000\", status: \"starting\" };\n }\n return null;\n }\n\n private detectDevServerReady(text: string): NormalizedEvent | null {\n if (this.devServerReadyEmitted) return null;\n\n const explicitMatch = text.match(/DEVSERVER_READY:(https?:\\/\\/[^\\s\"\\\\]+)/);\n if (explicitMatch) {\n this.devServerReadyEmitted = true;\n return { type: \"dev_server\", url: explicitMatch[1]!, status: \"ready\" };\n }\n\n const viteMatch = text.match(/Local:\\s+(https?:\\/\\/localhost:\\d+)/);\n if (viteMatch) {\n this.devServerReadyEmitted = true;\n return { type: \"dev_server\", url: viteMatch[1]!, status: \"ready\" };\n }\n\n if (text.includes(\"FRONTEND_READY\")) {\n this.devServerReadyEmitted = true;\n return { type: \"dev_server\", url: \"http://localhost:3000\", status: \"ready\" };\n }\n\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n private getContentBlocks(message: AgentMessage): ContentBlock[] {\n if (Array.isArray(message.content)) return message.content;\n if (typeof message.content === \"string\" && message.content) {\n return [{ type: \"text\", text: message.content }];\n }\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pure helper functions (exported for reuse)\n// ---------------------------------------------------------------------------\n\n/**\n * Produce a human-readable one-line summary of a tool call for the activity log.\n *\n * Returns a string like `$ git status` for Bash, `Read src/index.ts` for Read, etc.\n * Falls back to `ToolName({...input...})` for unrecognised tools.\n *\n * @param tool - Tool name (e.g. `\"Bash\"`, `\"Write\"`, `\"Grep\"`).\n * @param input - Tool input record passed to the call.\n * @returns A short display string suitable for the activity feed.\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport function summarizeToolCall(tool: string, input: Record<string, unknown>): string {\n // A driver that sent a bare value instead of named args has it under `input`.\n const arg = (key: string) => String(input[key] ?? input.input);\n switch (tool) {\n case \"Bash\":\n return `$ ${String(input.command ?? input.input ?? \"\").slice(0, 200)}`;\n case \"Write\":\n return `Create ${arg(\"file_path\")}`;\n case \"Edit\":\n return `Edit ${arg(\"file_path\")}`;\n case \"Read\":\n return `Read ${arg(\"file_path\")}`;\n case \"Glob\":\n return `Find ${arg(\"pattern\")}`;\n case \"Grep\":\n return `Search for ${arg(\"pattern\")}`;\n case \"ApplyPatch\": {\n // Paths only: stringifying the input would serialize every full diff.\n const changes = Array.isArray(input.changes) ? input.changes : [];\n const paths = changes\n .map((change) => (change as { path?: unknown } | null)?.path)\n .filter((path): path is string => typeof path === \"string\");\n return `Edit ${paths.join(\", \").slice(0, 200) || \"files\"}`;\n }\n default:\n return `${tool}(${JSON.stringify(input).slice(0, 100)})`;\n }\n}\n\n/**\n * Produce the plain-language label shown to non-technical users while a tool\n * call runs: the agent's own `activity_label`, Bash's `description`, else a\n * derived phrase for Claude Code built-ins. `undefined` for any other tool —\n * the UI then falls back to a generic \"working\" line rather than raw input.\n *\n * @param tool - Tool name as the model called it.\n * @param input - Tool input record, still carrying `activity_label`.\n * @returns A trimmed label capped at `TOOL_ACTIVITY_LABEL_MAX_CHARS`, or `undefined`.\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport function labelToolCall(tool: string, input: Record<string, unknown>): string | undefined {\n const authored =\n nonEmpty(input[TOOL_ACTIVITY_LABEL_PARAM]) ??\n (tool === \"Bash\" ? nonEmpty(input.description) : undefined);\n const label = authored ?? builtinToolLabel(tool, input);\n if (!label) return undefined;\n return label.length > TOOL_ACTIVITY_LABEL_MAX_CHARS\n ? `${label.slice(0, TOOL_ACTIVITY_LABEL_MAX_CHARS - 1).trimEnd()}…`\n : label;\n}\n\nfunction nonEmpty(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.replace(/\\s+/g, \" \").trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction builtinToolLabel(tool: string, input: Record<string, unknown>): string | undefined {\n switch (tool) {\n case \"Read\":\n return withTarget(\"Reading\", baseName(input.file_path));\n case \"Edit\":\n case \"MultiEdit\":\n case \"NotebookEdit\":\n return withTarget(\"Editing\", baseName(input.file_path ?? input.notebook_path));\n case \"Write\":\n return withTarget(\"Creating\", baseName(input.file_path));\n case \"Grep\":\n case \"Glob\":\n return \"Searching files\";\n case \"WebSearch\":\n return \"Searching the web\";\n case \"WebFetch\":\n return withTarget(\"Fetching\", hostOf(input.url), \"a web page\");\n case \"TodoWrite\":\n return \"Updating the task list\";\n case \"ApplyPatch\":\n return \"Editing files\";\n default:\n return undefined;\n }\n}\n\nfunction withTarget(verb: string, target: string | undefined, fallback = \"a file\"): string {\n return `${verb} ${target ?? fallback}`;\n}\n\nfunction baseName(value: unknown): string | undefined {\n if (typeof value !== \"string\" || value.length === 0) return undefined;\n return value.split(/[\\\\/]/).filter(Boolean).pop();\n}\n\nfunction hostOf(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n try {\n return new URL(value).host || undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Extract plain text from an Anthropic content-block array (e.g. tool results returned by Claude SDK). */\nfunction extractContentBlockText(blocks: unknown[]): string | null {\n const textBlocks = blocks.filter(\n (b): b is { type: \"text\"; text: string } =>\n typeof b === \"object\" &&\n b !== null &&\n (b as Record<string, unknown>).type === \"text\" &&\n typeof (b as Record<string, unknown>).text === \"string\",\n );\n if (textBlocks.length === 0) return null;\n return textBlocks.map((b) => b.text).join(\"\\n\");\n}\n\n/**\n * Produce a human-readable one-line summary of a tool result for the activity log.\n *\n * Handles Bash stdout/stderr, Write/Edit file paths, ApplyPatch change counts, and\n * Anthropic content-block arrays. Falls back to `JSON.stringify` for unknown shapes.\n *\n * @param tool - Tool name.\n * @param result - Raw tool result payload.\n * @returns A short display string, truncated to 200 characters.\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport function summarizeToolResult(tool: string, result: unknown): string {\n // Handle Anthropic content-block arrays: [{ type: \"text\", text: \"...\" }, ...]\n if (Array.isArray(result)) {\n const text = extractContentBlockText(result);\n return (text ?? JSON.stringify(result)).slice(0, 200);\n }\n if (typeof result !== \"object\" || !result) {\n return String(result).slice(0, 200);\n }\n const r = result as Record<string, unknown>;\n switch (tool) {\n case \"Bash\": {\n const stderr = String(r.stderr ?? \"\").trim();\n if (stderr) return `stderr: ${stderr.slice(0, 200)}`;\n return (\n String(r.stdout ?? \"\")\n .trim()\n .slice(0, 200) || \"(no output)\"\n );\n }\n case \"Write\":\n return `${String(r.type)}: ${String(r.filePath)}`;\n case \"Edit\":\n return `Edited ${String(r.filePath)}`;\n case \"ApplyPatch\":\n return `${Array.isArray(r.changes) ? r.changes.length : 0} file changes`;\n default:\n return JSON.stringify(result).slice(0, 200);\n }\n}\n\n/**\n * Detect file-change events from a tool result, returning zero or more `file_changed` events.\n *\n * Handles `Write` (single create/edit), `Edit` (single edit), and `ApplyPatch` (multi-file\n * patch with per-change `kind` classification). Returns an empty array for all other tools.\n *\n * @param toolName - Name of the tool that produced the result.\n * @param result - Raw tool result payload.\n * @returns Array of `file_changed` normalized events.\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport function detectFileChanges(toolName: string, result: unknown): NormalizedEvent[] {\n if (typeof result !== \"object\" || !result) return [];\n const r = result as Record<string, unknown>;\n\n if (toolName === \"Write\" && r.filePath) {\n return [\n {\n type: \"file_changed\",\n path: String(r.filePath),\n action: r.type === \"create\" ? \"create\" : \"edit\",\n },\n ];\n }\n if (toolName === \"Edit\" && r.filePath) {\n return [{ type: \"file_changed\", path: String(r.filePath), action: \"edit\" }];\n }\n if (toolName === \"ApplyPatch\" && Array.isArray(r.changes)) {\n return r.changes\n .filter(\n (change): change is { path: string; kind: \"add\" | \"delete\" | \"update\" } =>\n typeof change === \"object\" &&\n change !== null &&\n typeof (change as Record<string, unknown>).path === \"string\" &&\n typeof (change as Record<string, unknown>).kind === \"string\",\n )\n .map((change) => ({\n type: \"file_changed\" as const,\n path: change.path,\n action: change.kind === \"add\" ? \"create\" : change.kind === \"delete\" ? \"delete\" : \"edit\",\n }));\n }\n\n return [];\n}\n\n/**\n * Backward-compatible single-event helper; returns the first `file_changed` event or `null`.\n *\n * Prefer {@link detectFileChanges} for multi-file patches (e.g. `ApplyPatch`).\n *\n * @param toolName - Name of the tool that produced the result.\n * @param result - Raw tool result payload.\n * @returns First detected `file_changed` event, or `null`.\n * @docLink packages/bridge/api-reference#normalizer\n */\nexport function detectFileChange(toolName: string, result: unknown): NormalizedEvent | null {\n return detectFileChanges(toolName, result)[0] ?? null;\n}\n","/**\n * BridgeRuntime — implements IAgentRuntime from @skaile/workspaces/types by wrapping\n * an AgentDriver + EventNormalizer. This is the primary integration point for\n * consumers that want normalized events from any driver.\n */\n\nimport type {\n AgentEvent,\n AgentPromptInput,\n AgentReconfigureOptions,\n AgentRuntimeConfig,\n IAgentRuntime,\n} from \"@skaile/workspaces/types\";\n\nimport { EventNormalizer } from \"./normalizer.js\";\nimport { toMergedRegistry } from \"./provider-registry-derive.js\";\nimport { createDriver } from \"./registry.js\";\nimport type { AgentConfig, AgentDriver } from \"./types.js\";\n\n/**\n * Implements `IAgentRuntime` from `@skaile/workspaces/types` by wrapping an {@link AgentDriver}\n * and an {@link EventNormalizer}.\n *\n * This is the primary integration point for consumers that want normalized `AgentEvent`\n * payloads from any driver without managing the driver lifecycle directly. Create via\n * {@link createRuntime} to avoid coupling to `BridgeRuntime` directly.\n *\n * @docLink packages/bridge/api-reference#runtime\n */\nexport class BridgeRuntime implements IAgentRuntime {\n private driver: AgentDriver | null = null;\n private normalizer = new EventNormalizer();\n private handlers = new Set<(event: AgentEvent) => void>();\n private boundEventHandler: ((event: any) => void) | null = null;\n private driverId: string;\n\n constructor(driverId: string = \"claude-sdk\") {\n this.driverId = driverId;\n }\n\n async start(config: AgentRuntimeConfig): Promise<void> {\n // Dispose previous driver if any\n if (this.driver) {\n await this.dispose();\n }\n\n this.normalizer.reset();\n\n const bridgeConfig: AgentConfig = {\n cwd: config.cwd,\n model: config.model,\n systemPrompt: config.systemPrompt,\n env: config.env,\n agentDir: config.agentDir,\n sessionId: config.sessionId,\n resumeSessionId: config.resumeSessionId,\n maxTurns: config.maxTurns,\n ...(config.registry ? { registry: toMergedRegistry(config.registry, \"runtime\") } : {}),\n ...(config.modelRef ? { modelRef: config.modelRef } : {}),\n };\n\n this.driver = await createDriver(this.driverId, bridgeConfig);\n\n // Wire bridge events through normalizer to handlers\n this.boundEventHandler = (bridgeEvent: any) => {\n const normalized = this.normalizer.normalize(bridgeEvent);\n for (const event of normalized) {\n for (const handler of this.handlers) {\n handler(event);\n }\n }\n };\n this.driver.on(\"agent-event\", this.boundEventHandler);\n\n await this.driver.start();\n }\n\n async configure(_config: AgentReconfigureOptions): Promise<void> {\n // Runtime reconfiguration for BridgeRuntime is a no-op for now.\n // Future: reconnect connectors, reload ai-assets, update subagents.\n }\n\n async prompt(message: string): Promise<void> {\n if (!this.driver) throw new Error(\"Runtime not started — call start() first\");\n await this.driver.prompt(message);\n }\n\n async promptInput(input: AgentPromptInput): Promise<void> {\n if (!this.driver) throw new Error(\"Runtime not started — call start() first\");\n await this.driver.promptInput(input);\n }\n\n async reply(answer: string, question?: string, requestId?: string): Promise<void> {\n if (!this.driver) throw new Error(\"Runtime not started — call start() first\");\n // Mirror serve.ts handleReply: an answer must resume the paused turn. Falling through to\n // prompt() would deny the question as superseded and drop the structured answer.\n if (\n this.driver?.hasPendingQuestion() &&\n this.driver.answerQuestion(answer, question, requestId)\n )\n return;\n if (this.driver?.acceptsReplyAsPrompt) await this.prompt(answer);\n }\n\n async abort(): Promise<void> {\n if (this.driver) {\n await this.driver.abort();\n }\n }\n\n async dispose(): Promise<void> {\n if (this.driver) {\n if (this.boundEventHandler) {\n this.driver.off(\"agent-event\", this.boundEventHandler);\n this.boundEventHandler = null;\n }\n this.driver.kill();\n this.driver = null;\n }\n this.normalizer.reset();\n }\n\n onEvent(handler: (event: AgentEvent) => void): void {\n this.handlers.add(handler);\n }\n\n offEvent(handler: (event: AgentEvent) => void): void {\n this.handlers.delete(handler);\n }\n\n get isRunning(): boolean {\n return this.driver?.isRunning ?? false;\n }\n}\n\n/**\n * Factory function to create a {@link BridgeRuntime} with the specified driver.\n *\n * @param driverId - Registered driver id (default: `\"claude-sdk\"`).\n * @returns A new `IAgentRuntime` wrapping the selected driver with event normalization.\n * @docLink packages/bridge/api-reference#runtime\n */\nexport function createRuntime(driverId: string = \"claude-sdk\"): IAgentRuntime {\n return new BridgeRuntime(driverId);\n}\n","/** Provider API key validation — hits each provider's models endpoint to verify the key works. */\n\nimport {\n buildCredentialHeaders,\n expandPreset,\n getProviderPreset,\n resolvePresetBaseUrl,\n resolveProbeUrl,\n} from \"./provider-catalog.js\";\n\n/**\n * Result of an API key validation check performed by {@link validateApiKey}.\n *\n * @docLink packages/bridge/api-reference#validation\n */\nexport interface ValidationResult {\n /** `true` when the API key was accepted by the provider's models endpoint. */\n ok: boolean;\n /** Human-readable error description when `ok` is `false`. */\n error?: string;\n}\n\n/**\n * Validate an API key by sending a lightweight GET request to the provider's models endpoint.\n *\n * Returns `{ ok: true }` when the provider accepts the key (HTTP 2xx). Returns\n * `{ ok: false, error }` on 401/403 (invalid key), other HTTP errors, network failures,\n * or unsupported providers. Requests time out after 8 seconds.\n *\n * @param provider - Catalog preset id (e.g. `\"anthropic\"`, `\"openai\"`, `\"google\"`).\n * @param key - API key to validate.\n * @param options - Optional base-URL / environment overrides; defaults to the\n * provider's own API, or its `base_url_env` value when one is set.\n * @returns Validation result with optional error description.\n * @docLink packages/bridge/api-reference#validation\n */\nexport async function validateApiKey(\n provider: string,\n key: string,\n options: { baseUrl?: string; env?: Record<string, string | undefined> } = {},\n): Promise<ValidationResult> {\n const preset = getProviderPreset(provider);\n if (!preset) return { ok: false, error: `Unknown provider: ${provider}` };\n\n // Validate against the same endpoint discovery/dispatch use: behind a gateway\n // the key is the gateway's, and the provider's public API would reject it.\n const baseUrl = resolvePresetBaseUrl(preset, {\n ...(options.baseUrl ? { baseUrl: options.baseUrl } : {}),\n env: options.env ?? process.env,\n });\n const entry = expandPreset(preset, baseUrl ? { baseUrl } : {});\n const url = resolveProbeUrl(entry);\n if (!url) return { ok: false, error: `Provider ${provider} exposes no models endpoint` };\n // Static non-secret headers (Anthropic's `anthropic-version`) plus the\n // credential carrier the preset's `auth_header` names.\n const headers = { ...entry.headers, ...buildCredentialHeaders(entry, key) };\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 8000);\n\n const response = await fetch(url, {\n method: \"GET\",\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) return { ok: true };\n\n const status = response.status;\n if (status === 401 || status === 403) {\n return { ok: false, error: \"Invalid API key (authentication failed)\" };\n }\n return { ok: false, error: `API returned HTTP ${status}` };\n } catch (err: any) {\n if (err.name === \"AbortError\") return { ok: false, error: \"Request timed out (8s)\" };\n return { ok: false, error: err.message ?? \"Network error\" };\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { getStoreConfig, getStoreToken, storeFetch } from './chunk-TB3LJ6NA.js';
2
- import { S, logErr, logWarn, logOk, logInfo } from './chunk-FDZL5QVZ.js';
1
+ import { getStoreConfig, getStoreToken, storeFetch } from './chunk-MDBAEEY5.js';
2
+ import { S, logErr, logWarn, logOk, logInfo } from './chunk-L22WTIIC.js';
3
3
 
4
4
  // cli/src/store-publisher.ts
5
5
  function makeHttpPublisherClient(config = getStoreConfig(), timeoutMs = 2e4) {
@@ -154,5 +154,5 @@ async function publishToStore(opts) {
154
154
  }
155
155
 
156
156
  export { bareName, formatNamespaceAvailability, makeHttpPublisherClient, preflightNamespace, publishToStore, refFor };
157
- //# sourceMappingURL=chunk-LA7DCX2U.js.map
158
- //# sourceMappingURL=chunk-LA7DCX2U.js.map
157
+ //# sourceMappingURL=chunk-422WJ2QC.js.map
158
+ //# sourceMappingURL=chunk-422WJ2QC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../cli/src/store-publisher.ts","../cli/src/commands/publish-core.ts"],"names":[],"mappings":"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","file":"chunk-LA7DCX2U.js","sourcesContent":["/**\n * Typed REST client for the AI Asset Store **publisher** surface — the\n * curator-publish flow (`skaile source manifest publish` / `yank`). Thin\n * wrappers over {@link storeFetch}; every method maps 1:1 to an `/api/v1/…`\n * endpoint. The {@link PublisherClient} interface is injectable so the\n * orchestration in `commands/source-manifest-publish.ts` can be unit-tested\n * against a fake without a live store.\n *\n * @docLink cli/dev-guide#store-publisher\n */\n\nimport { getStoreConfig, getStoreToken, type StoreConfig, storeFetch } from \"./store-client.ts\";\n\n/**\n * The publisher REST surface used by the curator-publish flow. Kept minimal —\n * only the endpoints `runPublish` / `runYank` actually call. Response shapes\n * are narrowed to the fields the orchestration reads (the server returns more).\n */\nexport interface PublisherClient {\n /**\n * Identity of the caller. `username` is the Keycloak login (personal-tier\n * namespace); `githubLogin` is the verified GitHub handle when connected —\n * the namespace to publish under when it differs from the login.\n */\n me(): Promise<{ username: string; githubLogin?: string | null }>;\n /** Register (or re-register) a source; returns the created/existing row id. */\n sourcesAdd(body: {\n url: string;\n ref: string;\n sidecarUrl?: string;\n sidecarRef?: string;\n /**\n * Target publisher namespace (the manifest's `publisher`). When it differs\n * from the caller's login username, the store resolves the CLAIMED Publisher\n * for it (the store must already have the claim). Omitted → the store\n * defaults to `@<username>` (personal).\n */\n namespace?: string;\n }): Promise<{ id: string }>;\n /** List sources — used to recover an id when `sourcesAdd` rejects a dup url. */\n sourcesList(): Promise<Array<{ id: string; url: string }>>;\n /** Kick off a source sync; returns the async job id to poll. */\n sourceSync(id: string): Promise<{ jobId: string }>;\n /** Poll a job's terminal status + per-item results. */\n jobGet(\n jobId: string,\n ): Promise<{ status: string; items?: Array<{ label: string; status: string; error?: string }> }>;\n /** Discovered publishable candidates for a synced source. */\n sourceCandidates(id: string): Promise<\n Array<{\n id: string;\n name: string;\n version: string;\n kind: string;\n published: boolean;\n assetRoot: string;\n }>\n >;\n /** Per-asset preview — the discovered file set + resolved candidate metadata. */\n assetPreview(id: string): Promise<{\n discoveredFiles: string[];\n candidate: { name: string; version: string; kind: string; publisherNamespace: string };\n }>;\n /**\n * Publish one asset. `dryRun` returns the would-be `{ manifest }` without\n * launching a job; the normal path returns `{ jobId }`.\n */\n assetPublish(\n id: string,\n body: { ref: string; files: string[] },\n dryRun?: boolean,\n ): Promise<{ jobId?: string; manifest?: unknown }>;\n /** Retract a published asset. Response body is ignored. */\n assetUnpublish(id: string): Promise<unknown>;\n /**\n * Read-only \"can I publish under `@<ns>` right now, and if not, what's the\n * path?\" probe. Backs the `publish --dry-run` namespace status line; its\n * `message` is store-authored and meant to be surfaced verbatim.\n */\n namespaceAvailability(ns: string): Promise<{\n namespace: string;\n status: \"owned-by-you\" | \"claimable-by-you\" | \"reserved\" | \"available\";\n claimMethod?: string;\n message: string;\n }>;\n}\n\n/**\n * Construct the real HTTP-backed {@link PublisherClient}. Every call carries a\n * longer timeout than the default store client because publish/sync trigger\n * server-side clone work.\n *\n * @param config - Store connection config; defaults to {@link getStoreConfig}.\n * @param timeoutMs - Per-request abort timeout (default 20s).\n */\nexport function makeHttpPublisherClient(\n config: StoreConfig = getStoreConfig(),\n timeoutMs = 20_000,\n): PublisherClient {\n // Acquire a fresh Keycloak token per call (device-flow session in\n // ~/.skaile/auth.json, refreshed on demand) rather than a static config.jwt.\n const call = async <T>(\n path: string,\n opts?: { method?: string; body?: unknown; params?: Record<string, string> },\n ): Promise<T> => {\n const jwt = await getStoreToken();\n return storeFetch<T>({ ...config, jwt }, path, { timeoutMs, ...opts });\n };\n return {\n me: () => call(\"/api/v1/me\"),\n sourcesAdd: (body) => call(\"/api/v1/sources\", { method: \"POST\", body }),\n sourcesList: () => call(\"/api/v1/sources\"),\n sourceSync: (id) => call(`/api/v1/sources/${id}/sync`, { method: \"POST\", body: {} }),\n jobGet: (jobId) => call(`/api/v1/jobs/${jobId}`),\n sourceCandidates: (id) => call(`/api/v1/sources/${id}/candidates`),\n assetPreview: (id) => call(`/api/v1/assets/${id}/preview`),\n assetPublish: (id, body, dryRun) =>\n call(`/api/v1/assets/${id}/publish`, {\n method: \"POST\",\n body,\n ...(dryRun ? { params: { dryRun: \"1\" } } : {}),\n }),\n assetUnpublish: (id) => call(`/api/v1/assets/${id}/unpublish`, { method: \"POST\", body: {} }),\n namespaceAvailability: (ns) =>\n call(`/api/v1/namespaces/${encodeURIComponent(ns)}/availability`),\n };\n}\n","/**\n * Shared store-interaction core for the two publish front-ends — the curator\n * sidecar flow (`source manifest publish`) and the first-party library flow\n * (`library publish`). Both differ only in their git side-effects + how they\n * resolve the source repo; the store orchestration below (register → sync →\n * candidates → per-asset preview+publish) is identical.\n *\n * The store REST surface is reached through the injectable {@link PublisherClient}\n * so the orchestration stays unit/integration-testable without a live store.\n *\n * @docLink cli/commands/source#manifest-publish\n */\n\nimport type { SkPublishManifest } from \"@skaile/workspaces/core\";\nimport { logErr, logInfo, logOk, logWarn, S } from \"../helpers.ts\";\nimport type { PublisherClient } from \"../store-publisher.ts\";\n\n/**\n * One-line rendering of a namespace-availability probe for a `--dry-run` plan.\n * The `message` is store-authored (identical to what a real publish would echo)\n * — we only prepend a status glyph so the reader sees green/amber/red at a\n * glance without the CLI re-deriving any authorization logic.\n */\nexport function formatNamespaceAvailability(a: {\n status: \"owned-by-you\" | \"claimable-by-you\" | \"reserved\" | \"available\";\n message: string;\n}): string {\n switch (a.status) {\n case \"owned-by-you\":\n case \"available\":\n return `${S.ok(\"✓\")} ${a.message}`;\n case \"claimable-by-you\":\n return `${S.warn(\"!\")} ${a.message}`;\n default:\n return `${S.err(\"✗\")} ${a.message}`;\n }\n}\n\n/**\n * Preflight the target namespace against the store's availability probe BEFORE a\n * publish does any irreversible work (a public git push). Returns `{ ok: false }`\n * with a guided message for `reserved` (not yours) and `claimable-by-you` (must\n * claim first) — the two states a real publish would reject — so the caller can\n * abort with actionable guidance instead of a raw 422 after pushing bytes.\n *\n * The probe is advisory: any failure (offline, older store) returns `{ ok: true }`\n * so the store stays the authority and a valid publish is never blocked.\n */\nexport async function preflightNamespace(\n client: PublisherClient,\n namespace: string,\n): Promise<{ ok: boolean; message?: string }> {\n let a: Awaited<ReturnType<PublisherClient[\"namespaceAvailability\"]>>;\n try {\n a = await client.namespaceAvailability(namespace);\n } catch {\n return { ok: true };\n }\n switch (a.status) {\n case \"owned-by-you\":\n case \"available\":\n return { ok: true };\n case \"claimable-by-you\":\n return {\n ok: false,\n message:\n `@${namespace} isn't yours yet — claim it in the store first` +\n `${a.claimMethod ? ` (${a.claimMethod})` : \"\"}, then re-run. ${a.message}`,\n };\n default: // reserved, or any unrecognized future status (fail safe → block)\n return { ok: false, message: `Cannot publish under @${namespace} — ${a.message}` };\n }\n}\n\n/** One candidate row shape the matcher operates on (kind + name are the key). */\ninterface CandidateLike {\n kind: string;\n name: string;\n}\n\n/**\n * Keep only candidates whose `(kind, name)` pair is declared in the manifest.\n * The backend may merge extra assets from the base repo into the candidate\n * list; a publish only touches what the manifest curated/declared.\n */\nexport function matchCandidatesToManifest<T extends CandidateLike>(\n candidates: T[],\n manifest: SkPublishManifest,\n): T[] {\n const wanted = new Set((manifest.assets ?? []).map((a) => `${a.kind}:${a.name}`));\n return candidates.filter((c) => wanted.has(`${c.kind}:${c.name}`));\n}\n\n/** A canonical ref string `kind:@publisher/name[#version]` for reporting. */\nexport function refFor(kind: string, publisher: string, name: string, version?: string): string {\n const base = `${kind}:@${publisher}/${name}`;\n return version ? `${base}#${version}` : base;\n}\n\n/** The bare asset name from a `kind:@publisher/name#version` ref or a plain name. */\nexport function bareName(ref: string): string {\n const afterKind = ref.includes(\":\") ? ref.slice(ref.indexOf(\":\") + 1) : ref;\n const afterScope = afterKind.includes(\"/\")\n ? afterKind.slice(afterKind.indexOf(\"/\") + 1)\n : afterKind;\n return afterScope.split(\"#\")[0];\n}\n\n/**\n * Poll a job until it leaves `running` or the deadline passes. Returns the last\n * observed state — the caller MUST treat a still-`running` result as a timeout\n * (not success), since it means the deadline was hit before the job finished.\n */\nexport async function pollJob(\n client: PublisherClient,\n jobId: string,\n intervalMs = 1_500,\n timeoutMs = 60_000,\n): Promise<{ status: string; items?: Array<{ label: string; status: string; error?: string }> }> {\n const deadline = Date.now() + timeoutMs;\n let job = await client.jobGet(jobId);\n while (job.status === \"running\" && Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, intervalMs));\n job = await client.jobGet(jobId);\n }\n return job;\n}\n\n/**\n * True when a `sourcesAdd` rejection is a duplicate-URL conflict (the source is\n * already registered) — the only error the publish flow recovers from by looking\n * the existing row up. Every other failure (auth, 5xx, network) must propagate.\n */\nexport function isDupSourceError(err: unknown): boolean {\n const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();\n return /\\b409\\b|conflict|duplicate|already exists|already registered|unique/.test(msg);\n}\n\n/**\n * Register + sync the source, then publish its curated/declared candidates —\n * the store-side steps shared by both publish front-ends. Git side-effects (the\n * sidecar push, or the library commit+push) happen in the caller *before* this;\n * this function is purely store interaction.\n *\n * The sidecar front-end passes `sidecar` (so `sourcesAdd` carries the sidecar\n * pin); the library front-end omits it (the source repo IS the manifest host).\n * `assetName`, when set, narrows publication to the single candidate of that\n * name. Fatal store states (`sourcesAdd` non-dup failure) surface; sync failures\n * and empty candidate sets `process.exit(1)` with the same messages as before.\n */\nexport async function publishToStore(opts: {\n sourceUrl: string;\n ref: string;\n sidecar?: { url: string; ref: string };\n manifest: SkPublishManifest;\n assetName?: string;\n client: PublisherClient;\n}): Promise<{ published: string[] }> {\n const { sourceUrl, ref, sidecar, manifest, assetName, client: pub } = opts;\n\n let sourceId: string;\n try {\n const added = await pub.sourcesAdd({\n url: sourceUrl,\n ref,\n ...(sidecar ? { sidecarUrl: sidecar.url, sidecarRef: sidecar.ref } : {}),\n // Publish under the manifest's declared namespace; the store resolves a\n // claimed Publisher when it differs from the caller's login, else defaults\n // to `@<username>`. Omitted when the manifest carries no publisher.\n ...(manifest.publisher ? { namespace: manifest.publisher } : {}),\n });\n sourceId = added.id;\n } catch (err) {\n // Only a duplicate-url conflict is recoverable (source already registered);\n // auth/5xx/network failures must surface, not silently reuse a stale row.\n if (!isDupSourceError(err)) throw err;\n const rows = await pub.sourcesList();\n const found = rows.find((r) => r.url === sourceUrl);\n if (!found) {\n throw new Error(\n `Source ${sourceUrl} looked already-registered but no owned row matched: ` +\n `${err instanceof Error ? err.message : String(err)}`,\n );\n }\n sourceId = found.id;\n }\n\n const { jobId } = await pub.sourceSync(sourceId);\n const job = await pollJob(pub, jobId);\n if (job.status === \"failed\" || job.status === \"cancelled\") {\n const failed = (job.items ?? []).filter((i) => i.status === \"failed\");\n for (const i of failed) logErr(`sync: ${i.label}: ${i.error ?? \"failed\"}`);\n logErr(`Source sync ${job.status}.`);\n process.exit(1);\n }\n // A still-`running` job means the poll deadline was hit — do NOT proceed on an\n // unfinished sync (it would read incomplete candidates).\n if (job.status === \"running\") {\n logErr(\"Source sync timed out before completing — re-run `publish`, or check the store.\");\n process.exit(1);\n }\n\n let candidates = matchCandidatesToManifest(await pub.sourceCandidates(sourceId), manifest);\n if (assetName) candidates = candidates.filter((c) => c.name === assetName);\n if (candidates.length === 0) {\n logWarn(\"No candidates discovered — check the manifest and the source ref.\");\n process.exit(1);\n }\n\n const published: string[] = [];\n for (const c of candidates) {\n try {\n const preview = await pub.assetPreview(c.id);\n const res = await pub.assetPublish(c.id, { ref, files: preview.discoveredFiles });\n // Publish is async — wait for the job so we only report refs that actually\n // landed, not ones whose import is still in flight or about to fail.\n if (res.jobId) {\n const pubJob = await pollJob(pub, res.jobId);\n if (pubJob.status !== \"succeeded\") {\n const errs = (pubJob.items ?? [])\n .filter((i) => i.status === \"failed\")\n .map((i) => i.error)\n .filter(Boolean);\n logWarn(\n `Publish of ${c.kind}:${c.name} did not succeed (${pubJob.status})` +\n (errs.length ? `: ${errs.join(\"; \")}` : \"\"),\n );\n continue;\n }\n }\n published.push(refFor(c.kind, preview.candidate.publisherNamespace, c.name, c.version));\n } catch (err) {\n logWarn(\n `Failed to publish ${c.kind}:${c.name}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n logOk(`Published ${published.length} asset(s):`);\n for (const r of published) logInfo(` ${r}`);\n return { published };\n}\n"]}
1
+ {"version":3,"sources":["../cli/src/store-publisher.ts","../cli/src/commands/publish-core.ts"],"names":[],"mappings":"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","file":"chunk-422WJ2QC.js","sourcesContent":["/**\n * Typed REST client for the AI Asset Store **publisher** surface — the\n * curator-publish flow (`skaile source manifest publish` / `yank`). Thin\n * wrappers over {@link storeFetch}; every method maps 1:1 to an `/api/v1/…`\n * endpoint. The {@link PublisherClient} interface is injectable so the\n * orchestration in `commands/source-manifest-publish.ts` can be unit-tested\n * against a fake without a live store.\n *\n * @docLink cli/dev-guide#store-publisher\n */\n\nimport { getStoreConfig, getStoreToken, type StoreConfig, storeFetch } from \"./store-client.ts\";\n\n/**\n * The publisher REST surface used by the curator-publish flow. Kept minimal —\n * only the endpoints `runPublish` / `runYank` actually call. Response shapes\n * are narrowed to the fields the orchestration reads (the server returns more).\n */\nexport interface PublisherClient {\n /**\n * Identity of the caller. `username` is the Keycloak login (personal-tier\n * namespace); `githubLogin` is the verified GitHub handle when connected —\n * the namespace to publish under when it differs from the login.\n */\n me(): Promise<{ username: string; githubLogin?: string | null }>;\n /** Register (or re-register) a source; returns the created/existing row id. */\n sourcesAdd(body: {\n url: string;\n ref: string;\n sidecarUrl?: string;\n sidecarRef?: string;\n /**\n * Target publisher namespace (the manifest's `publisher`). When it differs\n * from the caller's login username, the store resolves the CLAIMED Publisher\n * for it (the store must already have the claim). Omitted → the store\n * defaults to `@<username>` (personal).\n */\n namespace?: string;\n }): Promise<{ id: string }>;\n /** List sources — used to recover an id when `sourcesAdd` rejects a dup url. */\n sourcesList(): Promise<Array<{ id: string; url: string }>>;\n /** Kick off a source sync; returns the async job id to poll. */\n sourceSync(id: string): Promise<{ jobId: string }>;\n /** Poll a job's terminal status + per-item results. */\n jobGet(\n jobId: string,\n ): Promise<{ status: string; items?: Array<{ label: string; status: string; error?: string }> }>;\n /** Discovered publishable candidates for a synced source. */\n sourceCandidates(id: string): Promise<\n Array<{\n id: string;\n name: string;\n version: string;\n kind: string;\n published: boolean;\n assetRoot: string;\n }>\n >;\n /** Per-asset preview — the discovered file set + resolved candidate metadata. */\n assetPreview(id: string): Promise<{\n discoveredFiles: string[];\n candidate: { name: string; version: string; kind: string; publisherNamespace: string };\n }>;\n /**\n * Publish one asset. `dryRun` returns the would-be `{ manifest }` without\n * launching a job; the normal path returns `{ jobId }`.\n */\n assetPublish(\n id: string,\n body: { ref: string; files: string[] },\n dryRun?: boolean,\n ): Promise<{ jobId?: string; manifest?: unknown }>;\n /** Retract a published asset. Response body is ignored. */\n assetUnpublish(id: string): Promise<unknown>;\n /**\n * Read-only \"can I publish under `@<ns>` right now, and if not, what's the\n * path?\" probe. Backs the `publish --dry-run` namespace status line; its\n * `message` is store-authored and meant to be surfaced verbatim.\n */\n namespaceAvailability(ns: string): Promise<{\n namespace: string;\n status: \"owned-by-you\" | \"claimable-by-you\" | \"reserved\" | \"available\";\n claimMethod?: string;\n message: string;\n }>;\n}\n\n/**\n * Construct the real HTTP-backed {@link PublisherClient}. Every call carries a\n * longer timeout than the default store client because publish/sync trigger\n * server-side clone work.\n *\n * @param config - Store connection config; defaults to {@link getStoreConfig}.\n * @param timeoutMs - Per-request abort timeout (default 20s).\n */\nexport function makeHttpPublisherClient(\n config: StoreConfig = getStoreConfig(),\n timeoutMs = 20_000,\n): PublisherClient {\n // Acquire a fresh Keycloak token per call (device-flow session in\n // ~/.skaile/auth.json, refreshed on demand) rather than a static config.jwt.\n const call = async <T>(\n path: string,\n opts?: { method?: string; body?: unknown; params?: Record<string, string> },\n ): Promise<T> => {\n const jwt = await getStoreToken();\n return storeFetch<T>({ ...config, jwt }, path, { timeoutMs, ...opts });\n };\n return {\n me: () => call(\"/api/v1/me\"),\n sourcesAdd: (body) => call(\"/api/v1/sources\", { method: \"POST\", body }),\n sourcesList: () => call(\"/api/v1/sources\"),\n sourceSync: (id) => call(`/api/v1/sources/${id}/sync`, { method: \"POST\", body: {} }),\n jobGet: (jobId) => call(`/api/v1/jobs/${jobId}`),\n sourceCandidates: (id) => call(`/api/v1/sources/${id}/candidates`),\n assetPreview: (id) => call(`/api/v1/assets/${id}/preview`),\n assetPublish: (id, body, dryRun) =>\n call(`/api/v1/assets/${id}/publish`, {\n method: \"POST\",\n body,\n ...(dryRun ? { params: { dryRun: \"1\" } } : {}),\n }),\n assetUnpublish: (id) => call(`/api/v1/assets/${id}/unpublish`, { method: \"POST\", body: {} }),\n namespaceAvailability: (ns) =>\n call(`/api/v1/namespaces/${encodeURIComponent(ns)}/availability`),\n };\n}\n","/**\n * Shared store-interaction core for the two publish front-ends — the curator\n * sidecar flow (`source manifest publish`) and the first-party library flow\n * (`library publish`). Both differ only in their git side-effects + how they\n * resolve the source repo; the store orchestration below (register → sync →\n * candidates → per-asset preview+publish) is identical.\n *\n * The store REST surface is reached through the injectable {@link PublisherClient}\n * so the orchestration stays unit/integration-testable without a live store.\n *\n * @docLink cli/commands/source#manifest-publish\n */\n\nimport type { SkPublishManifest } from \"@skaile/workspaces/core\";\nimport { logErr, logInfo, logOk, logWarn, S } from \"../helpers.ts\";\nimport type { PublisherClient } from \"../store-publisher.ts\";\n\n/**\n * One-line rendering of a namespace-availability probe for a `--dry-run` plan.\n * The `message` is store-authored (identical to what a real publish would echo)\n * — we only prepend a status glyph so the reader sees green/amber/red at a\n * glance without the CLI re-deriving any authorization logic.\n */\nexport function formatNamespaceAvailability(a: {\n status: \"owned-by-you\" | \"claimable-by-you\" | \"reserved\" | \"available\";\n message: string;\n}): string {\n switch (a.status) {\n case \"owned-by-you\":\n case \"available\":\n return `${S.ok(\"✓\")} ${a.message}`;\n case \"claimable-by-you\":\n return `${S.warn(\"!\")} ${a.message}`;\n default:\n return `${S.err(\"✗\")} ${a.message}`;\n }\n}\n\n/**\n * Preflight the target namespace against the store's availability probe BEFORE a\n * publish does any irreversible work (a public git push). Returns `{ ok: false }`\n * with a guided message for `reserved` (not yours) and `claimable-by-you` (must\n * claim first) — the two states a real publish would reject — so the caller can\n * abort with actionable guidance instead of a raw 422 after pushing bytes.\n *\n * The probe is advisory: any failure (offline, older store) returns `{ ok: true }`\n * so the store stays the authority and a valid publish is never blocked.\n */\nexport async function preflightNamespace(\n client: PublisherClient,\n namespace: string,\n): Promise<{ ok: boolean; message?: string }> {\n let a: Awaited<ReturnType<PublisherClient[\"namespaceAvailability\"]>>;\n try {\n a = await client.namespaceAvailability(namespace);\n } catch {\n return { ok: true };\n }\n switch (a.status) {\n case \"owned-by-you\":\n case \"available\":\n return { ok: true };\n case \"claimable-by-you\":\n return {\n ok: false,\n message:\n `@${namespace} isn't yours yet — claim it in the store first` +\n `${a.claimMethod ? ` (${a.claimMethod})` : \"\"}, then re-run. ${a.message}`,\n };\n default: // reserved, or any unrecognized future status (fail safe → block)\n return { ok: false, message: `Cannot publish under @${namespace} — ${a.message}` };\n }\n}\n\n/** One candidate row shape the matcher operates on (kind + name are the key). */\ninterface CandidateLike {\n kind: string;\n name: string;\n}\n\n/**\n * Keep only candidates whose `(kind, name)` pair is declared in the manifest.\n * The backend may merge extra assets from the base repo into the candidate\n * list; a publish only touches what the manifest curated/declared.\n */\nexport function matchCandidatesToManifest<T extends CandidateLike>(\n candidates: T[],\n manifest: SkPublishManifest,\n): T[] {\n const wanted = new Set((manifest.assets ?? []).map((a) => `${a.kind}:${a.name}`));\n return candidates.filter((c) => wanted.has(`${c.kind}:${c.name}`));\n}\n\n/** A canonical ref string `kind:@publisher/name[#version]` for reporting. */\nexport function refFor(kind: string, publisher: string, name: string, version?: string): string {\n const base = `${kind}:@${publisher}/${name}`;\n return version ? `${base}#${version}` : base;\n}\n\n/** The bare asset name from a `kind:@publisher/name#version` ref or a plain name. */\nexport function bareName(ref: string): string {\n const afterKind = ref.includes(\":\") ? ref.slice(ref.indexOf(\":\") + 1) : ref;\n const afterScope = afterKind.includes(\"/\")\n ? afterKind.slice(afterKind.indexOf(\"/\") + 1)\n : afterKind;\n return afterScope.split(\"#\")[0];\n}\n\n/**\n * Poll a job until it leaves `running` or the deadline passes. Returns the last\n * observed state — the caller MUST treat a still-`running` result as a timeout\n * (not success), since it means the deadline was hit before the job finished.\n */\nexport async function pollJob(\n client: PublisherClient,\n jobId: string,\n intervalMs = 1_500,\n timeoutMs = 60_000,\n): Promise<{ status: string; items?: Array<{ label: string; status: string; error?: string }> }> {\n const deadline = Date.now() + timeoutMs;\n let job = await client.jobGet(jobId);\n while (job.status === \"running\" && Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, intervalMs));\n job = await client.jobGet(jobId);\n }\n return job;\n}\n\n/**\n * True when a `sourcesAdd` rejection is a duplicate-URL conflict (the source is\n * already registered) — the only error the publish flow recovers from by looking\n * the existing row up. Every other failure (auth, 5xx, network) must propagate.\n */\nexport function isDupSourceError(err: unknown): boolean {\n const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();\n return /\\b409\\b|conflict|duplicate|already exists|already registered|unique/.test(msg);\n}\n\n/**\n * Register + sync the source, then publish its curated/declared candidates —\n * the store-side steps shared by both publish front-ends. Git side-effects (the\n * sidecar push, or the library commit+push) happen in the caller *before* this;\n * this function is purely store interaction.\n *\n * The sidecar front-end passes `sidecar` (so `sourcesAdd` carries the sidecar\n * pin); the library front-end omits it (the source repo IS the manifest host).\n * `assetName`, when set, narrows publication to the single candidate of that\n * name. Fatal store states (`sourcesAdd` non-dup failure) surface; sync failures\n * and empty candidate sets `process.exit(1)` with the same messages as before.\n */\nexport async function publishToStore(opts: {\n sourceUrl: string;\n ref: string;\n sidecar?: { url: string; ref: string };\n manifest: SkPublishManifest;\n assetName?: string;\n client: PublisherClient;\n}): Promise<{ published: string[] }> {\n const { sourceUrl, ref, sidecar, manifest, assetName, client: pub } = opts;\n\n let sourceId: string;\n try {\n const added = await pub.sourcesAdd({\n url: sourceUrl,\n ref,\n ...(sidecar ? { sidecarUrl: sidecar.url, sidecarRef: sidecar.ref } : {}),\n // Publish under the manifest's declared namespace; the store resolves a\n // claimed Publisher when it differs from the caller's login, else defaults\n // to `@<username>`. Omitted when the manifest carries no publisher.\n ...(manifest.publisher ? { namespace: manifest.publisher } : {}),\n });\n sourceId = added.id;\n } catch (err) {\n // Only a duplicate-url conflict is recoverable (source already registered);\n // auth/5xx/network failures must surface, not silently reuse a stale row.\n if (!isDupSourceError(err)) throw err;\n const rows = await pub.sourcesList();\n const found = rows.find((r) => r.url === sourceUrl);\n if (!found) {\n throw new Error(\n `Source ${sourceUrl} looked already-registered but no owned row matched: ` +\n `${err instanceof Error ? err.message : String(err)}`,\n );\n }\n sourceId = found.id;\n }\n\n const { jobId } = await pub.sourceSync(sourceId);\n const job = await pollJob(pub, jobId);\n if (job.status === \"failed\" || job.status === \"cancelled\") {\n const failed = (job.items ?? []).filter((i) => i.status === \"failed\");\n for (const i of failed) logErr(`sync: ${i.label}: ${i.error ?? \"failed\"}`);\n logErr(`Source sync ${job.status}.`);\n process.exit(1);\n }\n // A still-`running` job means the poll deadline was hit — do NOT proceed on an\n // unfinished sync (it would read incomplete candidates).\n if (job.status === \"running\") {\n logErr(\"Source sync timed out before completing — re-run `publish`, or check the store.\");\n process.exit(1);\n }\n\n let candidates = matchCandidatesToManifest(await pub.sourceCandidates(sourceId), manifest);\n if (assetName) candidates = candidates.filter((c) => c.name === assetName);\n if (candidates.length === 0) {\n logWarn(\"No candidates discovered — check the manifest and the source ref.\");\n process.exit(1);\n }\n\n const published: string[] = [];\n for (const c of candidates) {\n try {\n const preview = await pub.assetPreview(c.id);\n const res = await pub.assetPublish(c.id, { ref, files: preview.discoveredFiles });\n // Publish is async — wait for the job so we only report refs that actually\n // landed, not ones whose import is still in flight or about to fail.\n if (res.jobId) {\n const pubJob = await pollJob(pub, res.jobId);\n if (pubJob.status !== \"succeeded\") {\n const errs = (pubJob.items ?? [])\n .filter((i) => i.status === \"failed\")\n .map((i) => i.error)\n .filter(Boolean);\n logWarn(\n `Publish of ${c.kind}:${c.name} did not succeed (${pubJob.status})` +\n (errs.length ? `: ${errs.join(\"; \")}` : \"\"),\n );\n continue;\n }\n }\n published.push(refFor(c.kind, preview.candidate.publisherNamespace, c.name, c.version));\n } catch (err) {\n logWarn(\n `Failed to publish ${c.kind}:${c.name}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n logOk(`Published ${published.length} asset(s):`);\n for (const r of published) logInfo(` ${r}`);\n return { published };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { tryWithFsDeadline, withFsDeadline, fsDeadlineMs } from './chunk-2FBPAR2V.js';
1
+ import { tryWithFsDeadline, withFsDeadline, fsDeadlineMs } from './chunk-SQ7IN7KR.js';
2
2
  import { createLogger } from './chunk-BOFL7GIF.js';
3
3
  import { stat, mkdir, cp, writeFile, rm } from 'fs/promises';
4
4
  import { resolve, sep, join } from 'path';
@@ -155,5 +155,5 @@ function resolveFlowSkills(flow, allEntries) {
155
155
  }
156
156
 
157
157
  export { WORKSPACE_MOUNT_ENV_VAR, deployAll, deployCatalogEntry, findAiAssetsRoot, isUnderWorkspaceMount, resolveFlowSkills, undeployCatalogEntry, workspaceMountDirs };
158
- //# sourceMappingURL=chunk-Q6NDQ6BH.js.map
159
- //# sourceMappingURL=chunk-Q6NDQ6BH.js.map
158
+ //# sourceMappingURL=chunk-5JAO4MXA.js.map
159
+ //# sourceMappingURL=chunk-5JAO4MXA.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../asset-manager/src/catalog-deployer.ts"],"names":[],"mappings":"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","file":"chunk-Q6NDQ6BH.js","sourcesContent":["/**\n * Platform-triggered asset deployment.\n *\n * Takes catalog entries (with source_path relative to ai-assets/) and deploys\n * them to a session's .claude/skills/ directory. Handles skill context injection\n * and catalog priority-based name resolution.\n */\n\nimport { cp, mkdir, rm, stat, writeFile } from \"node:fs/promises\";\nimport { join, resolve, sep } from \"node:path\";\nimport { fsDeadlineMs, tryWithFsDeadline, withFsDeadline } from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\n\n// ---------------------------------------------------------------------------\n// Types (formerly in catalog-compiler.ts, inlined after tear-out in Task 1.5)\n// ---------------------------------------------------------------------------\n\n/**\n * A single user-facing input parameter declared in a SKILL.md.\n *\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport interface InputSpec {\n /** Input parameter key used in skill invocation. */\n key: string;\n /** Whether the input must be provided before running the skill. */\n required?: boolean;\n /** Question string shown to the user when collecting this input. */\n prompt?: string;\n /** Short display label for UI forms. */\n label?: string;\n /** Input data type hint (e.g. `\"string\"`, `\"number\"`, `\"file\"`). */\n type?: string;\n /** Additional guidance text shown alongside the input field. */\n hint?: string;\n}\n\n/**\n * A compiled catalog entry (skill or flow).\n *\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport interface CatalogEntryCompiled {\n /** Unique ID in `domain/name` form (e.g. `skaileup-conceptualization/cf_overview`). */\n id: string;\n /** Asset kind. */\n kind: \"skill\" | \"flow\";\n /** Human-readable asset name. */\n name: string;\n /** One-line description. */\n description: string;\n /** Semantic version string. */\n version: string;\n /** Maturity stage. */\n stage: \"alpha\" | \"beta\" | \"stable\";\n /** Searchable keywords. */\n keywords: string[];\n /** User-facing input specifications. */\n inputs: InputSpec[];\n /** Domain directory name. */\n source_domain: string;\n /** Asset path relative to assetsRoot. */\n source_path: string;\n /** Optional icon identifier. */\n icon?: string;\n /** Flow-only: required skill names. */\n required_skills?: string[];\n /** Flow-only: optional skill names. */\n optional_skills?: string[];\n}\n\n/**\n * Options controlling how platform-triggered skill deployment is performed.\n *\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport interface DeployFromCatalogOptions {\n /** Root directory of ai-assets (where `source_path` in catalog entries is relative to). */\n assetsRoot: string;\n /** Target directory for deployed skills (e.g. `/workspace/.claude/skills/`). */\n skillsDir: string;\n /** Optional context markdown appended to the deployed skill directory as `CONTEXT.md`. */\n context?: string;\n}\n\n/**\n * Result of a platform-triggered batch skill deployment.\n *\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport interface DeployResult {\n /** IDs of catalog entries successfully deployed. */\n deployed: string[];\n /** IDs of catalog entries skipped (non-skill kinds). */\n skipped: string[];\n /** Error messages for entries that could not be deployed. */\n errors: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Workspace-mount awareness\n// ---------------------------------------------------------------------------\n\n/**\n * Multiplier applied to the base filesystem deadline for whole-tree operations\n * (recursive copy / remove), which legitimately outlast a single `stat`.\n */\nconst TREE_OP_DEADLINE_FACTOR = 4;\n\n/** Default number of parent levels {@link findAiAssetsRoot} inspects. */\nconst AI_ASSETS_WALK_LEVELS = 6;\n\nlet deployerLogger: ReturnType<typeof createLogger> | undefined;\n\nfunction log(): ReturnType<typeof createLogger> {\n deployerLogger ??= createLogger({ kind: \"runner\", subkind: \"catalog-deployer\" });\n return deployerLogger;\n}\n\n/**\n * Where the agent container binds its rclone FUSE mount. Nothing under this\n * path is a safe place to read an asset tree from: the mount is remote\n * (SharePoint / OneDrive / WebDAV) and can wedge indefinitely.\n */\nconst DEFAULT_WORKSPACE_MOUNT_DIR = \"/skaile/workspace\";\n\n/**\n * Env override for the workspace-mount path(s), comma-separated.\n *\n * Set it when the runner binds the mount somewhere other than\n * {@link DEFAULT_WORKSPACE_MOUNT_DIR}; set it to the empty string to disable\n * the guard entirely (single-machine dev, where nothing is a network mount).\n */\nexport const WORKSPACE_MOUNT_ENV_VAR = \"SKAILE_WORKSPACE_MOUNT_DIR\";\n\n/**\n * Resolve the directories treated as network mounts.\n *\n * Read per call rather than cached: the runner mutates `process.env` while\n * wiring a session, so a module-load snapshot would pin a pre-configuration\n * value.\n *\n * @returns Absolute mount paths; empty when the guard is disabled.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport function workspaceMountDirs(): string[] {\n const raw = process.env[WORKSPACE_MOUNT_ENV_VAR];\n if (raw === undefined) return [DEFAULT_WORKSPACE_MOUNT_DIR];\n return raw\n .split(\",\")\n .map((segment) => segment.trim())\n .filter((segment) => segment.length > 0)\n .map((segment) => resolve(segment));\n}\n\n/**\n * Is `candidate` at, or inside, one of the known workspace mount paths?\n *\n * Pure path arithmetic — deliberately no filesystem access, because the whole\n * point is to decide *before* touching a path that might be unresponsive.\n *\n * @param candidate - Path to test.\n * @param mountDirs - Mount roots; defaults to {@link workspaceMountDirs}.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport function isUnderWorkspaceMount(\n candidate: string,\n mountDirs: string[] = workspaceMountDirs(),\n): boolean {\n const target = resolve(candidate);\n return mountDirs.some((dir) => {\n const root = resolve(dir);\n return target === root || target.startsWith(root + sep);\n });\n}\n\n/**\n * Walk upward from `startDir` looking for an `ai-assets/` directory.\n *\n * Two properties matter beyond \"find the folder\":\n *\n * 1. **Never synchronous.** The walk probes up to six directories; any one of\n * them can be on a FUSE mount, and the former `existsSync` chain blocked the\n * event loop on the first unresponsive probe. Each probe is now awaited and\n * deadline-bounded, so a wedged mount costs one skipped candidate.\n * 2. **Never resolves onto a mount.** A hit under the workspace mount is\n * skipped with a warning rather than returned: accepting it would wire every\n * later skill deploy — a recursive copy — to a remote filesystem. The walk\n * continues upward, so a legitimate `ai-assets/` in a parent still wins.\n *\n * Only a **directory** counts. An `ai-assets` file would otherwise be returned\n * as a root and every later `join(root, source_path)` would fail with ENOTDIR.\n *\n * @param startDir - Directory to start from (typically the project dir).\n * @param opts - `levels` caps the upward walk; `mountDirs` overrides the mount\n * roots (defaults to {@link workspaceMountDirs}).\n * @returns Absolute path to the `ai-assets/` directory, or `null` if none is\n * reachable within `levels`.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport async function findAiAssetsRoot(\n startDir: string,\n opts?: { levels?: number; mountDirs?: string[] },\n): Promise<string | null> {\n const mountDirs = opts?.mountDirs ?? workspaceMountDirs();\n const levels = opts?.levels ?? AI_ASSETS_WALK_LEVELS;\n let dir = resolve(startDir);\n // Every level of a `/skaile/workspace/...` start dir is under the mount, so\n // an unconditional warn would fire once per level for one lookup. Collect and\n // report once — the operator needs the fact, not six copies of it.\n const refused: string[] = [];\n\n for (let i = 0; i < levels; i++) {\n const candidate = join(dir, \"ai-assets\");\n if (isUnderWorkspaceMount(candidate, mountDirs)) {\n refused.push(candidate);\n } else {\n const isDir = await tryWithFsDeadline(\n `stat ${candidate}`,\n async () => (await stat(candidate)).isDirectory(),\n false,\n );\n if (isDir) {\n if (refused.length > 0) warnRefused(refused, mountDirs);\n return candidate;\n }\n }\n const parent = resolve(dir, \"..\");\n if (parent === dir) break; // filesystem root — nothing further up\n dir = parent;\n }\n if (refused.length > 0) warnRefused(refused, mountDirs);\n return null;\n}\n\n/** Single warning for every `ai-assets` candidate skipped for sitting on a mount. */\nfunction warnRefused(refused: string[], mountDirs: string[]): void {\n log().warn(\n \"findAiAssetsRoot refused candidates under a workspace mount — deploying skills from a network mount can stall the session\",\n { refused, mountDirs },\n );\n}\n\n/**\n * Deploy a single catalog entry to the session skills directory.\n *\n * Copies the entire skill source directory into `skillsDir/<entry.name>/`.\n * If `context` is provided, a separate `CONTEXT.md` is written alongside\n * `SKILL.md` so the source file is never modified.\n *\n * Only `skill` entries are deployable; other kinds return an error.\n *\n * **Async by necessity.** This runs from the `session_init` command handler\n * with the WebSocket live, and both `assetsRoot` and `skillsDir` can sit on a\n * network mount. The former `cpSync`/`rmSync` pair parked the event loop for\n * the whole copy; every call is now awaited and deadline-bounded, so an\n * unresponsive mount fails one deployment instead of the session.\n *\n * @param entry - Compiled catalog entry to deploy.\n * @param options - Deployment target and optional context.\n * @returns `{ success: true }` on success, `{ success: false, error }` on failure.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport async function deployCatalogEntry(\n entry: CatalogEntryCompiled,\n options: DeployFromCatalogOptions,\n): Promise<{ success: boolean; error?: string }> {\n const { assetsRoot, skillsDir, context } = options;\n\n if (entry.kind !== \"skill\") {\n return { success: false, error: `Cannot deploy ${entry.kind} directly — only skills` };\n }\n\n const sourcePath = join(assetsRoot, entry.source_path);\n const skillMdPath = join(sourcePath, \"SKILL.md\");\n\n const hasSkillMd = await tryWithFsDeadline(\n `stat ${skillMdPath}`,\n async () => {\n await stat(skillMdPath);\n return true;\n },\n false,\n );\n if (!hasSkillMd) {\n return { success: false, error: `SKILL.md not found at ${skillMdPath}` };\n }\n\n const destDir = join(skillsDir, entry.name);\n\n try {\n await withFsDeadline(`mkdir ${destDir}`, () => mkdir(destDir, { recursive: true }));\n\n // Copy the entire skill directory\n await withFsDeadline(\n `cp ${sourcePath} -> ${destDir}`,\n () => cp(sourcePath, destDir, { recursive: true }),\n fsDeadlineMs() * TREE_OP_DEADLINE_FACTOR,\n );\n\n // Write context to a separate CONTEXT.md — never modify the original SKILL.md.\n // The agent discovers both files in the skill directory.\n const contextPath = join(destDir, \"CONTEXT.md\");\n if (context) {\n await withFsDeadline(`write ${contextPath}`, () =>\n writeFile(contextPath, `# Additional Context\\n\\n${context}\\n`, \"utf8\"),\n );\n } else {\n // `force: true` makes this a single call: a stale CONTEXT.md is removed,\n // an absent one is a no-op. The former existsSync probe only added a\n // second trip to the same possibly-wedged mount.\n await withFsDeadline(`rm ${contextPath}`, () => rm(contextPath, { force: true }));\n }\n } catch (err) {\n return { success: false, error: err instanceof Error ? err.message : String(err) };\n }\n\n return { success: true };\n}\n\n/**\n * Remove a deployed skill directory from the session skills directory.\n *\n * @param name - Skill name (directory basename under `skillsDir`).\n * @param skillsDir - Absolute path to the session skills directory.\n * @returns `true` if the skill was found and removed; `false` if it was not\n * deployed, or if the directory could not be reached within the deadline.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport async function undeployCatalogEntry(name: string, skillsDir: string): Promise<boolean> {\n const destDir = join(skillsDir, name);\n const exists = await tryWithFsDeadline(\n `stat ${destDir}`,\n async () => {\n await stat(destDir);\n return true;\n },\n false,\n );\n if (!exists) return false;\n await withFsDeadline(\n `rm -r ${destDir}`,\n () => rm(destDir, { recursive: true, force: true }),\n fsDeadlineMs() * TREE_OP_DEADLINE_FACTOR,\n );\n return true;\n}\n\n/**\n * Deploy multiple catalog entries in a single batch operation.\n *\n * Non-skill entries (flows, agents, etc.) are automatically skipped and\n * recorded in `result.skipped`. Deployment failures are collected in\n * `result.errors` without aborting the rest of the batch.\n *\n * @param entries - Compiled catalog entries to deploy.\n * @param options - Deployment target and optional context.\n * @returns Aggregated {@link DeployResult} with deployed, skipped, and error lists.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport async function deployAll(\n entries: CatalogEntryCompiled[],\n options: DeployFromCatalogOptions,\n): Promise<DeployResult> {\n const result: DeployResult = { deployed: [], skipped: [], errors: [] };\n\n for (const entry of entries) {\n if (entry.kind !== \"skill\") {\n result.skipped.push(entry.id);\n continue;\n }\n\n // Serial on purpose: concurrent recursive copies onto one mount multiply\n // the queue depth on the exact resource that is already the bottleneck.\n const r = await deployCatalogEntry(entry, options);\n if (r.success) {\n result.deployed.push(entry.id);\n } else {\n result.errors.push(`${entry.id}: ${r.error}`);\n }\n }\n\n return result;\n}\n\n/**\n * Resolve a flow's skill dependencies from the full catalog entry list.\n *\n * Partitions `flow.required_skills` and `flow.optional_skills` into resolved\n * entries and a list of names that could not be found. Missing optional skills\n * are silently ignored (they do not appear in `missing`).\n *\n * @param flow - Compiled flow entry whose skill dependencies should be resolved.\n * @param allEntries - Full set of compiled catalog entries to search.\n * @returns Object containing resolved `required` entries, resolved `optional` entries,\n * and `missing` skill names that were listed as required but not found.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport function resolveFlowSkills(\n flow: CatalogEntryCompiled,\n allEntries: CatalogEntryCompiled[],\n): { required: CatalogEntryCompiled[]; optional: CatalogEntryCompiled[]; missing: string[] } {\n const skillsByName = new Map<string, CatalogEntryCompiled>();\n for (const e of allEntries) {\n if (e.kind === \"skill\") skillsByName.set(e.name, e);\n }\n\n const required: CatalogEntryCompiled[] = [];\n const optional: CatalogEntryCompiled[] = [];\n const missing: string[] = [];\n\n for (const name of flow.required_skills ?? []) {\n const entry = skillsByName.get(name);\n if (entry) required.push(entry);\n else missing.push(name);\n }\n\n for (const name of flow.optional_skills ?? []) {\n const entry = skillsByName.get(name);\n if (entry) optional.push(entry);\n // Optional skills don't count as missing\n }\n\n return { required, optional, missing };\n}\n"]}
1
+ {"version":3,"sources":["../asset-manager/src/catalog-deployer.ts"],"names":[],"mappings":"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","file":"chunk-5JAO4MXA.js","sourcesContent":["/**\n * Platform-triggered asset deployment.\n *\n * Takes catalog entries (with source_path relative to ai-assets/) and deploys\n * them to a session's .claude/skills/ directory. Handles skill context injection\n * and catalog priority-based name resolution.\n */\n\nimport { cp, mkdir, rm, stat, writeFile } from \"node:fs/promises\";\nimport { join, resolve, sep } from \"node:path\";\nimport { fsDeadlineMs, tryWithFsDeadline, withFsDeadline } from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\n\n// ---------------------------------------------------------------------------\n// Types (formerly in catalog-compiler.ts, inlined after tear-out in Task 1.5)\n// ---------------------------------------------------------------------------\n\n/**\n * A single user-facing input parameter declared in a SKILL.md.\n *\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport interface InputSpec {\n /** Input parameter key used in skill invocation. */\n key: string;\n /** Whether the input must be provided before running the skill. */\n required?: boolean;\n /** Question string shown to the user when collecting this input. */\n prompt?: string;\n /** Short display label for UI forms. */\n label?: string;\n /** Input data type hint (e.g. `\"string\"`, `\"number\"`, `\"file\"`). */\n type?: string;\n /** Additional guidance text shown alongside the input field. */\n hint?: string;\n}\n\n/**\n * A compiled catalog entry (skill or flow).\n *\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport interface CatalogEntryCompiled {\n /** Unique ID in `domain/name` form (e.g. `skaileup-conceptualization/cf_overview`). */\n id: string;\n /** Asset kind. */\n kind: \"skill\" | \"flow\";\n /** Human-readable asset name. */\n name: string;\n /** One-line description. */\n description: string;\n /** Semantic version string. */\n version: string;\n /** Maturity stage. */\n stage: \"alpha\" | \"beta\" | \"stable\";\n /** Searchable keywords. */\n keywords: string[];\n /** User-facing input specifications. */\n inputs: InputSpec[];\n /** Domain directory name. */\n source_domain: string;\n /** Asset path relative to assetsRoot. */\n source_path: string;\n /** Optional icon identifier. */\n icon?: string;\n /** Flow-only: required skill names. */\n required_skills?: string[];\n /** Flow-only: optional skill names. */\n optional_skills?: string[];\n}\n\n/**\n * Options controlling how platform-triggered skill deployment is performed.\n *\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport interface DeployFromCatalogOptions {\n /** Root directory of ai-assets (where `source_path` in catalog entries is relative to). */\n assetsRoot: string;\n /** Target directory for deployed skills (e.g. `/workspace/.claude/skills/`). */\n skillsDir: string;\n /** Optional context markdown appended to the deployed skill directory as `CONTEXT.md`. */\n context?: string;\n}\n\n/**\n * Result of a platform-triggered batch skill deployment.\n *\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport interface DeployResult {\n /** IDs of catalog entries successfully deployed. */\n deployed: string[];\n /** IDs of catalog entries skipped (non-skill kinds). */\n skipped: string[];\n /** Error messages for entries that could not be deployed. */\n errors: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Workspace-mount awareness\n// ---------------------------------------------------------------------------\n\n/**\n * Multiplier applied to the base filesystem deadline for whole-tree operations\n * (recursive copy / remove), which legitimately outlast a single `stat`.\n */\nconst TREE_OP_DEADLINE_FACTOR = 4;\n\n/** Default number of parent levels {@link findAiAssetsRoot} inspects. */\nconst AI_ASSETS_WALK_LEVELS = 6;\n\nlet deployerLogger: ReturnType<typeof createLogger> | undefined;\n\nfunction log(): ReturnType<typeof createLogger> {\n deployerLogger ??= createLogger({ kind: \"runner\", subkind: \"catalog-deployer\" });\n return deployerLogger;\n}\n\n/**\n * Where the agent container binds its rclone FUSE mount. Nothing under this\n * path is a safe place to read an asset tree from: the mount is remote\n * (SharePoint / OneDrive / WebDAV) and can wedge indefinitely.\n */\nconst DEFAULT_WORKSPACE_MOUNT_DIR = \"/skaile/workspace\";\n\n/**\n * Env override for the workspace-mount path(s), comma-separated.\n *\n * Set it when the runner binds the mount somewhere other than\n * {@link DEFAULT_WORKSPACE_MOUNT_DIR}; set it to the empty string to disable\n * the guard entirely (single-machine dev, where nothing is a network mount).\n */\nexport const WORKSPACE_MOUNT_ENV_VAR = \"SKAILE_WORKSPACE_MOUNT_DIR\";\n\n/**\n * Resolve the directories treated as network mounts.\n *\n * Read per call rather than cached: the runner mutates `process.env` while\n * wiring a session, so a module-load snapshot would pin a pre-configuration\n * value.\n *\n * @returns Absolute mount paths; empty when the guard is disabled.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport function workspaceMountDirs(): string[] {\n const raw = process.env[WORKSPACE_MOUNT_ENV_VAR];\n if (raw === undefined) return [DEFAULT_WORKSPACE_MOUNT_DIR];\n return raw\n .split(\",\")\n .map((segment) => segment.trim())\n .filter((segment) => segment.length > 0)\n .map((segment) => resolve(segment));\n}\n\n/**\n * Is `candidate` at, or inside, one of the known workspace mount paths?\n *\n * Pure path arithmetic — deliberately no filesystem access, because the whole\n * point is to decide *before* touching a path that might be unresponsive.\n *\n * @param candidate - Path to test.\n * @param mountDirs - Mount roots; defaults to {@link workspaceMountDirs}.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport function isUnderWorkspaceMount(\n candidate: string,\n mountDirs: string[] = workspaceMountDirs(),\n): boolean {\n const target = resolve(candidate);\n return mountDirs.some((dir) => {\n const root = resolve(dir);\n return target === root || target.startsWith(root + sep);\n });\n}\n\n/**\n * Walk upward from `startDir` looking for an `ai-assets/` directory.\n *\n * Two properties matter beyond \"find the folder\":\n *\n * 1. **Never synchronous.** The walk probes up to six directories; any one of\n * them can be on a FUSE mount, and the former `existsSync` chain blocked the\n * event loop on the first unresponsive probe. Each probe is now awaited and\n * deadline-bounded, so a wedged mount costs one skipped candidate.\n * 2. **Never resolves onto a mount.** A hit under the workspace mount is\n * skipped with a warning rather than returned: accepting it would wire every\n * later skill deploy — a recursive copy — to a remote filesystem. The walk\n * continues upward, so a legitimate `ai-assets/` in a parent still wins.\n *\n * Only a **directory** counts. An `ai-assets` file would otherwise be returned\n * as a root and every later `join(root, source_path)` would fail with ENOTDIR.\n *\n * @param startDir - Directory to start from (typically the project dir).\n * @param opts - `levels` caps the upward walk; `mountDirs` overrides the mount\n * roots (defaults to {@link workspaceMountDirs}).\n * @returns Absolute path to the `ai-assets/` directory, or `null` if none is\n * reachable within `levels`.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport async function findAiAssetsRoot(\n startDir: string,\n opts?: { levels?: number; mountDirs?: string[] },\n): Promise<string | null> {\n const mountDirs = opts?.mountDirs ?? workspaceMountDirs();\n const levels = opts?.levels ?? AI_ASSETS_WALK_LEVELS;\n let dir = resolve(startDir);\n // Every level of a `/skaile/workspace/...` start dir is under the mount, so\n // an unconditional warn would fire once per level for one lookup. Collect and\n // report once — the operator needs the fact, not six copies of it.\n const refused: string[] = [];\n\n for (let i = 0; i < levels; i++) {\n const candidate = join(dir, \"ai-assets\");\n if (isUnderWorkspaceMount(candidate, mountDirs)) {\n refused.push(candidate);\n } else {\n const isDir = await tryWithFsDeadline(\n `stat ${candidate}`,\n async () => (await stat(candidate)).isDirectory(),\n false,\n );\n if (isDir) {\n if (refused.length > 0) warnRefused(refused, mountDirs);\n return candidate;\n }\n }\n const parent = resolve(dir, \"..\");\n if (parent === dir) break; // filesystem root — nothing further up\n dir = parent;\n }\n if (refused.length > 0) warnRefused(refused, mountDirs);\n return null;\n}\n\n/** Single warning for every `ai-assets` candidate skipped for sitting on a mount. */\nfunction warnRefused(refused: string[], mountDirs: string[]): void {\n log().warn(\n \"findAiAssetsRoot refused candidates under a workspace mount — deploying skills from a network mount can stall the session\",\n { refused, mountDirs },\n );\n}\n\n/**\n * Deploy a single catalog entry to the session skills directory.\n *\n * Copies the entire skill source directory into `skillsDir/<entry.name>/`.\n * If `context` is provided, a separate `CONTEXT.md` is written alongside\n * `SKILL.md` so the source file is never modified.\n *\n * Only `skill` entries are deployable; other kinds return an error.\n *\n * **Async by necessity.** This runs from the `session_init` command handler\n * with the WebSocket live, and both `assetsRoot` and `skillsDir` can sit on a\n * network mount. The former `cpSync`/`rmSync` pair parked the event loop for\n * the whole copy; every call is now awaited and deadline-bounded, so an\n * unresponsive mount fails one deployment instead of the session.\n *\n * @param entry - Compiled catalog entry to deploy.\n * @param options - Deployment target and optional context.\n * @returns `{ success: true }` on success, `{ success: false, error }` on failure.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport async function deployCatalogEntry(\n entry: CatalogEntryCompiled,\n options: DeployFromCatalogOptions,\n): Promise<{ success: boolean; error?: string }> {\n const { assetsRoot, skillsDir, context } = options;\n\n if (entry.kind !== \"skill\") {\n return { success: false, error: `Cannot deploy ${entry.kind} directly — only skills` };\n }\n\n const sourcePath = join(assetsRoot, entry.source_path);\n const skillMdPath = join(sourcePath, \"SKILL.md\");\n\n const hasSkillMd = await tryWithFsDeadline(\n `stat ${skillMdPath}`,\n async () => {\n await stat(skillMdPath);\n return true;\n },\n false,\n );\n if (!hasSkillMd) {\n return { success: false, error: `SKILL.md not found at ${skillMdPath}` };\n }\n\n const destDir = join(skillsDir, entry.name);\n\n try {\n await withFsDeadline(`mkdir ${destDir}`, () => mkdir(destDir, { recursive: true }));\n\n // Copy the entire skill directory\n await withFsDeadline(\n `cp ${sourcePath} -> ${destDir}`,\n () => cp(sourcePath, destDir, { recursive: true }),\n fsDeadlineMs() * TREE_OP_DEADLINE_FACTOR,\n );\n\n // Write context to a separate CONTEXT.md — never modify the original SKILL.md.\n // The agent discovers both files in the skill directory.\n const contextPath = join(destDir, \"CONTEXT.md\");\n if (context) {\n await withFsDeadline(`write ${contextPath}`, () =>\n writeFile(contextPath, `# Additional Context\\n\\n${context}\\n`, \"utf8\"),\n );\n } else {\n // `force: true` makes this a single call: a stale CONTEXT.md is removed,\n // an absent one is a no-op. The former existsSync probe only added a\n // second trip to the same possibly-wedged mount.\n await withFsDeadline(`rm ${contextPath}`, () => rm(contextPath, { force: true }));\n }\n } catch (err) {\n return { success: false, error: err instanceof Error ? err.message : String(err) };\n }\n\n return { success: true };\n}\n\n/**\n * Remove a deployed skill directory from the session skills directory.\n *\n * @param name - Skill name (directory basename under `skillsDir`).\n * @param skillsDir - Absolute path to the session skills directory.\n * @returns `true` if the skill was found and removed; `false` if it was not\n * deployed, or if the directory could not be reached within the deadline.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport async function undeployCatalogEntry(name: string, skillsDir: string): Promise<boolean> {\n const destDir = join(skillsDir, name);\n const exists = await tryWithFsDeadline(\n `stat ${destDir}`,\n async () => {\n await stat(destDir);\n return true;\n },\n false,\n );\n if (!exists) return false;\n await withFsDeadline(\n `rm -r ${destDir}`,\n () => rm(destDir, { recursive: true, force: true }),\n fsDeadlineMs() * TREE_OP_DEADLINE_FACTOR,\n );\n return true;\n}\n\n/**\n * Deploy multiple catalog entries in a single batch operation.\n *\n * Non-skill entries (flows, agents, etc.) are automatically skipped and\n * recorded in `result.skipped`. Deployment failures are collected in\n * `result.errors` without aborting the rest of the batch.\n *\n * @param entries - Compiled catalog entries to deploy.\n * @param options - Deployment target and optional context.\n * @returns Aggregated {@link DeployResult} with deployed, skipped, and error lists.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport async function deployAll(\n entries: CatalogEntryCompiled[],\n options: DeployFromCatalogOptions,\n): Promise<DeployResult> {\n const result: DeployResult = { deployed: [], skipped: [], errors: [] };\n\n for (const entry of entries) {\n if (entry.kind !== \"skill\") {\n result.skipped.push(entry.id);\n continue;\n }\n\n // Serial on purpose: concurrent recursive copies onto one mount multiply\n // the queue depth on the exact resource that is already the bottleneck.\n const r = await deployCatalogEntry(entry, options);\n if (r.success) {\n result.deployed.push(entry.id);\n } else {\n result.errors.push(`${entry.id}: ${r.error}`);\n }\n }\n\n return result;\n}\n\n/**\n * Resolve a flow's skill dependencies from the full catalog entry list.\n *\n * Partitions `flow.required_skills` and `flow.optional_skills` into resolved\n * entries and a list of names that could not be found. Missing optional skills\n * are silently ignored (they do not appear in `missing`).\n *\n * @param flow - Compiled flow entry whose skill dependencies should be resolved.\n * @param allEntries - Full set of compiled catalog entries to search.\n * @returns Object containing resolved `required` entries, resolved `optional` entries,\n * and `missing` skill names that were listed as required but not found.\n * @docLink packages/asset-manager/concepts#catalog-deployer\n */\nexport function resolveFlowSkills(\n flow: CatalogEntryCompiled,\n allEntries: CatalogEntryCompiled[],\n): { required: CatalogEntryCompiled[]; optional: CatalogEntryCompiled[]; missing: string[] } {\n const skillsByName = new Map<string, CatalogEntryCompiled>();\n for (const e of allEntries) {\n if (e.kind === \"skill\") skillsByName.set(e.name, e);\n }\n\n const required: CatalogEntryCompiled[] = [];\n const optional: CatalogEntryCompiled[] = [];\n const missing: string[] = [];\n\n for (const name of flow.required_skills ?? []) {\n const entry = skillsByName.get(name);\n if (entry) required.push(entry);\n else missing.push(name);\n }\n\n for (const name of flow.optional_skills ?? []) {\n const entry = skillsByName.get(name);\n if (entry) optional.push(entry);\n // Optional skills don't count as missing\n }\n\n return { required, optional, missing };\n}\n"]}
@@ -1,7 +1,7 @@
1
- import { logErr } from './chunk-FDZL5QVZ.js';
2
- import { flowKindProvider } from './chunk-7HJ6SFFF.js';
3
- import { knowledgeKindProvider } from './chunk-DOF77WEV.js';
4
- import { createDefaultRegistry } from './chunk-VOXFI3XS.js';
1
+ import { logErr } from './chunk-L22WTIIC.js';
2
+ import { flowKindProvider } from './chunk-FLGLODDF.js';
3
+ import { knowledgeKindProvider } from './chunk-BSIHJZKN.js';
4
+ import { createDefaultRegistry } from './chunk-DFZDL62S.js';
5
5
 
6
6
  // cli/src/open-registry.ts
7
7
  function createFullRegistry() {
@@ -103,5 +103,5 @@ async function openLibraryManager() {
103
103
  }
104
104
 
105
105
  export { LocalCatalogDisabledError, createFullRegistry, openCatalogSource, openLibrary, openLibraryManager, resolveCatalogSource };
106
- //# sourceMappingURL=chunk-ENV5DDQ7.js.map
107
- //# sourceMappingURL=chunk-ENV5DDQ7.js.map
106
+ //# sourceMappingURL=chunk-5JJ5KQUM.js.map
107
+ //# sourceMappingURL=chunk-5JJ5KQUM.js.map