@skaile/workspaces 0.24.0 → 0.26.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 (520) hide show
  1. package/CHANGELOG.md +276 -0
  2. package/README.md +2 -2
  3. package/dist/{asset-feeds-WKIKSZ6Z.js → asset-feeds-WMVTI7KW.js} +11 -10
  4. package/dist/asset-feeds-WMVTI7KW.js.map +1 -0
  5. package/dist/asset-manager/index.js +11 -10
  6. package/dist/asset-manager/installer.js +10 -9
  7. package/dist/asset-manager/renderers.js +2 -2
  8. package/dist/asset-manager/src/index.d.ts +6 -7
  9. package/dist/asset-manager/src/index.d.ts.map +1 -1
  10. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  11. package/dist/bridge/drivers/claude-sdk.js +14 -7
  12. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  13. package/dist/bridge/drivers/codex.js +8 -34
  14. package/dist/bridge/drivers/codex.js.map +1 -1
  15. package/dist/bridge/drivers/echo.js +1 -1
  16. package/dist/bridge/drivers/omp.js +64 -50
  17. package/dist/bridge/drivers/omp.js.map +1 -1
  18. package/dist/bridge/index.js +4 -4
  19. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  20. package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
  21. package/dist/bridge/src/drivers/omp.d.ts +20 -4
  22. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  23. package/dist/bridge/src/error-classifier.d.ts +17 -0
  24. package/dist/bridge/src/error-classifier.d.ts.map +1 -1
  25. package/dist/bridge/src/models.d.ts +1 -1
  26. package/dist/bridge/src/models.d.ts.map +1 -1
  27. package/dist/bridge/src/provider-endpoints.d.ts +16 -0
  28. package/dist/bridge/src/provider-endpoints.d.ts.map +1 -0
  29. package/dist/bridge/src/validation.d.ts +1 -1
  30. package/dist/bridge/src/validation.d.ts.map +1 -1
  31. package/dist/{chunk-M5TE6YI5.js → chunk-23M4XZQW.js} +10 -52
  32. package/dist/chunk-23M4XZQW.js.map +1 -0
  33. package/dist/{chunk-DH4N5AW4.js → chunk-2FS4FPZ7.js} +3 -3
  34. package/dist/{chunk-DH4N5AW4.js.map → chunk-2FS4FPZ7.js.map} +1 -1
  35. package/dist/{chunk-6VTG73UY.js → chunk-45H3UO2R.js} +2 -2
  36. package/dist/{chunk-6VTG73UY.js.map → chunk-45H3UO2R.js.map} +1 -1
  37. package/dist/chunk-4SQ6Y6U7.js +28 -0
  38. package/dist/chunk-4SQ6Y6U7.js.map +1 -0
  39. package/dist/{chunk-LSGAYQ2E.js → chunk-5YO3H5Q4.js} +3 -3
  40. package/dist/{chunk-LSGAYQ2E.js.map → chunk-5YO3H5Q4.js.map} +1 -1
  41. package/dist/{chunk-JDX54X4Y.js → chunk-7GWYRVAX.js} +12 -9
  42. package/dist/chunk-7GWYRVAX.js.map +1 -0
  43. package/dist/{chunk-46COM7M5.js → chunk-7OBGSR7O.js} +5 -5
  44. package/dist/chunk-7OBGSR7O.js.map +1 -0
  45. package/dist/{chunk-2RFOFHSM.js → chunk-BKF3UFF4.js} +21 -9
  46. package/dist/chunk-BKF3UFF4.js.map +1 -0
  47. package/dist/{chunk-KOVLSBXK.js → chunk-BMQKMOQY.js} +81 -79
  48. package/dist/chunk-BMQKMOQY.js.map +1 -0
  49. package/dist/{chunk-J2TITSXF.js → chunk-BQRRBGDE.js} +2 -2
  50. package/dist/{chunk-J2TITSXF.js.map → chunk-BQRRBGDE.js.map} +1 -1
  51. package/dist/{chunk-5ESCS2OS.js → chunk-C32BRO2W.js} +67 -35
  52. package/dist/chunk-C32BRO2W.js.map +1 -0
  53. package/dist/{chunk-GZWJGNNN.js → chunk-DEYYRFQU.js} +3 -3
  54. package/dist/chunk-DEYYRFQU.js.map +1 -0
  55. package/dist/{chunk-YX3UWPJ5.js → chunk-IEJ5IOC3.js} +27 -49
  56. package/dist/chunk-IEJ5IOC3.js.map +1 -0
  57. package/dist/chunk-IERB3UXJ.js +215 -0
  58. package/dist/chunk-IERB3UXJ.js.map +1 -0
  59. package/dist/{chunk-FVTV7M76.js → chunk-IFGTRL2I.js} +3 -3
  60. package/dist/chunk-IFGTRL2I.js.map +1 -0
  61. package/dist/{chunk-LJ52ZKIU.js → chunk-JIQLLZ65.js} +203 -39
  62. package/dist/chunk-JIQLLZ65.js.map +1 -0
  63. package/dist/{chunk-Z3M5K67G.js → chunk-KL2MQ6WI.js} +114 -63
  64. package/dist/chunk-KL2MQ6WI.js.map +1 -0
  65. package/dist/{chunk-6FNCZYJY.js → chunk-MBOR7D65.js} +3 -3
  66. package/dist/{chunk-6FNCZYJY.js.map → chunk-MBOR7D65.js.map} +1 -1
  67. package/dist/{chunk-QAVZOJCV.js → chunk-OVRSNIKJ.js} +2 -2
  68. package/dist/chunk-OVRSNIKJ.js.map +1 -0
  69. package/dist/{chunk-DQWREFRQ.js → chunk-PAYAFNXG.js} +22 -3
  70. package/dist/chunk-PAYAFNXG.js.map +1 -0
  71. package/dist/{chunk-D3VO6WNC.js → chunk-PRLD7EXG.js} +3 -3
  72. package/dist/chunk-PRLD7EXG.js.map +1 -0
  73. package/dist/{chunk-N6TA6RSH.js → chunk-PY7AQRGH.js} +59 -13
  74. package/dist/chunk-PY7AQRGH.js.map +1 -0
  75. package/dist/{chunk-NELZIQ2E.js → chunk-QDJKE557.js} +20 -3
  76. package/dist/chunk-QDJKE557.js.map +1 -0
  77. package/dist/{chunk-OYRW5RCM.js → chunk-QHXS3YDV.js} +9 -9
  78. package/dist/chunk-QHXS3YDV.js.map +1 -0
  79. package/dist/{chunk-2F3RUZXC.js → chunk-RTAIGPTF.js} +161 -106
  80. package/dist/chunk-RTAIGPTF.js.map +1 -0
  81. package/dist/{chunk-IPUYL6TD.js → chunk-TV72ZJYN.js} +8 -5
  82. package/dist/{chunk-IPUYL6TD.js.map → chunk-TV72ZJYN.js.map} +1 -1
  83. package/dist/{chunk-ICS76R4T.js → chunk-W7W66MDZ.js} +10 -8
  84. package/dist/chunk-W7W66MDZ.js.map +1 -0
  85. package/dist/{chunk-JQBHCJ6N.js → chunk-WD4LP66U.js} +329 -121
  86. package/dist/chunk-WD4LP66U.js.map +1 -0
  87. package/dist/{chunk-AFLH7B64.js → chunk-XGLGS5B4.js} +3 -3
  88. package/dist/{chunk-AFLH7B64.js.map → chunk-XGLGS5B4.js.map} +1 -1
  89. package/dist/{chunk-HIIARTRZ.js → chunk-YDTW4GT6.js} +450 -207
  90. package/dist/chunk-YDTW4GT6.js.map +1 -0
  91. package/dist/{chunk-2XY6732A.js → chunk-YRU4WB6Y.js} +5 -5
  92. package/dist/chunk-YRU4WB6Y.js.map +1 -0
  93. package/dist/{chunk-542K7SR6.js → chunk-Z5DI7PDG.js} +173 -90
  94. package/dist/chunk-Z5DI7PDG.js.map +1 -0
  95. package/dist/{chunk-KLNL7QHN.js → chunk-ZAP2BDHG.js} +30 -5
  96. package/dist/chunk-ZAP2BDHG.js.map +1 -0
  97. package/dist/{chunk-GCJXPUHG.js → chunk-ZONCCO5N.js} +9 -4
  98. package/dist/chunk-ZONCCO5N.js.map +1 -0
  99. package/dist/{chunk-ODPII24X.js → chunk-ZYDE52WE.js} +3 -3
  100. package/dist/{chunk-ODPII24X.js.map → chunk-ZYDE52WE.js.map} +1 -1
  101. package/dist/cli/index.js +566 -425
  102. package/dist/cli/index.js.map +1 -1
  103. package/dist/cli/src/commands/complete-resolvers.d.ts.map +1 -1
  104. package/dist/cli/src/commands/config.d.ts.map +1 -1
  105. package/dist/cli/src/commands/connector.d.ts +7 -0
  106. package/dist/cli/src/commands/connector.d.ts.map +1 -1
  107. package/dist/cli/src/commands/flow.d.ts +3 -2
  108. package/dist/cli/src/commands/flow.d.ts.map +1 -1
  109. package/dist/cli/src/commands/npx.d.ts.map +1 -1
  110. package/dist/cli/src/commands/project.d.ts.map +1 -1
  111. package/dist/cli/src/commands/run.d.ts.map +1 -1
  112. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  113. package/dist/cli/src/flow-discovery.d.ts +24 -0
  114. package/dist/cli/src/flow-discovery.d.ts.map +1 -0
  115. package/dist/cli/src/open-registry.d.ts +2 -2
  116. package/dist/cli/src/paths.d.ts +26 -9
  117. package/dist/cli/src/paths.d.ts.map +1 -1
  118. package/dist/cli/src/skill-walker.d.ts +9 -5
  119. package/dist/cli/src/skill-walker.d.ts.map +1 -1
  120. package/dist/connectors/config.js +8 -7
  121. package/dist/connectors/index.js +13 -12
  122. package/dist/connectors/rclone-config.js +1 -1
  123. package/dist/connectors/src/connector-manager.d.ts +24 -2
  124. package/dist/connectors/src/connector-manager.d.ts.map +1 -1
  125. package/dist/connectors/src/connector-prompt.d.ts.map +1 -1
  126. package/dist/connectors/src/connector-registry.d.ts +3 -3
  127. package/dist/connectors/src/credential-helper-script.d.ts.map +1 -1
  128. package/dist/connectors/src/index.d.ts +4 -2
  129. package/dist/connectors/src/index.d.ts.map +1 -1
  130. package/dist/connectors/src/managed-gitconfig.d.ts.map +1 -1
  131. package/dist/connectors/src/mount-placeholder.d.ts +68 -0
  132. package/dist/connectors/src/mount-placeholder.d.ts.map +1 -0
  133. package/dist/connectors/src/rclone-config/googledrive.d.ts +1 -1
  134. package/dist/core/discovery.js +1 -1
  135. package/dist/core/index.js +7 -6
  136. package/dist/core/manifest.js +2 -2
  137. package/dist/core/models.js +1 -1
  138. package/dist/core/publish-manifest.d.ts +2 -0
  139. package/dist/core/publish-manifest.js +5 -0
  140. package/dist/core/publish-manifest.js.map +1 -0
  141. package/dist/core/runtime-assets.js +5 -4
  142. package/dist/core/src/discovery.d.ts +27 -0
  143. package/dist/core/src/discovery.d.ts.map +1 -1
  144. package/dist/core/src/index.d.ts +9 -6
  145. package/dist/core/src/index.d.ts.map +1 -1
  146. package/dist/core/src/lock.d.ts.map +1 -1
  147. package/dist/core/src/manifest-yaml-editor.d.ts +62 -0
  148. package/dist/core/src/manifest-yaml-editor.d.ts.map +1 -0
  149. package/dist/core/src/models.d.ts +16 -3
  150. package/dist/core/src/models.d.ts.map +1 -1
  151. package/dist/core/src/publish-manifest.d.ts +160 -0
  152. package/dist/core/src/publish-manifest.d.ts.map +1 -0
  153. package/dist/core/src/repo-manager.d.ts +9 -1
  154. package/dist/core/src/repo-manager.d.ts.map +1 -1
  155. package/dist/core/src/runtime-assets.d.ts +80 -29
  156. package/dist/core/src/runtime-assets.d.ts.map +1 -1
  157. package/dist/core/src/walker.d.ts +19 -6
  158. package/dist/core/src/walker.d.ts.map +1 -1
  159. package/dist/core/src/workspace-config.d.ts +30 -36
  160. package/dist/core/src/workspace-config.d.ts.map +1 -1
  161. package/dist/core/src/workspace-yaml-editor.d.ts +1 -15
  162. package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
  163. package/dist/core/workspace-config.js +4 -3
  164. package/dist/deploy/index.js +50 -79
  165. package/dist/deploy/index.js.map +1 -1
  166. package/dist/deploy/src/targets/container-runtime.d.ts +1 -1
  167. package/dist/deploy/src/targets/container-runtime.d.ts.map +1 -1
  168. package/dist/deploy/src/targets/local.d.ts.map +1 -1
  169. package/dist/deploy/src/targets/nix.d.ts.map +1 -1
  170. package/dist/deploy/src/targets/process-handle.d.ts +7 -5
  171. package/dist/deploy/src/targets/process-handle.d.ts.map +1 -1
  172. package/dist/discovery/index.js +5 -4
  173. package/dist/discovery/src/discover-manifest.d.ts +3 -2
  174. package/dist/discovery/src/discover-manifest.d.ts.map +1 -1
  175. package/dist/discovery/src/discover.d.ts +2 -2
  176. package/dist/discovery/src/discover.d.ts.map +1 -1
  177. package/dist/discovery/src/index.d.ts +1 -1
  178. package/dist/discovery/src/index.d.ts.map +1 -1
  179. package/dist/discovery/src/source-config.d.ts +53 -12
  180. package/dist/discovery/src/source-config.d.ts.map +1 -1
  181. package/dist/discovery/src/tree-entries.d.ts +2 -2
  182. package/dist/discovery/src/tree-entries.d.ts.map +1 -1
  183. package/dist/{ensure-sources-OJUBGX6Z.js → ensure-sources-CVULUVH4.js} +12 -11
  184. package/dist/ensure-sources-CVULUVH4.js.map +1 -0
  185. package/dist/factory-assets/.skaile-source.yaml +6 -0
  186. package/dist/factory-assets/README.md +36 -0
  187. package/dist/factory-assets/bundles/workspaces-authoring/workspaces-authoring.bundle.yaml +9 -0
  188. package/dist/factory-assets/connectors/deploy/CONNECTOR.md +41 -0
  189. package/dist/{base-assets → factory-assets}/connectors/deploy/adapter.d.ts +2 -2
  190. package/dist/factory-assets/connectors/deploy/adapter.d.ts.map +1 -0
  191. package/dist/factory-assets/connectors/deploy.js +22 -0
  192. package/dist/factory-assets/connectors/devserver/CONNECTOR.md +44 -0
  193. package/dist/{base-assets → factory-assets}/connectors/devserver/adapter.d.ts +2 -2
  194. package/dist/factory-assets/connectors/devserver/adapter.d.ts.map +1 -0
  195. package/dist/factory-assets/connectors/devserver.js +22 -0
  196. package/dist/factory-assets/connectors/flow/CONNECTOR.md +47 -0
  197. package/dist/{base-assets → factory-assets}/connectors/flow/adapter.d.ts +2 -2
  198. package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -0
  199. package/dist/factory-assets/connectors/flow/adapter.js +22 -0
  200. package/dist/factory-assets/connectors/flow/engine/engine.d.ts.map +1 -0
  201. package/dist/{base-assets → factory-assets}/connectors/flow/engine/flow-kind-provider.d.ts +1 -1
  202. package/dist/factory-assets/connectors/flow/engine/flow-kind-provider.d.ts.map +1 -0
  203. package/dist/factory-assets/connectors/flow/engine/flow-manifest.d.ts.map +1 -0
  204. package/dist/factory-assets/connectors/flow/engine/index.d.ts.map +1 -0
  205. package/dist/factory-assets/connectors/flow/engine/loader.d.ts.map +1 -0
  206. package/dist/factory-assets/connectors/flow/engine/types.d.ts.map +1 -0
  207. package/dist/factory-assets/connectors/flow/engine.js +15 -0
  208. package/dist/factory-assets/connectors/flow/index.d.ts.map +1 -0
  209. package/dist/{base-assets → factory-assets}/connectors/flow/prompt-fragments.d.ts +5 -5
  210. package/dist/factory-assets/connectors/flow/prompt-fragments.d.ts.map +1 -0
  211. package/dist/{base-assets → factory-assets}/connectors/flow/prompt-fragments.js +1 -1
  212. package/dist/{base-assets → factory-assets}/connectors/flow/run-flow.d.ts +8 -8
  213. package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -0
  214. package/dist/factory-assets/connectors/flow/run-flow.js +25 -0
  215. package/dist/{base-assets → factory-assets}/connectors/flow/stimulus-driver.d.ts +2 -2
  216. package/dist/factory-assets/connectors/flow/stimulus-driver.d.ts.map +1 -0
  217. package/dist/factory-assets/connectors/flow/stimulus-driver.js +4 -0
  218. package/dist/factory-assets/connectors/flow.js +22 -0
  219. package/dist/factory-assets/connectors/git/CONNECTOR.md +145 -0
  220. package/dist/{base-assets → factory-assets}/connectors/git/driver.d.ts +2 -2
  221. package/dist/factory-assets/connectors/git/driver.d.ts.map +1 -0
  222. package/dist/factory-assets/connectors/git.js +22 -0
  223. package/dist/factory-assets/connectors/gmail/CONNECTOR.md +50 -0
  224. package/dist/{base-assets → factory-assets}/connectors/gmail/adapter.d.ts +2 -2
  225. package/dist/factory-assets/connectors/gmail/adapter.d.ts.map +1 -0
  226. package/dist/factory-assets/connectors/gmail.js +22 -0
  227. package/dist/factory-assets/connectors/googledrive/CONNECTOR.md +150 -0
  228. package/dist/{base-assets → factory-assets}/connectors/googledrive/driver.d.ts +2 -2
  229. package/dist/factory-assets/connectors/googledrive/driver.d.ts.map +1 -0
  230. package/dist/factory-assets/connectors/googledrive.js +22 -0
  231. package/dist/factory-assets/connectors/local/CONNECTOR.md +40 -0
  232. package/dist/{base-assets → factory-assets}/connectors/local/driver.d.ts +2 -2
  233. package/dist/factory-assets/connectors/local/driver.d.ts.map +1 -0
  234. package/dist/factory-assets/connectors/local.js +22 -0
  235. package/dist/factory-assets/connectors/mattermost/CONNECTOR.md +65 -0
  236. package/dist/{base-assets → factory-assets}/connectors/mattermost/adapter.d.ts +2 -2
  237. package/dist/factory-assets/connectors/mattermost/adapter.d.ts.map +1 -0
  238. package/dist/factory-assets/connectors/mattermost.js +22 -0
  239. package/dist/factory-assets/connectors/memory/CONNECTOR.md +40 -0
  240. package/dist/{base-assets → factory-assets}/connectors/memory/adapter.d.ts +2 -2
  241. package/dist/factory-assets/connectors/memory/adapter.d.ts.map +1 -0
  242. package/dist/factory-assets/connectors/memory.js +22 -0
  243. package/dist/factory-assets/connectors/minio/CONNECTOR.md +68 -0
  244. package/dist/{base-assets → factory-assets}/connectors/minio/adapter.d.ts +2 -2
  245. package/dist/factory-assets/connectors/minio/adapter.d.ts.map +1 -0
  246. package/dist/factory-assets/connectors/minio.js +22 -0
  247. package/dist/factory-assets/connectors/postgres/CONNECTOR.md +46 -0
  248. package/dist/{base-assets → factory-assets}/connectors/postgres/adapter.d.ts +2 -2
  249. package/dist/factory-assets/connectors/postgres/adapter.d.ts.map +1 -0
  250. package/dist/factory-assets/connectors/postgres.js +22 -0
  251. package/dist/factory-assets/connectors/s3/CONNECTOR.md +76 -0
  252. package/dist/{base-assets → factory-assets}/connectors/s3/driver.d.ts +2 -2
  253. package/dist/factory-assets/connectors/s3/driver.d.ts.map +1 -0
  254. package/dist/factory-assets/connectors/s3.js +22 -0
  255. package/dist/factory-assets/connectors/sharepoint/CONNECTOR.md +181 -0
  256. package/dist/{base-assets → factory-assets}/connectors/sharepoint/driver.d.ts +2 -2
  257. package/dist/factory-assets/connectors/sharepoint/driver.d.ts.map +1 -0
  258. package/dist/factory-assets/connectors/sharepoint.js +22 -0
  259. package/dist/factory-assets/connectors/sqlite/CONNECTOR.md +44 -0
  260. package/dist/{base-assets → factory-assets}/connectors/sqlite/adapter.d.ts +2 -2
  261. package/dist/factory-assets/connectors/sqlite/adapter.d.ts.map +1 -0
  262. package/dist/factory-assets/connectors/sqlite.js +22 -0
  263. package/dist/factory-assets/connectors/static-server/CONNECTOR.md +41 -0
  264. package/dist/{base-assets → factory-assets}/connectors/static-server/adapter.d.ts +2 -2
  265. package/dist/factory-assets/connectors/static-server/adapter.d.ts.map +1 -0
  266. package/dist/factory-assets/connectors/static-server.js +22 -0
  267. package/dist/factory-assets/connectors/tunnel/CONNECTOR.md +40 -0
  268. package/dist/{base-assets → factory-assets}/connectors/tunnel/adapter.d.ts +2 -2
  269. package/dist/factory-assets/connectors/tunnel/adapter.d.ts.map +1 -0
  270. package/dist/factory-assets/connectors/tunnel.js +22 -0
  271. package/dist/factory-assets/connectors/webdav/CONNECTOR.md +139 -0
  272. package/dist/{base-assets → factory-assets}/connectors/webdav/driver.d.ts +2 -2
  273. package/dist/factory-assets/connectors/webdav/driver.d.ts.map +1 -0
  274. package/dist/factory-assets/connectors/webdav.js +22 -0
  275. package/dist/factory-assets/connectors/xstate/CONNECTOR.md +57 -0
  276. package/dist/{base-assets → factory-assets}/connectors/xstate/adapter.d.ts +2 -2
  277. package/dist/factory-assets/connectors/xstate/adapter.d.ts.map +1 -0
  278. package/dist/factory-assets/connectors/xstate-store/CONNECTOR.md +48 -0
  279. package/dist/{base-assets → factory-assets}/connectors/xstate-store/adapter.d.ts +2 -2
  280. package/dist/factory-assets/connectors/xstate-store/adapter.d.ts.map +1 -0
  281. package/dist/factory-assets/connectors/xstate-store.js +22 -0
  282. package/dist/factory-assets/connectors/xstate.js +22 -0
  283. package/dist/{base-assets → factory-assets}/index.d.ts +1 -1
  284. package/dist/factory-assets/index.d.ts.map +1 -0
  285. package/dist/{base-assets → factory-assets}/index.js +1 -1
  286. package/dist/factory-assets/index.js.map +1 -0
  287. package/dist/factory-assets/skaile.manifest.yaml +25 -0
  288. package/dist/factory-assets/skills/authoring-skaile-assets/SKILL.md +176 -0
  289. package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +243 -0
  290. package/dist/factory-assets/skills/authoring-skaile-manifests/references/dependency-standard.md +197 -0
  291. package/dist/factory-assets/skills/manifest-compliance/SKILL.md +140 -0
  292. package/dist/factory-assets/skills/skaile-author-asset/SKILL.md +239 -0
  293. package/dist/factory-assets/skills/skaile-manage-workspace/SKILL.md +168 -0
  294. package/dist/{flows-DYFTPCPM.js → flows-JZFJD5IN.js} +3 -3
  295. package/dist/{flows-DYFTPCPM.js.map → flows-JZFJD5IN.js.map} +1 -1
  296. package/dist/library/index.js +14 -5
  297. package/dist/library/src/install/install-from-manifest.d.ts.map +1 -1
  298. package/dist/library/src/library.d.ts +2 -0
  299. package/dist/library/src/library.d.ts.map +1 -1
  300. package/dist/library/src/local/library.d.ts +2 -0
  301. package/dist/library/src/local/library.d.ts.map +1 -1
  302. package/dist/library/src/local/local-catalog-source.d.ts +2 -1
  303. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  304. package/dist/library/src/local/sidecar-paths.d.ts +4 -4
  305. package/dist/library/src/local/sidecar-paths.d.ts.map +1 -1
  306. package/dist/library/src/local/store-paths.d.ts +4 -3
  307. package/dist/library/src/local/store-paths.d.ts.map +1 -1
  308. package/dist/library/src/pin-resolver.d.ts.map +1 -1
  309. package/dist/library/src/preset/apply.d.ts.map +1 -1
  310. package/dist/library/src/preset/placeholders.d.ts.map +1 -1
  311. package/dist/library/src/remote/remote-catalog-source.d.ts +7 -0
  312. package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
  313. package/dist/library/src/remote/rest-catalog-source.d.ts +7 -0
  314. package/dist/library/src/remote/rest-catalog-source.d.ts.map +1 -1
  315. package/dist/library/src/sync/manifest-writeback.d.ts +1 -1
  316. package/dist/library/src/sync/manifest-writeback.d.ts.map +1 -1
  317. package/dist/open-library-WYASW4BH.js +22 -0
  318. package/dist/{open-library-67FSSQWE.js.map → open-library-WYASW4BH.js.map} +1 -1
  319. package/dist/paths-BMW6JYW6.js +15 -0
  320. package/dist/{paths-FKKGS6BA.js.map → paths-BMW6JYW6.js.map} +1 -1
  321. package/dist/{plugin-store-IZ5SCRAV.js → plugin-store-O5VR45CA.js} +9 -8
  322. package/dist/plugin-store-O5VR45CA.js.map +1 -0
  323. package/dist/plugins/src/asset-kind-provider.d.ts +1 -1
  324. package/dist/plugins/src/catalog-source.d.ts +13 -0
  325. package/dist/plugins/src/catalog-source.d.ts.map +1 -1
  326. package/dist/resolver/index.js +1 -1
  327. package/dist/resolver/src/parser.d.ts.map +1 -1
  328. package/dist/runner/index.js +20 -19
  329. package/dist/runner/src/capability-registry.d.ts +1 -1
  330. package/dist/runner/src/capability-registry.d.ts.map +1 -1
  331. package/dist/runner/src/external-mcp.d.ts +112 -0
  332. package/dist/runner/src/external-mcp.d.ts.map +1 -0
  333. package/dist/runner/src/resource-handler.d.ts.map +1 -1
  334. package/dist/runner/src/resources.d.ts +10 -2
  335. package/dist/runner/src/resources.d.ts.map +1 -1
  336. package/dist/runner/src/serve.d.ts.map +1 -1
  337. package/dist/runner/src/session-builder.d.ts +12 -0
  338. package/dist/runner/src/session-builder.d.ts.map +1 -1
  339. package/dist/runner/src/workspace-migration.d.ts.map +1 -1
  340. package/dist/sdk/asset-manager.js +11 -10
  341. package/dist/sdk/bridge.js +4 -4
  342. package/dist/sdk/core.js +7 -6
  343. package/dist/sdk/flow.js +12 -1
  344. package/dist/sdk/index.js +23 -22
  345. package/dist/sdk/index.js.map +1 -1
  346. package/dist/sdk/resolver.js +1 -1
  347. package/dist/sdk/runner.js +20 -19
  348. package/dist/sdk/session.js +1 -1
  349. package/dist/sdk/src/flow/index.d.ts +1 -1
  350. package/dist/sdk/src/flow/index.d.ts.map +1 -1
  351. package/dist/sdk/src/workspace.d.ts +3 -2
  352. package/dist/sdk/src/workspace.d.ts.map +1 -1
  353. package/dist/sdk/telemetry.js +1 -1
  354. package/dist/secrets/index.js +1 -1
  355. package/dist/secrets/src/providers/env.d.ts.map +1 -1
  356. package/dist/secrets/src/providers/local.d.ts.map +1 -1
  357. package/dist/session/index.js +1 -1
  358. package/dist/session/src/mentions.d.ts.map +1 -1
  359. package/dist/{setup-J7CYEQOF.js → setup-YNLFR5GB.js} +13 -12
  360. package/dist/setup-YNLFR5GB.js.map +1 -0
  361. package/dist/skills-6HJ3WINN.js +7 -0
  362. package/dist/{skills-CRL3VJNN.js.map → skills-6HJ3WINN.js.map} +1 -1
  363. package/dist/store-client-CENBEASX.js +15 -0
  364. package/dist/{store-client-AEI6Y3KD.js.map → store-client-CENBEASX.js.map} +1 -1
  365. package/dist/telemetry/index.js +1 -1
  366. package/dist/telemetry/src/config.d.ts +0 -16
  367. package/dist/telemetry/src/config.d.ts.map +1 -1
  368. package/dist/tui/index.js +20 -19
  369. package/dist/tui/index.js.map +1 -1
  370. package/dist/types/manifests.js +1 -1
  371. package/dist/types/src/flow.d.ts +2 -2
  372. package/dist/types/src/install-manifest.d.ts +1 -1
  373. package/dist/types/src/install-manifest.d.ts.map +1 -1
  374. package/dist/types/src/manifests/index.d.ts +1 -1
  375. package/dist/types/src/manifests/skill.d.ts +21 -0
  376. package/dist/types/src/manifests/skill.d.ts.map +1 -1
  377. package/dist/workspace-plugin/adapters/mcp.js +4 -4
  378. package/dist/workspace-plugin/adapters/omp.js +7 -7
  379. package/dist/workspace-plugin/index.js +1 -1
  380. package/dist/workspace-plugin/src/tools/flows.d.ts.map +1 -1
  381. package/package.json +158 -151
  382. package/dist/asset-feeds-WKIKSZ6Z.js.map +0 -1
  383. package/dist/base-assets/connectors/deploy/adapter.d.ts.map +0 -1
  384. package/dist/base-assets/connectors/deploy.js +0 -21
  385. package/dist/base-assets/connectors/devserver/adapter.d.ts.map +0 -1
  386. package/dist/base-assets/connectors/devserver.js +0 -21
  387. package/dist/base-assets/connectors/flow/adapter.d.ts.map +0 -1
  388. package/dist/base-assets/connectors/flow/adapter.js +0 -21
  389. package/dist/base-assets/connectors/flow/engine/engine.d.ts.map +0 -1
  390. package/dist/base-assets/connectors/flow/engine/flow-kind-provider.d.ts.map +0 -1
  391. package/dist/base-assets/connectors/flow/engine/flow-manifest.d.ts.map +0 -1
  392. package/dist/base-assets/connectors/flow/engine/index.d.ts.map +0 -1
  393. package/dist/base-assets/connectors/flow/engine/loader.d.ts.map +0 -1
  394. package/dist/base-assets/connectors/flow/engine/types.d.ts.map +0 -1
  395. package/dist/base-assets/connectors/flow/engine.js +0 -4
  396. package/dist/base-assets/connectors/flow/index.d.ts.map +0 -1
  397. package/dist/base-assets/connectors/flow/prompt-fragments.d.ts.map +0 -1
  398. package/dist/base-assets/connectors/flow/run-flow.d.ts.map +0 -1
  399. package/dist/base-assets/connectors/flow/run-flow.js +0 -24
  400. package/dist/base-assets/connectors/flow/stimulus-driver.d.ts.map +0 -1
  401. package/dist/base-assets/connectors/flow/stimulus-driver.js +0 -4
  402. package/dist/base-assets/connectors/flow.js +0 -21
  403. package/dist/base-assets/connectors/git/driver.d.ts.map +0 -1
  404. package/dist/base-assets/connectors/git.js +0 -21
  405. package/dist/base-assets/connectors/gmail/adapter.d.ts.map +0 -1
  406. package/dist/base-assets/connectors/gmail.js +0 -21
  407. package/dist/base-assets/connectors/googledrive/driver.d.ts.map +0 -1
  408. package/dist/base-assets/connectors/googledrive.js +0 -21
  409. package/dist/base-assets/connectors/local/driver.d.ts.map +0 -1
  410. package/dist/base-assets/connectors/local.js +0 -21
  411. package/dist/base-assets/connectors/mattermost/adapter.d.ts.map +0 -1
  412. package/dist/base-assets/connectors/mattermost.js +0 -21
  413. package/dist/base-assets/connectors/memory/adapter.d.ts.map +0 -1
  414. package/dist/base-assets/connectors/memory.js +0 -21
  415. package/dist/base-assets/connectors/minio/adapter.d.ts.map +0 -1
  416. package/dist/base-assets/connectors/minio.js +0 -21
  417. package/dist/base-assets/connectors/postgres/adapter.d.ts.map +0 -1
  418. package/dist/base-assets/connectors/postgres.js +0 -21
  419. package/dist/base-assets/connectors/s3/driver.d.ts.map +0 -1
  420. package/dist/base-assets/connectors/s3.js +0 -21
  421. package/dist/base-assets/connectors/sharepoint/driver.d.ts.map +0 -1
  422. package/dist/base-assets/connectors/sharepoint.js +0 -21
  423. package/dist/base-assets/connectors/sqlite/adapter.d.ts.map +0 -1
  424. package/dist/base-assets/connectors/sqlite.js +0 -21
  425. package/dist/base-assets/connectors/static-server/adapter.d.ts.map +0 -1
  426. package/dist/base-assets/connectors/static-server.js +0 -21
  427. package/dist/base-assets/connectors/tunnel/adapter.d.ts.map +0 -1
  428. package/dist/base-assets/connectors/tunnel.js +0 -21
  429. package/dist/base-assets/connectors/webdav/driver.d.ts.map +0 -1
  430. package/dist/base-assets/connectors/webdav.js +0 -21
  431. package/dist/base-assets/connectors/xstate/adapter.d.ts.map +0 -1
  432. package/dist/base-assets/connectors/xstate-store/adapter.d.ts.map +0 -1
  433. package/dist/base-assets/connectors/xstate-store.js +0 -21
  434. package/dist/base-assets/connectors/xstate.js +0 -21
  435. package/dist/base-assets/index.d.ts.map +0 -1
  436. package/dist/base-assets/index.js.map +0 -1
  437. package/dist/chunk-2F3RUZXC.js.map +0 -1
  438. package/dist/chunk-2M3XTMOL.js +0 -23
  439. package/dist/chunk-2M3XTMOL.js.map +0 -1
  440. package/dist/chunk-2RFOFHSM.js.map +0 -1
  441. package/dist/chunk-2XY6732A.js.map +0 -1
  442. package/dist/chunk-46COM7M5.js.map +0 -1
  443. package/dist/chunk-542K7SR6.js.map +0 -1
  444. package/dist/chunk-5ESCS2OS.js.map +0 -1
  445. package/dist/chunk-D3VO6WNC.js.map +0 -1
  446. package/dist/chunk-DQWREFRQ.js.map +0 -1
  447. package/dist/chunk-FVTV7M76.js.map +0 -1
  448. package/dist/chunk-GCJXPUHG.js.map +0 -1
  449. package/dist/chunk-GZWJGNNN.js.map +0 -1
  450. package/dist/chunk-HIIARTRZ.js.map +0 -1
  451. package/dist/chunk-ICS76R4T.js.map +0 -1
  452. package/dist/chunk-JDX54X4Y.js.map +0 -1
  453. package/dist/chunk-JQBHCJ6N.js.map +0 -1
  454. package/dist/chunk-KLNL7QHN.js.map +0 -1
  455. package/dist/chunk-KOVLSBXK.js.map +0 -1
  456. package/dist/chunk-LJ52ZKIU.js.map +0 -1
  457. package/dist/chunk-M5TE6YI5.js.map +0 -1
  458. package/dist/chunk-N6TA6RSH.js.map +0 -1
  459. package/dist/chunk-NELZIQ2E.js.map +0 -1
  460. package/dist/chunk-OYRW5RCM.js.map +0 -1
  461. package/dist/chunk-QAVZOJCV.js.map +0 -1
  462. package/dist/chunk-YX3UWPJ5.js.map +0 -1
  463. package/dist/chunk-Z3M5K67G.js.map +0 -1
  464. package/dist/ensure-sources-OJUBGX6Z.js.map +0 -1
  465. package/dist/open-library-67FSSQWE.js +0 -13
  466. package/dist/paths-FKKGS6BA.js +0 -4
  467. package/dist/plugin-store-IZ5SCRAV.js.map +0 -1
  468. package/dist/setup-J7CYEQOF.js.map +0 -1
  469. package/dist/skills-CRL3VJNN.js +0 -7
  470. package/dist/store-client-AEI6Y3KD.js +0 -14
  471. /package/dist/{base-assets → factory-assets}/connectors/deploy.d.ts +0 -0
  472. /package/dist/{base-assets → factory-assets}/connectors/deploy.js.map +0 -0
  473. /package/dist/{base-assets → factory-assets}/connectors/devserver.d.ts +0 -0
  474. /package/dist/{base-assets → factory-assets}/connectors/devserver.js.map +0 -0
  475. /package/dist/{base-assets → factory-assets}/connectors/flow/adapter.js.map +0 -0
  476. /package/dist/{base-assets → factory-assets}/connectors/flow/engine/engine.d.ts +0 -0
  477. /package/dist/{base-assets → factory-assets}/connectors/flow/engine/flow-manifest.d.ts +0 -0
  478. /package/dist/{base-assets → factory-assets}/connectors/flow/engine/index.d.ts +0 -0
  479. /package/dist/{base-assets → factory-assets}/connectors/flow/engine/loader.d.ts +0 -0
  480. /package/dist/{base-assets → factory-assets}/connectors/flow/engine/types.d.ts +0 -0
  481. /package/dist/{base-assets → factory-assets}/connectors/flow/engine.d.ts +0 -0
  482. /package/dist/{base-assets → factory-assets}/connectors/flow/engine.js.map +0 -0
  483. /package/dist/{base-assets → factory-assets}/connectors/flow/index.d.ts +0 -0
  484. /package/dist/{base-assets → factory-assets}/connectors/flow/prompt-fragments.js.map +0 -0
  485. /package/dist/{base-assets → factory-assets}/connectors/flow/run-flow.js.map +0 -0
  486. /package/dist/{base-assets → factory-assets}/connectors/flow/stimulus-driver.js.map +0 -0
  487. /package/dist/{base-assets → factory-assets}/connectors/flow.d.ts +0 -0
  488. /package/dist/{base-assets → factory-assets}/connectors/flow.js.map +0 -0
  489. /package/dist/{base-assets → factory-assets}/connectors/git.d.ts +0 -0
  490. /package/dist/{base-assets → factory-assets}/connectors/git.js.map +0 -0
  491. /package/dist/{base-assets → factory-assets}/connectors/gmail.d.ts +0 -0
  492. /package/dist/{base-assets → factory-assets}/connectors/gmail.js.map +0 -0
  493. /package/dist/{base-assets → factory-assets}/connectors/googledrive.d.ts +0 -0
  494. /package/dist/{base-assets → factory-assets}/connectors/googledrive.js.map +0 -0
  495. /package/dist/{base-assets → factory-assets}/connectors/local.d.ts +0 -0
  496. /package/dist/{base-assets → factory-assets}/connectors/local.js.map +0 -0
  497. /package/dist/{base-assets → factory-assets}/connectors/mattermost.d.ts +0 -0
  498. /package/dist/{base-assets → factory-assets}/connectors/mattermost.js.map +0 -0
  499. /package/dist/{base-assets → factory-assets}/connectors/memory.d.ts +0 -0
  500. /package/dist/{base-assets → factory-assets}/connectors/memory.js.map +0 -0
  501. /package/dist/{base-assets → factory-assets}/connectors/minio.d.ts +0 -0
  502. /package/dist/{base-assets → factory-assets}/connectors/minio.js.map +0 -0
  503. /package/dist/{base-assets → factory-assets}/connectors/postgres.d.ts +0 -0
  504. /package/dist/{base-assets → factory-assets}/connectors/postgres.js.map +0 -0
  505. /package/dist/{base-assets → factory-assets}/connectors/s3.d.ts +0 -0
  506. /package/dist/{base-assets → factory-assets}/connectors/s3.js.map +0 -0
  507. /package/dist/{base-assets → factory-assets}/connectors/sharepoint.d.ts +0 -0
  508. /package/dist/{base-assets → factory-assets}/connectors/sharepoint.js.map +0 -0
  509. /package/dist/{base-assets → factory-assets}/connectors/sqlite.d.ts +0 -0
  510. /package/dist/{base-assets → factory-assets}/connectors/sqlite.js.map +0 -0
  511. /package/dist/{base-assets → factory-assets}/connectors/static-server.d.ts +0 -0
  512. /package/dist/{base-assets → factory-assets}/connectors/static-server.js.map +0 -0
  513. /package/dist/{base-assets → factory-assets}/connectors/tunnel.d.ts +0 -0
  514. /package/dist/{base-assets → factory-assets}/connectors/tunnel.js.map +0 -0
  515. /package/dist/{base-assets → factory-assets}/connectors/webdav.d.ts +0 -0
  516. /package/dist/{base-assets → factory-assets}/connectors/webdav.js.map +0 -0
  517. /package/dist/{base-assets → factory-assets}/connectors/xstate-store.d.ts +0 -0
  518. /package/dist/{base-assets → factory-assets}/connectors/xstate-store.js.map +0 -0
  519. /package/dist/{base-assets → factory-assets}/connectors/xstate.d.ts +0 -0
  520. /package/dist/{base-assets → factory-assets}/connectors/xstate.js.map +0 -0
@@ -173,6 +173,25 @@ function classifyClaudeSdkError(input) {
173
173
  retryable: true
174
174
  };
175
175
  }
176
+ function classifyGenericErrorMessage(msg) {
177
+ const lower = msg.toLowerCase();
178
+ if (lower.includes("api key") || lower.includes("unauthorized") || lower.includes("authentication") || lower.includes("401")) {
179
+ return { category: "auth", retryable: false };
180
+ }
181
+ if (lower.includes("rate limit") || lower.includes("429") || lower.includes("too many requests") || lower.includes("quota")) {
182
+ return { category: "rate_limit", retryable: true };
183
+ }
184
+ if (lower.includes("model") && (lower.includes("not found") || lower.includes("not available") || lower.includes("does not exist"))) {
185
+ return { category: "model", retryable: false };
186
+ }
187
+ if (lower.includes("context length") || lower.includes("too long") || lower.includes("token limit") || lower.includes("max_tokens")) {
188
+ return { category: "model", retryable: false };
189
+ }
190
+ if (lower.includes("timeout") || lower.includes("econnrefused") || lower.includes("enotfound") || lower.includes("network") || lower.includes("fetch failed") || lower.includes("fetch") || lower.includes("connection")) {
191
+ return { category: "network", retryable: true };
192
+ }
193
+ return null;
194
+ }
176
195
  function oauthQuotaHint(oauthCredential) {
177
196
  if (oauthCredential) {
178
197
  return "Quota exhausted on this Claude Code subscription. Wait for the rate-limit window to reset (typically a few minutes for short windows, longer for daily/weekly limits) before retrying. The credential itself is fine.";
@@ -230,6 +249,6 @@ function tryParseEmbeddedAnthropicError(text) {
230
249
  return { errorType, statusCode };
231
250
  }
232
251
 
233
- export { AuthError, classifyClaudeSdkError };
234
- //# sourceMappingURL=chunk-DQWREFRQ.js.map
235
- //# sourceMappingURL=chunk-DQWREFRQ.js.map
252
+ export { AuthError, classifyClaudeSdkError, classifyGenericErrorMessage };
253
+ //# sourceMappingURL=chunk-PAYAFNXG.js.map
254
+ //# sourceMappingURL=chunk-PAYAFNXG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../bridge/src/error-classifier.ts"],"names":[],"mappings":"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","file":"chunk-PAYAFNXG.js","sourcesContent":["/**\n * Error classification for the Claude Agent SDK driver.\n *\n * Wraps the Anthropic API error patterns surfaced through the bundled\n * `claude-cli.js`. The CLI flattens upstream HTTP errors into terse strings\n * like:\n *\n * `Claude Code returned an error result: Failed to authenticate. API Error:\n * 401 {\"type\":\"error\",\"error\":{\"type\":\"authentication_error\",\"message\":\n * \"Invalid authentication credentials\"}}`\n *\n * Word-for-word that reads as an auth failure, but in practice it also\n * fires when a Claude Max OAuth subscription has exhausted its current\n * quota window — Anthropic returns a non-200 that the CLI relabels as\n * \"Failed to authenticate\" without preserving the original error type.\n *\n * The classifier here:\n * 1. Parses an embedded JSON body when the upstream included one\n * (e.g. `{\"type\":\"error\",\"error\":{\"type\":\"rate_limit_error\",...}}`)\n * so we believe the structured `error.type` over the surrounding\n * free-text wrapper.\n * 2. Honours the SDK's `terminal_reason` when it explicitly indicates\n * a blocking-limit / rapid-refill / model-error condition — those\n * are authoritative even if the textual error reads as auth.\n * 3. Falls back to keyword heuristics on the message text.\n * 4. For OAuth-style credentials (Claude Code subscriptions), adds a\n * hint that bounces user attention to quota rather than credentials,\n * because that's overwhelmingly the cause when a CredentialsFile\n * provider that worked yesterday now returns \"Invalid authentication\n * credentials\" without anyone touching the file.\n */\n\nimport type { AgentError } from \"./types.js\";\n\n/**\n * Error thrown by drivers when the upstream provider rejects the credential\n * with an authentication-shaped failure (HTTP 401 / `authentication_error`\n * structured body). Carries the structured {@link AgentError} produced by\n * {@link classifyClaudeSdkError} so the runner can mediate without\n * re-classifying string text.\n *\n * The runner's 401-mediation handler `instanceof`-discriminates on this\n * subclass so the auth-vs-rate_limit fork stays in one place.\n *\n * Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n * § \"Runner-side handling on 401\".\n *\n * @category Errors\n * @since 3.3.0\n */\nexport class AuthError extends Error {\n readonly detail: AgentError;\n constructor(detail: AgentError) {\n super(detail.message);\n this.name = \"AuthError\";\n this.detail = detail;\n }\n}\n\n/**\n * `terminal_reason` values from the Claude Agent SDK that imply the failure\n * is a rate / quota / blocking condition rather than a credential problem.\n */\nconst RATE_LIMIT_TERMINAL_REASONS = new Set<string>([\"blocking_limit\", \"rapid_refill_breaker\"]);\n\n/**\n * `terminal_reason` values that indicate a generic, retryable model failure.\n * `prompt_too_long` is handled separately (not retryable, different hint).\n */\nconst MODEL_TERMINAL_REASONS = new Set<string>([\"model_error\", \"image_error\"]);\n\n/**\n * Input shape for {@link classifyClaudeSdkError} when decoding an `SDKResultError`.\n *\n * All fields are optional; `classifyClaudeSdkError` also accepts a plain `string`\n * (a thrown exception message) for the common non-SDK code paths.\n *\n * @docLink packages/bridge/api-reference#error-classifier\n */\nexport interface ClaudeSdkResultErrorInput {\n /** `errors` array from `SDKResultError`. Empty when not provided. */\n errors?: string[];\n /**\n * `terminal_reason` from `SDKResultError`. Authoritative when set to a\n * blocking/rapid-refill value, regardless of message text.\n */\n terminalReason?: string;\n /** `subtype` from `SDKResultError` — `error_max_turns` etc. */\n subtype?: string;\n /**\n * `true` when the configured Anthropic credential is a Claude Code\n * subscription (`CredentialsFile` provider) rather than a raw API key.\n * Changes the hint copy because `Invalid authentication credentials`\n * on an OAuth subscription almost always means quota.\n */\n oauthCredential?: boolean;\n}\n\n/**\n * Classify a Claude SDK result-error or thrown error into a structured\n * {@link AgentError}. Pure function — safe to call from any layer.\n *\n * @param input - Either a free-text error message (from a thrown exception)\n * or a partially-decoded `SDKResultError` shape with `errors[]`,\n * `terminal_reason`, and `subtype`.\n * @returns A category, retryable flag, and human-readable hint.\n * @docLink packages/bridge/api-reference#error-classifier\n */\nexport function classifyClaudeSdkError(input: string | ClaudeSdkResultErrorInput): AgentError {\n const opts: ClaudeSdkResultErrorInput = typeof input === \"string\" ? { errors: [input] } : input;\n\n const message = (opts.errors ?? []).join(\"; \") || \"Unknown agent error\";\n\n // ── 1. Honour authoritative `terminal_reason` ──────────────────────────\n if (opts.terminalReason && RATE_LIMIT_TERMINAL_REASONS.has(opts.terminalReason)) {\n return {\n message,\n category: \"rate_limit\",\n retryable: true,\n hint: oauthQuotaHint(opts.oauthCredential),\n };\n }\n if (opts.terminalReason === \"prompt_too_long\") {\n return {\n message,\n category: \"model\",\n retryable: false,\n hint: \"The conversation is too long for the configured model. Start a new session or compact the existing one.\",\n };\n }\n if (opts.terminalReason && MODEL_TERMINAL_REASONS.has(opts.terminalReason)) {\n return {\n message,\n category: \"model\",\n retryable: true,\n hint: \"The model rejected this turn. Try again or switch models.\",\n };\n }\n\n // ── 2. Inspect embedded JSON body for a structured error.type ──────────\n const structured = tryParseEmbeddedAnthropicError(message);\n if (structured) {\n if (structured.errorType === \"rate_limit_error\") {\n return {\n message,\n category: \"rate_limit\",\n statusCode: structured.statusCode ?? 429,\n retryable: true,\n hint: oauthQuotaHint(opts.oauthCredential),\n };\n }\n if (structured.errorType === \"overloaded_error\") {\n return {\n message,\n category: \"rate_limit\",\n statusCode: structured.statusCode ?? 529,\n retryable: true,\n hint: \"Anthropic is overloaded. Try again in a moment.\",\n };\n }\n if (structured.errorType === \"authentication_error\") {\n // Anthropic genuinely says it's an auth failure. But for OAuth\n // credentials with the `oauth-2025-04-20` beta flow, this still\n // overwhelmingly correlates with quota. Surface both possibilities\n // in the hint so the user does not first re-upload a perfectly\n // good credentials file.\n return {\n message,\n category: \"auth\",\n statusCode: structured.statusCode ?? 401,\n retryable: false,\n hint: opts.oauthCredential\n ? \"Anthropic rejected the OAuth credential. With Claude Code subscriptions this is usually a quota or rate-limit issue rather than an invalid token — wait a few minutes before re-uploading the credentials file. If it persists, re-export `~/.claude/.credentials.json` from a working Claude Code install.\"\n : \"Anthropic rejected the API key. Check it in Settings -> AI Providers.\",\n };\n }\n if (structured.errorType === \"permission_error\") {\n return {\n message,\n category: \"auth\",\n statusCode: structured.statusCode ?? 403,\n retryable: false,\n hint: \"The configured credential does not have access to the requested model.\",\n };\n }\n if (structured.errorType === \"invalid_request_error\") {\n return {\n message,\n category: \"validation\",\n statusCode: structured.statusCode ?? 400,\n retryable: false,\n hint: \"Anthropic rejected the request shape. This is likely a bug — please report it.\",\n };\n }\n }\n\n // ── 3. Heuristic keyword classification on the wrapper text ────────────\n const lower = message.toLowerCase();\n\n if (\n lower.includes(\"rate limit\") ||\n lower.includes(\"rate_limit\") ||\n lower.includes(\"too many requests\") ||\n lower.includes(\"429\") ||\n lower.includes(\"quota\") ||\n lower.includes(\"blocking_limit\") ||\n lower.includes(\"rapid_refill\")\n ) {\n return {\n message,\n category: \"rate_limit\",\n retryable: true,\n hint: oauthQuotaHint(opts.oauthCredential),\n };\n }\n\n if (\n lower.includes(\"credit balance\") ||\n lower.includes(\"insufficient credit\") ||\n lower.includes(\"out of credits\")\n ) {\n return {\n message,\n category: \"rate_limit\",\n retryable: false,\n hint: \"The configured Anthropic account is out of credits. Top up at https://console.anthropic.com/ or switch providers.\",\n };\n }\n\n if (lower.includes(\"oauth authentication is currently not supported\")) {\n return {\n message,\n category: \"auth\",\n statusCode: 401,\n retryable: false,\n hint: \"The Claude Code CLI did not send the OAuth beta header. The bundled CLI in this image is too old — rebuild the agent image.\",\n };\n }\n\n // The Claude Code CLI emits this terse, JSON-less string when it finds no\n // usable credential — most commonly because the OAuth access token in\n // `~/.claude/.credentials.json` expired and the file carries no refresh token\n // (the platform provisions access-token-only files by design). It MUST be\n // classified as `auth` so the driver promotes it to `AuthError` and the\n // `onAuthError` self-heal re-mints the credential. Without this branch the\n // message falls through to `unknown`, the self-heal never fires, and every\n // subsequent turn dead-ends on \"please /login\". The check sits ahead of the\n // generic auth keywords because the string contains none of them.\n if (lower.includes(\"not logged in\") || lower.includes(\"please run /login\")) {\n return {\n message,\n category: \"auth\",\n statusCode: 401,\n retryable: false,\n hint: opts.oauthCredential\n ? \"The Claude Code OAuth credential expired and could not be auto-refreshed in-container. The runner will re-mint it — retry the prompt. If it persists, re-export `~/.claude/.credentials.json` from a working Claude Code install.\"\n : \"No Anthropic credential is configured for this provider. Add one in Settings -> AI Providers.\",\n };\n }\n\n if (\n lower.includes(\"api key\") ||\n lower.includes(\"authentication\") ||\n lower.includes(\"invalid authentication\") ||\n lower.includes(\"unauthorized\") ||\n lower.includes(\"401\") ||\n lower.includes(\"403\")\n ) {\n return {\n message,\n category: \"auth\",\n retryable: false,\n hint: opts.oauthCredential\n ? \"Anthropic rejected the OAuth credential. With Claude Code subscriptions this is usually a quota or rate-limit issue rather than an invalid token — wait a few minutes before re-uploading the credentials file.\"\n : \"Check the API key configured for this AI provider in Settings.\",\n };\n }\n\n if (\n lower.includes(\"model\") &&\n (lower.includes(\"not found\") ||\n lower.includes(\"not available\") ||\n lower.includes(\"does not exist\"))\n ) {\n return {\n message,\n category: \"model\",\n retryable: false,\n hint: \"The selected model is not available for this credential. Change the model in the AI provider config.\",\n };\n }\n\n if (\n lower.includes(\"context length\") ||\n lower.includes(\"token limit\") ||\n lower.includes(\"max_tokens\") ||\n lower.includes(\"prompt is too long\") ||\n lower.includes(\"prompt_too_long\")\n ) {\n return {\n message,\n category: \"model\",\n retryable: false,\n hint: \"The conversation is too long for the model. Start a new session or compact this one.\",\n };\n }\n\n if (\n lower.includes(\"timeout\") ||\n lower.includes(\"econnrefused\") ||\n lower.includes(\"enotfound\") ||\n lower.includes(\"fetch failed\") ||\n lower.includes(\"network\")\n ) {\n return {\n message,\n category: \"network\",\n retryable: true,\n hint: \"Network error reaching Anthropic. The runner will retry — try again if it persists.\",\n };\n }\n\n if (opts.subtype === \"error_max_turns\") {\n return {\n message,\n category: \"unknown\",\n retryable: true,\n hint: \"The agent stopped after reaching `max_turns`. Resume the session or raise `max_turns` in the agent config.\",\n };\n }\n if (opts.subtype === \"error_max_budget_usd\") {\n return {\n message,\n category: \"rate_limit\",\n retryable: false,\n hint: \"The agent stopped because it hit the configured per-turn budget. Raise the budget or split the work.\",\n };\n }\n\n return {\n message,\n category: \"unknown\",\n retryable: true,\n };\n}\n\n/**\n * The shared keyword buckets matched by {@link classifyGenericErrorMessage}.\n * Drivers layer a provider-specific `hint` on top of the returned category.\n */\nexport type GenericErrorCategory = \"auth\" | \"rate_limit\" | \"model\" | \"network\";\n\n/**\n * Classify a free-text driver error against the keyword buckets common to the\n * subprocess/SDK drivers (omp, codex). Returns the matched `category` +\n * `retryable` flag, or `null` when no shared bucket matches so the caller can\n * fall through to its own provider-specific buckets (e.g. codex sandbox) and\n * `unknown` default. The driver supplies the user-facing `hint` — only the\n * bucketing logic is shared, not the copy.\n */\nexport function classifyGenericErrorMessage(\n msg: string,\n): { category: GenericErrorCategory; retryable: boolean } | null {\n const lower = msg.toLowerCase();\n if (\n lower.includes(\"api key\") ||\n lower.includes(\"unauthorized\") ||\n lower.includes(\"authentication\") ||\n lower.includes(\"401\")\n ) {\n return { category: \"auth\", retryable: false };\n }\n if (\n lower.includes(\"rate limit\") ||\n lower.includes(\"429\") ||\n lower.includes(\"too many requests\") ||\n lower.includes(\"quota\")\n ) {\n return { category: \"rate_limit\", retryable: true };\n }\n if (\n lower.includes(\"model\") &&\n (lower.includes(\"not found\") ||\n lower.includes(\"not available\") ||\n lower.includes(\"does not exist\"))\n ) {\n return { category: \"model\", retryable: false };\n }\n if (\n lower.includes(\"context length\") ||\n lower.includes(\"too long\") ||\n lower.includes(\"token limit\") ||\n lower.includes(\"max_tokens\")\n ) {\n return { category: \"model\", retryable: false };\n }\n if (\n lower.includes(\"timeout\") ||\n lower.includes(\"econnrefused\") ||\n lower.includes(\"enotfound\") ||\n lower.includes(\"network\") ||\n lower.includes(\"fetch failed\") ||\n lower.includes(\"fetch\") ||\n lower.includes(\"connection\")\n ) {\n return { category: \"network\", retryable: true };\n }\n return null;\n}\n\n/**\n * Returns the rate-limit hint copy, branched on whether the active\n * credential is a Claude Code OAuth subscription.\n */\nfunction oauthQuotaHint(oauthCredential?: boolean): string {\n if (oauthCredential) {\n return \"Quota exhausted on this Claude Code subscription. Wait for the rate-limit window to reset (typically a few minutes for short windows, longer for daily/weekly limits) before retrying. The credential itself is fine.\";\n }\n return \"The Anthropic account hit a rate limit. Wait a moment and try again.\";\n}\n\n/**\n * Try to extract a structured Anthropic error body from a free-text wrapper.\n * The bundled `claude-cli.js` typically formats failures as\n * `... API Error: <status> {\"type\":\"error\",\"error\":{\"type\":\"<errorType>\",...}}`\n * with optional trailing garbage after the JSON.\n *\n * Strategy: find the first `{`, then forward-scan tracking brace depth (with\n * string-literal awareness so braces inside quoted values do not throw the\n * count). The substring from `braceStart` to the matching `}` is the JSON\n * candidate; one `JSON.parse` does the rest. O(n) in the input length.\n *\n * Returns `null` when nothing parseable is found.\n */\nfunction tryParseEmbeddedAnthropicError(\n text: string,\n): { errorType: string; statusCode?: number } | null {\n const braceStart = text.indexOf(\"{\");\n if (braceStart < 0) {\n return null;\n }\n\n // Forward scan with brace counting to find the matching close brace.\n // String-literal awareness: skip braces between unescaped double quotes.\n let depth = 0;\n let inString = false;\n let escaped = false;\n let braceEnd = -1;\n for (let i = braceStart; i < text.length; i++) {\n const ch = text.charCodeAt(i);\n if (inString) {\n if (escaped) {\n escaped = false;\n } else if (ch === 92 /* \\ */) {\n escaped = true;\n } else if (ch === 34 /* \" */) {\n inString = false;\n }\n continue;\n }\n if (ch === 34 /* \" */) {\n inString = true;\n } else if (ch === 123 /* { */) {\n depth++;\n } else if (ch === 125 /* } */) {\n depth--;\n if (depth === 0) {\n braceEnd = i + 1;\n break;\n }\n }\n }\n if (braceEnd < 0) {\n return null;\n }\n\n let parsed: { type?: string; error?: { type?: string; message?: string } };\n try {\n parsed = JSON.parse(text.slice(braceStart, braceEnd));\n } catch {\n return null;\n }\n const errorType = parsed?.error?.type;\n if (typeof errorType !== \"string\") {\n return null;\n }\n const statusMatch = text.match(/API Error:\\s*(\\d{3})/i);\n const statusCode = statusMatch ? Number(statusMatch[1]) : undefined;\n return { errorType, statusCode };\n}\n"]}
@@ -487,7 +487,7 @@ function parseMentions(text, resolver) {
487
487
  }
488
488
  }
489
489
  }
490
- return mentions.sort((a, b) => a.offset - b.offset);
490
+ return mentions;
491
491
  }
492
492
  function isMentioned(userId, mentions) {
493
493
  for (const m of mentions) {
@@ -502,5 +502,5 @@ function isAgentAddressed(mentions) {
502
502
  }
503
503
 
504
504
  export { SessionDispatcher, isAgentAddressed, isMentioned, parseMentions };
505
- //# sourceMappingURL=chunk-D3VO6WNC.js.map
506
- //# sourceMappingURL=chunk-D3VO6WNC.js.map
505
+ //# sourceMappingURL=chunk-PRLD7EXG.js.map
506
+ //# sourceMappingURL=chunk-PRLD7EXG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../session/src/dispatcher.ts","../session/src/mentions.ts"],"names":[],"mappings":";;;AAsDA,IAAM,eAAA,uBAAsB,GAAA,CAAI;AAAA,EAC9B,kBAAA;AAAA,EACA,mBAAA;AAAA,EACA,qBAAA;AAAA,EACA,oBAAA;AAAA,EACA,eAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA;AAAA,EAEA,cAAA;AAAA;AAAA,EAEA,WAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAiCM,IAAM,oBAAN,MAAwB;AAAA;AAAA,EAEpB,SAAA;AAAA,EACD,MAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA,uBAA+B,GAAA,EAAI;AAAA,EACnC,cAAA,uBAAkD,GAAA,EAAI;AAAA,EACtD,GAAA,GAAc,CAAA;AAAA,EACd,mBAAA,GAAoE;AAAA,IAC1E,QAAQ,EAAC;AAAA,IACT,YAAY;AAAC,GACf;AAAA;AAAA,EAGiB,yBAAA;AAAA;AAAA,EAEA,YAAA;AAAA;AAAA,EAET,gBAAA;AAAA;AAAA,EAMA,WAAA,GAAc,KAAA;AAAA;AAAA,EAEd,eAAA,GAAkB,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlB,sBAAqD,EAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOtD,SAAA,GAAY,EAAA;AAAA;AAAA;AAAA;AAAA,EAKpB,YAAY,IAAA,EAAgC;AAC1C,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,yBAAA,GAA4B,KAAK,yBAAA,IAA6B,KAAA;AACnE,IAAA,IAAA,CAAK,YAAA,GAAe,KAAK,YAAA,IAAgB,EAAA;AACzC,IAAA,IAAA,CAAK,mBAAmB,IAAA,CAAK,eAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,gBAAgB,EAAA,EAEJ;AACd,IAAA,IAAA,CAAK,gBAAA,GAAmB,EAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,IAAA,GAAsB;AAC1B,IAAA,IAAA,CAAK,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,KAAK,SAAS,CAAA;AACvD,IAAA,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,CAAC,KAAA,KAAsB;AACzC,MAAA,KAAK,IAAA,CAAK,iBAAiB,KAAK,CAAA;AAAA,IAClC,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,SAAA,CACJ,YAAA,EACA,IAAA,EACoB;AACpB,IAAA,IAAA,CAAK,WAAA,CAAY,IAAI,YAAY,CAAA;AACjC,IAAA,IAAI,IAAA,EAAM,MAAA,KAAW,MAAA,IAAa,IAAA,EAAM,UAAU,MAAA,EAAW;AAC3D,MAAA,IAAA,CAAK,cAAA,CAAe,IAAI,YAAA,EAAc;AAAA,QACpC,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,OAAO,IAAA,CAAK;AAAA,OACb,CAAA;AAAA,IACH;AACA,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,IAAA,CAAK,SAAA,EAAW;AAAA,MAC5C,KAAA,EAAO,MAAM,KAAA,IAAS;AAAA,KACvB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,YAAA,EAA4B;AACtC,IAAA,IAAA,CAAK,WAAA,CAAY,OAAO,YAAY,CAAA;AACpC,IAAA,IAAA,CAAK,cAAA,CAAe,OAAO,YAAY,CAAA;AACvC,IAAA,IAAA,CAAK,SAAA,CAAU,OAAO,YAAY,CAAA;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6BA,MAAM,WAAA,CACJ,OAAA,EACA,QAAA,EACA,QAAA,EACA,YACA,cAAA,EACyB;AACzB,IAAA,IAAI,CAAC,IAAA,CAAK,aAAA,CAAc,OAAO,CAAA,EAAG;AAChC,MAAA,IAAA,CAAK,MAAA,CAAO,KAAK,OAAO,CAAA;AACxB,MAAA,OAAO,IAAA;AAAA,IACT;AAIA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,aAAA,CAAc,OAAA,EAAS,QAAQ,CAAA;AAEpD,IAAA,IAAI,QAAA,EAAU,MAAA,EAAQ,OAAA,CAAQ,QAAA,GAAW,QAAA;AAMzC,IAAA,IAAI,UAAA,UAAoB,UAAA,GAAa,UAAA;AACrC,IAAA,MAAM,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,OAAO,CAAA;AAI/B,IAAA,IAAI,QAAA,GAAyB,OAAA;AAC7B,IAAA,IAAI,OAAA,CAAQ,SAAS,QAAA,EAAU;AAC7B,MAAA,IAAI,SAAS,OAAA,CAAQ,MAAA;AAIrB,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,MAAA,GAAS,CAAA,EAAG,cAAc,CAAA,EAAG,MAAM,CAAA,CAAA;AAAA,MACrC;AACA,MAAA,IAAI,KAAK,yBAAA,EAA2B;AAClC,QAAA,MAAA,GAAS,MAAM,IAAA,CAAK,uBAAA,CAAwB,MAAM,CAAA;AAAA,MACpD;AACA,MAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,QAAA,MAAA,GAAS,IAAA,CAAK,gBAAA,CAAiB,MAAA,EAAQ,QAAA,EAAU,QAAQ,OAAO,CAAA;AAAA,MAClE;AACA,MAAA,IAAI,MAAA,KAAW,QAAQ,MAAA,EAAQ;AAC7B,QAAA,QAAA,GAAW,EAAE,GAAG,OAAA,EAAS,MAAA,EAAO;AAAA,MAClC;AAAA,IACF,CAAA,MAAA,IAAW,cAAA,IAAkB,OAAA,CAAQ,IAAA,KAAS,OAAA,EAAS;AAIrD,MAAA,QAAA,GAAW,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,GAAG,cAAc,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAA,CAAA,EAAG;AAAA,IACxE,CAAA,MAAA,IAAW,cAAA,IAAkB,OAAA,CAAQ,IAAA,KAAS,gBAAA,EAAkB;AAG9D,MAAA,QAAA,GAAW,EAAE,GAAG,OAAA,EAAS,OAAA,EAAS,GAAG,cAAc,CAAA,EAAG,OAAA,CAAQ,OAAO,CAAA,CAAA,EAAG;AAAA,IAC1E;AAYA,IAAA,IAAI,UAAA,EAAY,mBAAmB,YAAA,EAAc;AAC/C,MAAA,OAAO,OAAA;AAAA,IACT;AASA,IAAA,IACE,UAAA,EAAY,mBAAmB,SAAA,IAC/B,CAAC,WAAW,mBAAA,EAAqB,QAAA,CAAS,WAAW,CAAA,EACrD;AACA,MAAA,OAAO,OAAA;AAAA,IACT;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,QAAQ,CAAA;AACzB,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,YAAA,CAAa,KAAA,EAAmB,QAAA,EAA+C;AACnF,IAAA,OAAO,IAAA,CAAK,gBAAA,CAAiB,KAAA,EAAO,QAAQ,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YAAY,IAAA,EAAgE;AAChF,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,IAAA,CAAK,WAAW,IAAI,CAAA;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,kBAAA,GAAmE;AACrE,IAAA,OAAO,IAAA,CAAK,mBAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,cAAc,SAAA,EAA+D;AAC3E,IAAA,MAAM,KAAA,GACJ,KAAK,mBAAA,CAAoB,MAAA,CAAO,WAAW,CAAA,IAC3C,IAAA,CAAK,mBAAA,CAAoB,UAAA,CAAW,MAAA,KAAW,CAAA;AACjD,IAAA,IAAI,KAAA,KAAU,UAAU,MAAA,CAAO,MAAA,GAAS,KAAK,SAAA,CAAU,UAAA,CAAW,SAAS,CAAA,CAAA,EAAI;AAC7E,MAAA,IAAA,CAAK,mBAAA,GAAsB,SAAA;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,cAAc,MAAA,EAAsB;AAClC,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,EAAU,QAAQ,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,eAAA,CACJ,OAAA,EACA,SAAA,GAAY,GAAA,EACqB;AACjC,IAAA,OAAO,IAAI,OAAA,CAAgC,CAAC,OAAA,EAAS,MAAA,KAAW;AAC9D,MAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,QAAA,IAAA,CAAK,MAAA,CAAO,SAAS,OAAO,CAAA;AAC5B,QAAA,MAAA;AAAA,UACE,IAAI,KAAA;AAAA,YACF,oCAAoC,SAAS,CAAA,IAAA,EAAO,QAAQ,SAAS,CAAA,CAAA,EAAI,QAAQ,WAAW,CAAA;AAAA;AAC9F,SACF;AAAA,MACF,GAAG,SAAS,CAAA;AAEZ,MAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAAsB;AACrC,QAAA,IAAI,MAAM,IAAA,KAAS,mBAAA,IAAuB,KAAA,CAAM,SAAA,KAAc,QAAQ,SAAA,EAAW;AAC/E,UAAA,YAAA,CAAa,KAAK,CAAA;AAClB,UAAA,IAAA,CAAK,MAAA,CAAO,SAAS,OAAO,CAAA;AAC5B,UAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,QACf;AAAA,MACF,CAAA;AAEA,MAAA,IAAA,CAAK,MAAA,CAAO,QAAQ,OAAO,CAAA;AAC3B,MAAA,IAAA,CAAK,MAAA,CAAO,KAAK,OAAO,CAAA;AAAA,IAC1B,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAU,KAAA,EAAyB;AACjC,IAAA,KAAA,MAAW,YAAA,IAAgB,KAAK,WAAA,EAAa;AAC3C,MAAA,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,YAAA,EAAc,KAAK,CAAA;AAAA,IACzC;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,UAAA,GAA4B;AAChC,IAAA,KAAA,MAAW,EAAA,IAAM,KAAK,WAAA,EAAa;AACjC,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,EAAE,CAAA;AAAA,IAC1B;AACA,IAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AACvB,IAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAG1B,IAAA,IAAA,CAAK,sBAAsB,EAAC;AAC5B,IAAA,MAAM,IAAA,CAAK,OAAO,OAAA,EAAQ;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAA,GAAwB;AACtB,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,IAAA,IAAA,CAAK,eAAA,GAAkB,EAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAA,GAAwB;AACtB,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,IAAA,MAAM,OAAO,IAAA,CAAK,eAAA;AAClB,IAAA,IAAA,CAAK,eAAA,GAAkB,EAAA;AACvB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,YAAA,GAAwB;AAC1B,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,iBAAiB,EAAA,EAAwC;AACvD,IAAA,IAAA,CAAK,mBAAA,CAAoB,KAAK,EAAE,CAAA;AAChC,IAAA,OAAO,MAAM;AACX,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,mBAAA,CAAoB,OAAA,CAAQ,EAAE,CAAA;AAC/C,MAAA,IAAI,QAAQ,EAAA,EAAI;AACd,QAAA,IAAA,CAAK,mBAAA,CAAoB,MAAA,CAAO,GAAA,EAAK,CAAC,CAAA;AAAA,MACxC;AAAA,IACF,CAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAc,wBAAwB,aAAA,EAAwC;AAC5E,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,KAAK,SAAA,EAAW;AAAA,MAC5D,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AAGD,IAAA,MAAM,OAAA,GAAU,QAAA,CACb,MAAA,CAAO,CAAC,CAAA,KAAM;AACb,MAAA,MAAM,IAAA,GAAO,EAAE,OAAA,CAAQ,IAAA;AACvB,MAAA,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,UAAA,IAAc,IAAA,KAAS,UAAA;AAAA,IAC9D,CAAC,CAAA,CACA,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAEd,IAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,MAAA,OAAO,aAAA;AAAA,IACT;AAEA,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM;AAC/B,MAAA,MAAM,IAAI,CAAA,CAAE,OAAA;AACZ,MAAA,IAAI,CAAA,CAAE,SAAS,QAAA,EAAU;AACvB,QAAA,OAAO,CAAA,QAAA,EAAW,MAAA,CAAO,CAAA,CAAE,MAAA,IAAU,EAAE,CAAC,CAAA,CAAA;AAAA,MAC1C;AAEA,MAAA,MAAM,UAAU,MAAA,CAAO,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,YAAY,EAAE,CAAA;AACpD,MAAA,OAAO,gBAAgB,OAAO,CAAA,CAAA;AAAA,IAChC,CAAC,CAAA;AAED,IAAA,OAAO,CAAA;AAAA,EAA2B,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC;AAAA;;AAAA,EAAgC,aAAa,CAAA,CAAA;AAAA,EACjG;AAAA,EAEA,MAAc,gBAAA,CAAiB,KAAA,EAAmB,QAAA,EAA+C;AAE/F,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AACzB,QAAA,IAAA,CAAK,mBAAoB,KAAA,CAA8B,OAAA;AAAA,MACzD;AAEA,MAAA,KAAA,MAAW,YAAA,IAAgB,KAAK,WAAA,EAAa;AAC3C,QAAA,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,YAAA,EAAc,KAAK,CAAA;AAAA,MACzC;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,IAAI,KAAA,CAAM,SAAS,qBAAA,EAAuB;AACxC,MAAA,MAAM,OAAA,GAAU,KAAA;AAChB,MAAA,IAAA,CAAK,mBAAA,GAAsB;AAAA,QACzB,MAAA,EAAQ,OAAA,CAAQ,MAAA,IAAU,EAAC;AAAA,QAC3B,UAAA,EAAY,OAAA,CAAQ,UAAA,IAAc;AAAC,OACrC;AAAA,IACF;AAMA,IAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AACzB,MAAA,IAAA,CAAK,aAAc,KAAA,CAA8B,OAAA;AAAA,IACnD,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,UAAA,EAAY;AACpC,MAAA,MAAM,OAAA,GAAW,MAA+B,OAAA,IAAW,EAAA;AAC3D,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAA,GAAS,CAAA,GAAI,UAAU,IAAA,CAAK,SAAA;AACnD,MAAA,IAAA,CAAK,SAAA,GAAY,EAAA;AACjB,MAAA,IAAI,IAAA,CAAK,mBAAA,CAAoB,MAAA,GAAS,CAAA,EAAG;AACvC,QAAA,MAAM,UAAU,IAAA,CAAK,mBAAA;AACrB,QAAA,IAAA,CAAK,sBAAsB,EAAC;AAC5B,QAAA,KAAA,MAAW,MAAM,OAAA,EAAS;AACxB,UAAA,EAAA,CAAG,MAAM,CAAA;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,OAAA,GAA0B,IAAA;AAC9B,IAAA,IAAI,IAAA,CAAK,aAAA,CAAc,KAAK,CAAA,EAAG;AAC7B,MAAA,OAAA,GAAU,IAAA,CAAK,cAAc,KAAK,CAAA;AAClC,MAAA,IAAI,QAAA,EAAU,MAAA,EAAQ,OAAA,CAAQ,QAAA,GAAW,QAAA;AACzC,MAAA,MAAM,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,OAAO,CAAA;AAAA,IACjC;AAEA,IAAA,KAAA,MAAW,YAAA,IAAgB,KAAK,WAAA,EAAa;AAC3C,MAAA,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,YAAA,EAAc,KAAK,CAAA;AAAA,IACzC;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEQ,cAAc,OAAA,EAA6C;AACjE,IAAA,OAAO,CAAC,eAAA,CAAgB,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA;AAAA,EAC1C;AAAA,EAEQ,aAAA,CAAc,SAAoC,QAAA,EAA4B;AACpF,IAAA,IAAA,CAAK,GAAA,EAAA;AACL,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,OAAO,UAAA,EAAW;AAAA,MACtB,KAAK,IAAA,CAAK,GAAA;AAAA,MACV,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAClC,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,GAAI,QAAA,GAAW,EAAE,QAAA,KAAa,EAAC;AAAA,MAC/B;AAAA,KACF;AAAA,EACF;AACF;;;ACjlBA,IAAM,UAAA,GAAa,SAAA;AACnB,IAAM,iBAAA,GAAyC,IAAI,GAAA,CAAI,cAAc,CAAA;AAgB9D,SAAS,aAAA,CAAc,MAAc,QAAA,EAAsC;AAChF,EAAA,MAAM,WAAsB,EAAC;AAE7B,EAAA,KAAA,MAAW,KAAA,IAAS,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,EAAG;AAC7C,IAAA,MAAM,KAAA,GAAQ,MAAM,CAAC,CAAA;AACrB,IAAA,MAAM,SAAS,KAAA,CAAM,KAAA;AACrB,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,CAAC,CAAA,CAAE,MAAA;AAExB,IAAA,IAAI,iBAAA,CAAkB,GAAA,CAAI,KAAK,CAAA,EAAG;AAChC,MAAA,MAAM,KAAA,GAAQ,KAAA;AACd,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,IAAA,EAAM,OAAA;AAAA,QACN,KAAA;AAAA,QACA,QAAA,EAAU,QAAA,CAAS,YAAA,CAAa,KAAK,CAAA;AAAA,QACrC,MAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,WAAA,CAAY,KAAK,CAAA;AACvC,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,IAAA,EAAM,MAAA;AAAA,UACN,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,MAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,EAAA,OAAO,QAAA;AACT;AAcO,SAAS,WAAA,CAAY,QAAgB,QAAA,EAA8B;AACxE,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,IAAI,EAAE,IAAA,KAAS,MAAA,IAAU,CAAA,CAAE,MAAA,KAAW,QAAQ,OAAO,IAAA;AACrD,IAAA,IAAI,CAAA,CAAE,SAAS,OAAA,IAAW,CAAA,CAAE,SAAS,QAAA,CAAS,MAAM,GAAG,OAAO,IAAA;AAAA,EAChE;AACA,EAAA,OAAO,KAAA;AACT;AAOA,IAAM,+BAA0C,IAAI,GAAA,CAAI,CAAC,OAAA,EAAS,MAAA,EAAQ,KAAK,CAAC,CAAA;AAYzE,SAAS,iBAAiB,QAAA,EAA8B;AAC7D,EAAA,OAAO,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,OAAA,IAAW,YAAA,CAAa,GAAA,CAAI,CAAA,CAAE,KAAK,CAAC,CAAA;AAC7E","file":"chunk-PRLD7EXG.js","sourcesContent":["import type { AgentClient } from \"@skaile/workspaces/client\";\nimport type {\n AgentCommand,\n AgentEvent,\n ConnectorRequestCommand,\n ConnectorResponseEvent,\n Mention,\n ReplyRef,\n} from \"@skaile/workspaces/types\";\nimport type { Message, MessageStore, SubscriberInfo, SubscriberTransport } from \"./types.js\";\n\n/**\n * Construction options for {@link SessionDispatcher}.\n *\n * All three infrastructure objects (`client`, `store`, `transport`) are\n * injected by the caller so the dispatcher remains testable and framework-agnostic.\n *\n * @docLink packages/session/api-reference#session-dispatcher\n */\nexport interface SessionDispatcherOptions {\n /** Unique identifier for the session this dispatcher manages. */\n sessionId: string;\n /** Connected agent client used to send commands and receive events. */\n client: AgentClient;\n /** Persistence layer for all non-transient messages. */\n store: MessageStore;\n /** Fan-out transport for broadcasting events to connected frontends. */\n transport: SubscriberTransport;\n /**\n * When true, the dispatcher prepends conversation history to every prompt\n * command sent to the agent. Enable for agents without native session\n * continuity (e.g. mock mode). Agents with native multi-turn support\n * (Claude SDK, OMP) should set this to false to avoid duplicate context.\n * Default: false.\n */\n injectConversationHistory?: boolean;\n /** Max conversation history messages to include in enriched prompts (default: 50). */\n historyLimit?: number;\n /**\n * Optional callback to transform prompt text before forwarding to the agent.\n * The original (untransformed) prompt is persisted and broadcast to subscribers.\n * Applied after conversation history enrichment. Use this to inject context\n * (e.g. UI state) that the agent should see but subscribers should not.\n */\n transformPrompt?: (prompt: string, senderId: string | undefined, replyTo?: ReplyRef) => string;\n}\n\n/**\n * Command and event types classified as transient RPC — high-frequency,\n * ephemeral, and not part of the conversation history.\n *\n * Matching payloads are forwarded and broadcast but never persisted\n * or assigned a sequence number, preventing bloat in the message log.\n */\nconst TRANSIENT_TYPES = new Set([\n \"resource_request\",\n \"resource_response\",\n \"resources_available\",\n \"commands_available\",\n \"state_changed\",\n \"typing\",\n \"user_message\",\n // OMP session tracking — forwarded to subscribers but not persisted\n \"session_info\",\n // Structured log forwarding — high-volume; persisted in per-session SQLite, not the message store\n \"log_entry\",\n // Generic connector dispatch — system RPC, not chat messages.\n // Replaces the 6 typed flow commands removed in Protocol 2.2 (Phase 4 of the\n // flow-connector extraction). `connector_mutate` against the `flow` connector\n // is now how hosts drive flow execution between turns.\n \"connector_mutate\",\n \"connector_query\",\n \"connector_query_response\",\n]);\n\n/**\n * Bridges a single agent session between an {@link AgentClient} and one or more\n * frontend subscribers.\n *\n * Responsibilities:\n * - Persists every non-transient command and event as a {@link Message} with a\n * monotonic sequence number via the injected {@link MessageStore}.\n * - Fans agent events out to all connected frontends via the injected\n * {@link SubscriberTransport}.\n * - Optionally enriches prompt commands with conversation history so agents\n * without native multi-turn support maintain context across turns.\n *\n * **Lifecycle:** call {@link init} before any other method, and {@link disconnect}\n * when the session ends.\n *\n * @example\n * ```ts\n * const dispatcher = new SessionDispatcher({\n * sessionId: 'sess-123',\n * client: agentClient,\n * store: prismaMessageStore,\n * transport: trpcTransport,\n * })\n * await dispatcher.init()\n * const history = await dispatcher.subscribe('ws-conn-abc', { limit: 50 })\n * const msg = await dispatcher.sendCommand({ type: 'prompt', prompt: 'Hello' }, 'user-42')\n * await dispatcher.disconnect()\n * ```\n *\n * @docLink packages/session/api-reference#session-dispatcher\n */\nexport class SessionDispatcher {\n /** The session identifier this dispatcher is bound to. */\n readonly sessionId: string;\n private client: AgentClient;\n private store: MessageStore;\n private transport: SubscriberTransport;\n private subscribers: Set<string> = new Set();\n private subscriberMeta: Map<string, SubscriberInfo> = new Map();\n private seq: number = 0;\n private _availableResources: { mounts: unknown[]; connectors: unknown[] } = {\n mounts: [],\n connectors: [],\n };\n\n /** Whether to inject conversation history into prompt commands. */\n private readonly injectConversationHistory: boolean;\n /** Maximum number of history messages to include in enriched prompts. */\n private readonly historyLimit: number;\n /** Optional prompt transformer applied before forwarding (after persistence). */\n private _transformPrompt?: (\n prompt: string,\n senderId: string | undefined,\n replyTo?: ReplyRef,\n ) => string;\n /** Whether the dispatcher is currently in compaction mode. */\n private _compacting = false;\n /** Accumulated text content during compaction. */\n private _compactionText = \"\";\n\n /**\n * One-shot waiters registered via {@link onceNextFinished}. Each is invoked\n * exactly once with the text of the next `finished` assistant event, then\n * the list is cleared. Backs the A2A router's synchronous `ask` answer\n * capture.\n */\n private nextFinishedWaiters: Array<(text: string) => void> = [];\n /**\n * Text streamed by the agent since the last `finished` event. Used as the\n * fallback answer text for {@link onceNextFinished} when a `finished` event\n * carries an empty `summary` (drivers that stream `text` chunks and leave\n * the summary blank).\n */\n private _turnText = \"\";\n\n /**\n * @param opts - Dispatcher configuration — see {@link SessionDispatcherOptions}.\n */\n constructor(opts: SessionDispatcherOptions) {\n this.sessionId = opts.sessionId;\n this.client = opts.client;\n this.store = opts.store;\n this.transport = opts.transport;\n this.injectConversationHistory = opts.injectConversationHistory ?? false;\n this.historyLimit = opts.historyLimit ?? 50;\n this._transformPrompt = opts.transformPrompt;\n }\n\n /**\n * Replace the prompt transformer at runtime.\n *\n * Useful when additional context (e.g. a UI state cache) becomes available\n * after the dispatcher is constructed but before the first prompt is sent.\n */\n set transformPrompt(fn:\n | ((prompt: string, senderId: string | undefined, replyTo?: ReplyRef) => string)\n | undefined,) {\n this._transformPrompt = fn;\n }\n\n /**\n * Initialize the dispatcher for this session.\n *\n * Restores the monotonic sequence counter from the store and wires up the\n * agent event listener. Must be called once before any other method.\n *\n * @throws If {@link MessageStore.getLatestSeq} rejects.\n */\n async init(): Promise<void> {\n this.seq = await this.store.getLatestSeq(this.sessionId);\n this.client.onEvent((event: AgentEvent) => {\n void this.handleAgentEvent(event);\n });\n }\n\n /**\n * Register a frontend subscriber and return recent message history.\n *\n * Subsequent agent events are pushed to this subscriber via the\n * {@link SubscriberTransport} until {@link unsubscribe} is called.\n *\n * @param subscriberId - Opaque connection ID (e.g. WebSocket session ID).\n * @param opts - Optional subscription options.\n * @param opts.limit - Number of recent messages to return (default: 50).\n * @returns Recent messages ordered by seq ascending.\n */\n async subscribe(\n subscriberId: string,\n opts?: { limit?: number; userId?: string; roles?: string[] },\n ): Promise<Message[]> {\n this.subscribers.add(subscriberId);\n if (opts?.userId !== undefined || opts?.roles !== undefined) {\n this.subscriberMeta.set(subscriberId, {\n userId: opts.userId,\n roles: opts.roles,\n });\n }\n return this.store.getMessages(this.sessionId, {\n limit: opts?.limit ?? 50,\n });\n }\n\n /**\n * Remove a frontend subscriber and release transport resources.\n *\n * @param subscriberId - The ID passed to {@link subscribe}.\n */\n unsubscribe(subscriberId: string): void {\n this.subscribers.delete(subscriberId);\n this.subscriberMeta.delete(subscriberId);\n this.transport.remove(subscriberId);\n }\n\n /**\n * Send a command from a frontend to the agent.\n *\n * Persistent commands are wrapped in a Message envelope and stored before\n * forwarding. Transient commands (resource RPC) are forwarded directly\n * without persistence — returns null in that case.\n *\n * For `prompt` commands, the original message is persisted, but an enriched\n * version (with conversation history prepended) is sent to the agent so it\n * maintains context across turns.\n *\n * @param command - The command to dispatch to the agent (a prompt or tool result).\n * @param senderId - ID of the user sending the command, if known.\n * @param mentions - Resolved mention objects extracted from the prompt text.\n * @param visibility - Optional platform visibility envelope (F-23). When\n * `visibilityMode` is `HumansOnly`, or `Private` without the `\"__agent__\"`\n * sentinel in `privateRecipientIds` (B-30), the message is persisted and\n * broadcast to subscribers but NOT forwarded to the agent.\n * @param outgoingPrefix - Optional text prepended to the outgoing command's\n * user-text field ({@link command.prompt} / `command.answer` /\n * `command.content`) AFTER persistence but BEFORE history enrichment and\n * {@link transformPrompt}. The persisted {@link Message} envelope is built\n * from the original `command` and never sees the prefix. Use this to\n * inject one-shot wake-time context (Option B1 pending restoration\n * prompt) that the agent must see but UI subscribers must not.\n * @returns The persisted Message envelope, or null for transient command types.\n */\n async sendCommand(\n command: AgentCommand,\n senderId?: string,\n mentions?: Mention[],\n visibility?: NonNullable<Message[\"visibility\"]>,\n outgoingPrefix?: string,\n ): Promise<Message | null> {\n if (!this.shouldPersist(command)) {\n this.client.send(command);\n return null;\n }\n // Persist the original command (unenriched/untransformed/un-prefixed).\n // `outgoingPrefix` is intentionally NOT applied here — it must only\n // reach the agent client, never the MessageStore.\n const message = this.createMessage(command, senderId);\n // @TODO: Code-Review: v1 back-compat — mentions field no longer used by Protocol v2+ persistence layers; remove once platform PrismaMessageStore is migrated\n if (mentions?.length) message.mentions = mentions;\n // F-23: platform-extension visibility metadata (3.2.0). The platform\n // MessageStore reads this off the envelope and writes the\n // Message.visibilityMode column + recipient rows atomically with\n // the message itself — no post-send patch, no race window where a\n // concurrent send could mis-tag the wrong message id.\n if (visibility) message.visibility = visibility;\n await this.store.append(message);\n\n // Build the outgoing command — enrich and transform prompt commands\n // while leaving the persisted message untouched.\n let outgoing: AgentCommand = command;\n if (command.type === \"prompt\") {\n let prompt = command.prompt;\n // Restoration prefix lands FIRST (innermost) so the user's typed\n // text remains adjacent to its own framing, with history and reply\n // preambles wrapping the combined block from the outside in.\n if (outgoingPrefix) {\n prompt = `${outgoingPrefix}${prompt}`;\n }\n if (this.injectConversationHistory) {\n prompt = await this.enrichPromptWithHistory(prompt);\n }\n if (this._transformPrompt) {\n prompt = this._transformPrompt(prompt, senderId, command.replyTo);\n }\n if (prompt !== command.prompt) {\n outgoing = { ...command, prompt };\n }\n } else if (outgoingPrefix && command.type === \"reply\") {\n // `reply` carries user text in `answer`. Prefix is invisible to\n // subscribers (who see the persisted Message.payload.answer) but\n // visible to the agent driver.\n outgoing = { ...command, answer: `${outgoingPrefix}${command.answer}` };\n } else if (outgoingPrefix && command.type === \"custom_message\") {\n // `custom_message` carries user text in `content`. Same persist/send\n // split as the `reply` branch above.\n outgoing = { ...command, content: `${outgoingPrefix}${command.content}` };\n }\n\n // F-23 P3 review (B1) — HumansOnly visibility means the message is\n // intended for human recipients only; the agent must NOT see the\n // prompt content. Persist + broadcast (humans read it via\n // SubscriberTransport) but skip the agent forward. This closes a\n // critical privacy hole where `@user: secret` was persisted with\n // visibilityMode='HumansOnly' yet still reached the LLM. Threads\n // starting HumansOnly stay agent-invisible even on Public follow-ups\n // (parent-thread visibility threading is intentionally out of scope\n // for v1; only the immediate message is gated). See\n // platform/_concept/plans/f-23-p3-review-blockers.md.\n if (visibility?.visibilityMode === \"HumansOnly\") {\n return message;\n }\n\n // B-30 — Private visibility (F-23 `@mention_` underscore suffix) means the\n // message is addressed to an explicit recipient set. The agent is only a\n // recipient when the sender wrote `@agent_`, which the platform encodes as\n // the `\"__agent__\"` sentinel in `privateRecipientIds`. When the sentinel is\n // absent the message is a private human-to-human exchange: persist +\n // broadcast (the named human recipients read it via SubscriberTransport)\n // but skip the agent forward so the LLM never sees private content.\n if (\n visibility?.visibilityMode === \"Private\" &&\n !visibility.privateRecipientIds?.includes(\"__agent__\")\n ) {\n return message;\n }\n\n this.client.send(outgoing);\n return message;\n }\n\n /**\n * Persist a synthetic event (not received from the agent) and broadcast it.\n *\n * Used by the platform to inject events like a partial-text `finished` record\n * before a cancel command.\n *\n * @param event - The agent event to persist.\n * @param mentions - Resolved mentions from the originating command.\n */\n async persistEvent(event: AgentEvent, mentions?: Mention[]): Promise<Message | null> {\n return this.handleAgentEvent(event, mentions);\n }\n\n /**\n * Load paginated message history for this session.\n *\n * @param opts.before - Return messages with seq strictly less than this value.\n * @param opts.limit - Maximum number of messages to return.\n */\n async getMessages(opts?: { before?: number; limit?: number }): Promise<Message[]> {\n return this.store.getMessages(this.sessionId, opts);\n }\n\n /**\n * Available mounts and connectors captured from the most recent\n * `resources_available` event emitted by the agent on connect.\n *\n * Empty until the agent emits the event or {@link seedResources} is called.\n */\n get availableResources(): { mounts: unknown[]; connectors: unknown[] } {\n return this._availableResources;\n }\n\n /**\n * Seed the available resources from an external cache.\n *\n * This is needed when the dispatcher is created after the agent has already\n * emitted `resources_available` on WebSocket connect. Without seeding, the\n * dispatcher would report an empty resource list until the next reconnect.\n *\n * @param resources - Resource handles to register before the session starts.\n */\n seedResources(resources: { mounts: unknown[]; connectors: unknown[] }): void {\n const empty =\n this._availableResources.mounts.length === 0 &&\n this._availableResources.connectors.length === 0;\n if (empty && (resources.mounts.length > 0 || resources.connectors.length > 0)) {\n this._availableResources = resources;\n }\n }\n\n /**\n * Deliver a prompt to the agent that triggers a turn but is NOT persisted.\n *\n * Unlike {@link sendCommand}, this never touches the {@link MessageStore}:\n * the prompt is forwarded straight to the agent client. The caller owns\n * persistence of whatever conversation rows should represent this turn.\n *\n * Used by the platform's A2A router to deliver a `from-peer` prompt to a\n * target session: the router writes the authoritative A2A `Message` rows\n * itself, so persisting the framed prompt here too would create an extra,\n * un-attributed plain `prompt` row. The dispatcher's job for this prompt is\n * delivery only.\n *\n * The agent still produces a normal turn, so an A2A `ask` round-trip can\n * capture the answer via {@link onceNextFinished}.\n *\n * @param prompt - The fully-formed prompt text to deliver to the agent.\n */\n deliverPrompt(prompt: string): void {\n this.client.send({ type: \"prompt\", prompt });\n }\n\n /**\n * Send a resource request and await the correlated response.\n *\n * This is a convenience method for request/response resource RPC.\n * The request is transient (not persisted). A one-shot event listener\n * waits for the matching `resource_response` by `requestId`.\n *\n * @param command - A ConnectorRequestCommand (caller must set requestId).\n * @param timeoutMs - How long to wait before rejecting (default: 30s).\n */\n async requestResource(\n command: ConnectorRequestCommand,\n timeoutMs = 30_000,\n ): Promise<ConnectorResponseEvent> {\n return new Promise<ConnectorResponseEvent>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.client.offEvent(handler);\n reject(\n new Error(\n `Resource request timed out after ${timeoutMs}ms: ${command.operation} ${command.connectorId}`,\n ),\n );\n }, timeoutMs);\n\n const handler = (event: AgentEvent) => {\n if (event.type === \"resource_response\" && event.requestId === command.requestId) {\n clearTimeout(timer);\n this.client.offEvent(handler);\n resolve(event);\n }\n };\n\n this.client.onEvent(handler);\n this.client.send(command);\n });\n }\n\n /**\n * Broadcast a transient event to all subscribers without persisting it.\n *\n * Used for ephemeral signals like typing indicators or user-command\n * echoes that other subscribers need to see in real time.\n */\n broadcast(event: AgentEvent): void {\n for (const subscriberId of this.subscribers) {\n this.transport.send(subscriberId, event);\n }\n }\n\n /** Disconnect the agent client and clean up all subscribers. */\n async disconnect(): Promise<void> {\n for (const id of this.subscribers) {\n this.transport.remove(id);\n }\n this.subscribers.clear();\n this.subscriberMeta.clear();\n // Clear any pending A2A waiters so they don't leak if the session\n // disconnects before the target ever emits a `finished` event.\n this.nextFinishedWaiters = [];\n await this.client.dispose();\n }\n\n /**\n * Enter compaction mode. While active, events from the agent are captured\n * but NOT persisted. Text content is accumulated for the snapshot.\n */\n beginCompaction(): void {\n this._compacting = true;\n this._compactionText = \"\";\n }\n\n /**\n * Exit compaction mode and return the accumulated text.\n * The caller is responsible for creating and emitting the snapshot event.\n */\n endCompaction(): string {\n this._compacting = false;\n const text = this._compactionText;\n this._compactionText = \"\";\n return text;\n }\n\n /** Whether the dispatcher is currently in compaction mode. */\n get isCompacting(): boolean {\n return this._compacting;\n }\n\n /**\n * Register a one-shot callback fired with the text of this session's next\n * finished assistant turn. Returns an unsubscribe function.\n *\n * Semantics:\n * - The callback fires **at most once** — on the first `finished` event\n * observed after registration. Later finished turns do not re-fire it.\n * - A waiter registered after a `finished` event waits for the *following*\n * one. The hook captures the *next* finished turn, not a past one.\n * - The answer text is the `finished` event's `summary`; when that is\n * empty (drivers that stream `text` and leave the summary blank), the\n * text accumulated since the previous finished turn is used instead.\n * - Calling the returned function removes the waiter; if it has already\n * fired this is a no-op.\n *\n * Used by the platform's A2A router (`A2ARouterService.ask`) to capture a\n * peer session's answer to a `from-peer` question. v1 captures the first\n * finished turn after delivery — see the busy-target notes in the A2A\n * design spec for the known turn-matching limitation.\n *\n * @param cb - Invoked once with the next finished turn's text.\n * @returns Unsubscribe function that removes this waiter.\n */\n onceNextFinished(cb: (text: string) => void): () => void {\n this.nextFinishedWaiters.push(cb);\n return () => {\n const idx = this.nextFinishedWaiters.indexOf(cb);\n if (idx !== -1) {\n this.nextFinishedWaiters.splice(idx, 1);\n }\n };\n }\n\n // -- Private ----------------------------------------------------------------\n\n /**\n * Build an enriched prompt by prepending conversation history.\n *\n * Loads recent persisted messages, formats user/assistant turns, and\n * wraps them in a `<conversation_history>` block. The current user\n * message (just persisted) is excluded since it is already the prompt.\n *\n * Returns the original prompt unchanged if there is no prior history.\n */\n private async enrichPromptWithHistory(currentPrompt: string): Promise<string> {\n const messages = await this.store.getMessages(this.sessionId, {\n limit: this.historyLimit,\n });\n\n // Filter to conversation-relevant types and exclude the message we just appended\n const history = messages\n .filter((m) => {\n const type = m.payload.type;\n return type === \"prompt\" || type === \"finished\" || type === \"question\";\n })\n .slice(0, -1); // Exclude the current message (last by seq)\n\n if (history.length === 0) {\n return currentPrompt;\n }\n\n const lines = history.map((m) => {\n const p = m.payload as Record<string, unknown>;\n if (p.type === \"prompt\") {\n return `[User]: ${String(p.prompt ?? \"\")}`;\n }\n // finished (assistant response) or question\n const content = String(p.summary ?? p.question ?? \"\");\n return `[Assistant]: ${content}`;\n });\n\n return `<conversation_history>\\n${lines.join(\"\\n\")}\\n</conversation_history>\\n\\n${currentPrompt}`;\n }\n\n private async handleAgentEvent(event: AgentEvent, mentions?: Mention[]): Promise<Message | null> {\n // ── Compaction mode: capture text but don't persist ─────────────────\n if (this._compacting) {\n if (event.type === \"text\") {\n this._compactionText += (event as { content: string }).content;\n }\n // Still broadcast to subscribers (UI shows compaction progress)\n for (const subscriberId of this.subscribers) {\n this.transport.send(subscriberId, event);\n }\n return null;\n }\n\n // Capture resource metadata when the server announces available resources\n if (event.type === \"resources_available\") {\n const payload = event as { mounts?: unknown[]; connectors?: unknown[] };\n this._availableResources = {\n mounts: payload.mounts ?? [],\n connectors: payload.connectors ?? [],\n };\n }\n\n // ── onceNextFinished — one-shot \"next finished turn\" answer capture ──\n // Accumulate streamed text across the turn so the answer is available\n // even when a driver emits an empty `finished.summary`. On `finished`,\n // drain every queued waiter exactly once, then reset the accumulator.\n if (event.type === \"text\") {\n this._turnText += (event as { content: string }).content;\n } else if (event.type === \"finished\") {\n const summary = (event as { summary?: string }).summary ?? \"\";\n const answer = summary.length > 0 ? summary : this._turnText;\n this._turnText = \"\";\n if (this.nextFinishedWaiters.length > 0) {\n const waiters = this.nextFinishedWaiters;\n this.nextFinishedWaiters = [];\n for (const cb of waiters) {\n cb(answer);\n }\n }\n }\n\n let message: Message | null = null;\n if (this.shouldPersist(event)) {\n message = this.createMessage(event);\n if (mentions?.length) message.mentions = mentions;\n await this.store.append(message);\n }\n\n for (const subscriberId of this.subscribers) {\n this.transport.send(subscriberId, event);\n }\n return message;\n }\n\n private shouldPersist(payload: AgentCommand | AgentEvent): boolean {\n return !TRANSIENT_TYPES.has(payload.type);\n }\n\n private createMessage(payload: AgentCommand | AgentEvent, senderId?: string): Message {\n this.seq++;\n return {\n id: crypto.randomUUID(),\n seq: this.seq,\n timestamp: new Date().toISOString(),\n sessionId: this.sessionId,\n ...(senderId ? { senderId } : {}),\n payload,\n };\n }\n}\n","import { MENTION_GROUPS } from \"@skaile/workspaces/types\";\nimport type { Mention, MentionGroup } from \"@skaile/workspaces/types\";\n\n/**\n * Re-exported from `@skaile/workspaces/types` so consumers can import mention\n * types directly from `@skaile/workspaces/session` without a separate dependency.\n */\nexport type { Mention, MentionGroup };\n\n// ---------------------------------------------------------------------------\n// MentionResolver\n// ---------------------------------------------------------------------------\n\n/**\n * Consumer-provided resolver that maps @mention tokens to users and groups.\n *\n * The platform provides an implementation backed by Prisma and the live\n * presence service. Tests use lightweight mocks.\n *\n * @example\n * ```ts\n * const resolver: MentionResolver = {\n * resolveUser: (name) => db.users.findByName(name),\n * resolveGroup: (group) => presence.getMemberIds(group),\n * getOnlineUserIds: () => presence.getOnlineIds(),\n * }\n * ```\n *\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport interface MentionResolver {\n /**\n * Resolve a `@name` token to a user record.\n *\n * @param name - The token after the `@` symbol (case-insensitive lookup).\n * @returns User record, or null if the name is not found.\n */\n resolveUser(name: string): { userId: string; name: string } | null;\n /**\n * Resolve a group mention token to the list of member user IDs.\n *\n * @param group - The well-known group name (e.g. `\"agent\"`, `\"all\"`).\n * @returns Array of member user IDs belonging to the group.\n */\n resolveGroup(group: MentionGroup): string[];\n /** Return the IDs of users currently online (used by the `here` and `humans_here` groups). */\n getOnlineUserIds(): string[];\n}\n\n// ---------------------------------------------------------------------------\n// parseMentions\n// ---------------------------------------------------------------------------\n\nconst MENTION_RE = /@(\\w+)/g;\nconst MENTION_GROUP_SET: ReadonlySet<string> = new Set(MENTION_GROUPS);\n\n/**\n * Scan `text` for @token patterns and return resolved {@link Mention} objects.\n *\n * - Well-known group tokens (`agent`, `humans`, `humans_here`, `here`, `all`)\n * are resolved via {@link MentionResolver.resolveGroup}.\n * - All other tokens are resolved via {@link MentionResolver.resolveUser}.\n * - Tokens that cannot be resolved are silently ignored.\n * - Results are sorted by character offset ascending.\n *\n * @param text - Raw message text to scan for `@token` patterns.\n * @param resolver - Resolver that maps tokens to users and groups.\n * @returns Resolved mentions ordered by position in text.\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport function parseMentions(text: string, resolver: MentionResolver): Mention[] {\n const mentions: Mention[] = [];\n\n for (const match of text.matchAll(MENTION_RE)) {\n const token = match[1]!;\n const offset = match.index!;\n const length = match[0].length; // includes the @\n\n if (MENTION_GROUP_SET.has(token)) {\n const group = token as MentionGroup;\n mentions.push({\n type: \"group\",\n group,\n resolved: resolver.resolveGroup(group),\n offset,\n length,\n });\n } else {\n const user = resolver.resolveUser(token);\n if (user) {\n mentions.push({\n type: \"user\",\n userId: user.userId,\n name: user.name,\n offset,\n length,\n });\n }\n }\n }\n\n // matchAll iterates left-to-right, so mentions are already offset-ascending.\n return mentions;\n}\n\n// ---------------------------------------------------------------------------\n// isMentioned\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if `userId` is directly mentioned or is a member of any\n * group mention's resolved list.\n *\n * @param userId - The user ID to check (e.g. from the auth context).\n * @param mentions - Parsed mentions from {@link parseMentions}.\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport function isMentioned(userId: string, mentions: Mention[]): boolean {\n for (const m of mentions) {\n if (m.type === \"user\" && m.userId === userId) return true;\n if (m.type === \"group\" && m.resolved.includes(userId)) return true;\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// isAgentAddressed\n// ---------------------------------------------------------------------------\n\n/** Groups that include the agent in their resolved membership. */\nconst AGENT_GROUPS: ReadonlySet<MentionGroup> = new Set([\"agent\", \"here\", \"all\"]);\n\n/**\n * Returns true if the agent is addressed by any mention in the list.\n *\n * The groups `@agent`, `@here`, and `@all` address the agent. `@humans`\n * and `@humans_here` do not. Individual user mentions are also not matched\n * here — agent addressing is group-based.\n *\n * @param mentions - Parsed mentions from {@link parseMentions}.\n * @docLink packages/session/api-reference#mention-resolver\n */\nexport function isAgentAddressed(mentions: Mention[]): boolean {\n return mentions.some((m) => m.type === \"group\" && AGENT_GROUPS.has(m.group));\n}\n"]}
@@ -1,8 +1,8 @@
1
- import { removeAsset, deployAll, createScaffold } from './chunk-2RFOFHSM.js';
2
- import { writeLock, buildLockFile, readLock, verifyLock, extractForPatch, generatePatch, savePatch, applyPatch } from './chunk-Z3M5K67G.js';
3
- import { resolveRuntimeAssets } from './chunk-5ESCS2OS.js';
4
- import { resolveSkWorkspaceConfig, getRepoCommit, ensureRepo, buildProvenanceIndex, resolveAll, scanRepo, checkRepoStatus, resolveAsset, readLinks, getGlobalCacheDir } from './chunk-542K7SR6.js';
5
- import { parseAssetRef } from './chunk-YX3UWPJ5.js';
1
+ import { removeAsset, deployAll, createScaffold } from './chunk-BKF3UFF4.js';
2
+ import { writeLock, buildLockFile, readLock, verifyLock, extractForPatch, generatePatch, savePatch, applyPatch } from './chunk-KL2MQ6WI.js';
3
+ import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-C32BRO2W.js';
4
+ import { resolveSkWorkspaceConfig, getRepoCommit, ensureRepo, buildProvenanceIndex, resolveAll, scanRepo, checkRepoStatus, resolveAsset, readLinks, getGlobalCacheDir } from './chunk-Z5DI7PDG.js';
5
+ import { parseAssetRef } from './chunk-IEJ5IOC3.js';
6
6
  import { deployedBase, isDeployed, deployedDir } from './chunk-JKNWJ64A.js';
7
7
  import { appendHistory, getRecentHistory, clearHistory } from './chunk-KTBKW2FI.js';
8
8
  import { commitChanges } from './chunk-UQ6LFBPZ.js';
@@ -15,6 +15,9 @@ import { parse, stringify } from 'yaml';
15
15
  function sourceSlug(url) {
16
16
  return url.replace(/\.git$/, "").split(/[/:]/).pop() ?? "source";
17
17
  }
18
+ function normalizeRepoUrl(url) {
19
+ return url.trim().replace(/^git@([^:]+):/, "https://$1/").replace(/^[a-z]+:\/\//i, "").replace(/\.git$/i, "").replace(/\/+$/, "").toLowerCase();
20
+ }
18
21
  function parseCanonicalLockKey(key) {
19
22
  try {
20
23
  const ref = parseAssetRef(key);
@@ -28,6 +31,29 @@ function parseCanonicalLockKey(key) {
28
31
  return {};
29
32
  }
30
33
  }
34
+ var FACTORY_SOURCE_URL = "https://github.com/skaile-ai/ai-assets";
35
+ function resolveFactoryAssetsDir() {
36
+ for (const dir of factoryAssetRoots()) {
37
+ if (existsSync(join(dir, "skaile.manifest.yaml"))) return dir;
38
+ }
39
+ return null;
40
+ }
41
+ function readDeclaredPublisher(sourceDir) {
42
+ try {
43
+ const raw = parse(readFileSync(join(sourceDir, "skaile.manifest.yaml"), "utf8"));
44
+ return raw && typeof raw.publisher === "string" && raw.publisher.length > 0 ? raw.publisher : void 0;
45
+ } catch {
46
+ return void 0;
47
+ }
48
+ }
49
+ var factorySourceCache;
50
+ function resolveFactorySource() {
51
+ if (factorySourceCache !== void 0) return factorySourceCache;
52
+ const dir = resolveFactoryAssetsDir();
53
+ const publisher = dir ? readDeclaredPublisher(dir) : void 0;
54
+ factorySourceCache = dir && publisher ? { dir, publisher } : null;
55
+ return factorySourceCache;
56
+ }
31
57
  var AssetManager = class {
32
58
  /** Resolved absolute path to the workspace root. */
33
59
  projectDir;
@@ -67,6 +93,18 @@ var AssetManager = class {
67
93
  if (repositories[slug]) continue;
68
94
  repositories[slug] = { path: join(sourcesDir, slug), url: s.url };
69
95
  }
96
+ const factory = resolveFactorySource();
97
+ const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);
98
+ const alreadyDeclared = Object.values(repositories).some(
99
+ (d) => d.url !== void 0 && normalizeRepoUrl(d.url) === factoryUrl
100
+ );
101
+ if (factory && !alreadyDeclared && !repositories[factory.publisher]) {
102
+ repositories[factory.publisher] = {
103
+ path: factory.dir,
104
+ url: FACTORY_SOURCE_URL,
105
+ factory: true
106
+ };
107
+ }
70
108
  return { repositories, sources, stores, dependencies, overrides, patches, config };
71
109
  }
72
110
  /** Build provenance-index clones from the resolved source declarations. */
@@ -121,17 +159,23 @@ var AssetManager = class {
121
159
  const mdName = MD_BY_KIND[c.kind];
122
160
  const mdRel = c.files.find((f) => mdName ? f.path.endsWith(mdName) : false)?.path;
123
161
  const source = mdRel ? join(cloneDir, mdRel) : cloneDir;
124
- return {
162
+ const entry = {
125
163
  name: c.name,
126
164
  kind: c.kind,
127
- description: "",
165
+ description: c.description ?? "",
128
166
  source,
129
167
  publisher: slug,
130
168
  version: c.version,
131
169
  requires: [],
132
- dependencies: [],
170
+ // Manifest-declared deps are authoritative for the candidate's deps.
171
+ dependencies: c.deps ?? [],
133
172
  metadata: c.metadata
134
173
  };
174
+ if (c.category != null) entry.category = c.category;
175
+ if (c.keywords && c.keywords.length > 0) entry.keywords = c.keywords;
176
+ if (c.license != null) entry.license = c.license;
177
+ if (c.homepage != null) entry.homepage = c.homepage;
178
+ return entry;
135
179
  }
136
180
  // ── Install / resolve ──────────────────────────────────────────────────
137
181
  /**
@@ -434,9 +478,10 @@ var AssetManager = class {
434
478
  for (const [name, decl] of Object.entries(repositories)) {
435
479
  const repoDir = this.resolveRepoDir(decl, name);
436
480
  if (!repoDir) continue;
437
- if (parsed.publisher && parsed.publisher !== name) continue;
438
481
  const entries = scanRepo(repoDir, name);
439
- const match = entries.find((e) => e.kind === parsed.kind && e.name === parsed.name);
482
+ const match = entries.find(
483
+ (e) => e.kind === parsed.kind && e.name === parsed.name && (!parsed.publisher || e.publisher === parsed.publisher)
484
+ );
440
485
  if (match) return match;
441
486
  }
442
487
  return null;
@@ -729,7 +774,8 @@ var AssetManager = class {
729
774
  const { repositories } = this.loadConfig();
730
775
  const decl = repositories[entry.publisher];
731
776
  if (!decl?.url) throw new Error("Can only submit patches for remote sources.");
732
- const repoDir = join(this.reposDir, entry.publisher);
777
+ const repoDir = this.resolveRepoDir(decl, entry.publisher);
778
+ if (!repoDir) throw new Error(`Repository clone not found for ${entry.publisher}.`);
733
779
  const branchName = `patch/${parsed.kind}-${parsed.name}`;
734
780
  const patchFile = join(this.patchDir, `${parsed.kind}-${parsed.name}.patch`);
735
781
  if (!existsSync(patchFile)) throw new Error("No patch file. Run `skaile patch-commit` first.");
@@ -944,5 +990,5 @@ var AssetManager = class {
944
990
  };
945
991
 
946
992
  export { AssetManager, parseCanonicalLockKey };
947
- //# sourceMappingURL=chunk-N6TA6RSH.js.map
948
- //# sourceMappingURL=chunk-N6TA6RSH.js.map
993
+ //# sourceMappingURL=chunk-PY7AQRGH.js.map
994
+ //# sourceMappingURL=chunk-PY7AQRGH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../asset-manager/src/index.ts"],"names":["parseYaml","stringifyYaml"],"mappings":"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","file":"chunk-PY7AQRGH.js","sourcesContent":["/**\n * @skaile/asset-manager — programmatic AI asset management API.\n *\n * Manages project-local repositories, dependency resolution, deployment,\n * lock files, patches, and contribution workflows.\n *\n * Usage:\n * import { AssetManager } from \"@skaile/workspaces/asset-manager\"\n * const am = new AssetManager({ projectDir: \"/path/to/project\" })\n * await am.install()\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport {\n existsSync,\n lstatSync,\n readdirSync,\n readFileSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport type {\n AiComponent,\n CatalogEntry,\n DriverTarget,\n LockFile,\n OverrideEntry,\n ProvenanceCandidate,\n SkWorkspaceConfig,\n SourceClone,\n SourceDeclaration,\n SourceEntry,\n StoreEntry,\n StoreFetcher,\n} from \"@skaile/workspaces/core\";\nimport {\n buildLockFile,\n buildProvenanceIndex,\n checkRepoStatus,\n applyPatch as coreApplyPatch,\n deployedBase,\n deployedDir,\n ensureRepo,\n extractForPatch,\n generatePatch,\n getGlobalCacheDir,\n factoryAssetRoots,\n getRepoCommit,\n isDeployed,\n parseAssetRef,\n readLinks,\n readLock,\n resolveAll,\n resolveAsset,\n resolveRuntimeAssets,\n resolveSkWorkspaceConfig,\n savePatch,\n scanRepo,\n verifyLock,\n writeLock,\n} from \"@skaile/workspaces/core\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { commitChanges } from \"./contrib.js\";\nimport type { HistoryEntry } from \"./history.js\";\nimport { appendHistory, clearHistory, getRecentHistory } from \"./history.js\";\nimport type { DeployOptions } from \"./installer.js\";\nimport { createScaffold, deployAll, removeAsset } from \"./installer.js\";\n\n/** Derive a cache slug from a source git URL (`<host>/<owner>/<repo>` → `<repo>`). */\nfunction sourceSlug(url: string): string {\n return (\n url\n .replace(/\\.git$/, \"\")\n .split(/[/:]/)\n .pop() ?? \"source\"\n );\n}\n\n/**\n * Normalize a git remote URL to a comparable identity so the same repo declared\n * in different syntaxes (`https://…`, `git@host:…`, trailing `/`, `.git` suffix,\n * case) compares equal. Used to dedupe the implicit factory source against an\n * explicit user declaration.\n */\nfunction normalizeRepoUrl(url: string): string {\n return url\n .trim()\n .replace(/^git@([^:]+):/, \"https://$1/\") // git@host:org/repo → https://host/org/repo\n .replace(/^[a-z]+:\\/\\//i, \"\") // drop scheme\n .replace(/\\.git$/i, \"\")\n .replace(/\\/+$/, \"\")\n .toLowerCase();\n}\n\n/**\n * Parse a canonical lock key (`<kind>:@<publisher>/<name>#<version>`) into its\n * parts. The lock key is now a canonical asset ref, so this delegates to the one\n * ref parser; `AssetRef.pin` is exposed as `version` so the callers' destructuring\n * is unchanged. Stays total — callers rely on `{}`-then-`continue`, but\n * `parseAssetRef` throws, so a malformed key is caught and returned as `{}`.\n *\n * @internal Exported for unit tests; not part of the stable public surface.\n */\nexport function parseCanonicalLockKey(key: string): {\n publisher?: string;\n kind?: string;\n name?: string;\n version?: string;\n} {\n try {\n const ref = parseAssetRef(key);\n return {\n publisher: ref.publisher,\n kind: ref.kind,\n name: ref.name,\n version: ref.pin,\n };\n } catch {\n return {};\n }\n}\n\nexport type { HistoryEntry } from \"./history.js\";\nexport {\n appendHistory,\n clearHistory,\n getRecentHistory,\n loadHistory,\n} from \"./history.js\";\n// Re-export sub-modules\nexport type { DeployOptions } from \"./installer.js\";\nexport { createScaffold, deployAll, removeAsset } from \"./installer.js\";\nexport type { Log } from \"./renderers.js\";\nexport { renderAgentToFramework } from \"./renderers.js\";\n// Contrib helpers (commitChanges et al.) are still used internally by the\n// patch-submit flow but are no longer part of the public API surface — the\n// `skaile repo contrib *` command tree was removed on 2026-05-12.\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\n/**\n * Metadata about a repository declared in `skaile.yaml`.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface RepoInfo {\n /** Repository name as declared in `skaile.yaml`. */\n name: string;\n /** How the repo is sourced: cloned from a URL, mounted from a local path, or symlinked via `skaile repo link`. */\n kind: \"local\" | \"remote\" | \"linked\";\n /** Remote URL (present when `kind === \"remote\"`). */\n url?: string;\n /** Filesystem path (present when `kind === \"local\"` or `kind === \"linked\"`). */\n path?: string;\n /** Git branch configured for this repository. */\n branch: string;\n /** Whether the repository has been cloned/resolved locally. */\n cloned: boolean;\n}\n\n/**\n * Live sync status for a repository.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface RepoStatusInfo {\n /** Repository name as declared in `skaile.yaml`. */\n name: string;\n /** How the repo is sourced. */\n kind: \"local\" | \"remote\" | \"linked\";\n /** Number of commits the local clone is behind the remote. */\n behind: number;\n /** `true` when the local clone matches the remote HEAD. */\n upToDate: boolean;\n /** Error message when status check failed. */\n error?: string;\n}\n\n/**\n * Result of a full `skaile install` or `skaile add` run.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface InstallResult {\n /** Asset refs (`kind:name`) successfully deployed in this run. */\n deployed: string[];\n /** Asset refs (`kind:name`) removed because they are no longer in the resolved set. */\n removed: string[];\n /** Asset refs that could not be resolved in any configured repository. */\n missing: string[];\n /** Whether `skaile.lock.yaml` was written or updated. */\n lockWritten: boolean;\n /**\n * npm packages installed as a side effect of resolving runtime asset peer\n * deps (connectors / mounts declared in skaile.yaml). Empty when nothing\n * needed installing or when the runtime-deps step was skipped.\n */\n npmInstalled?: string[];\n /**\n * npm packages that the runtime-deps step tried but failed to install.\n * Non-fatal — listed for telemetry and CLI reporting.\n */\n npmFailed?: string[];\n}\n\n/**\n * An installed asset whose source repository is behind the remote.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface OutdatedEntry {\n /** Asset kind (`skill`, `agent`, `prompt`, `flow`, `contract`). */\n kind: string;\n /** Asset name as registered in the catalog. */\n name: string;\n /** Repository that provides this asset. */\n publisher: string;\n /** Version string recorded in the lock file at install time. */\n currentVersion: string;\n /** Number of commits the local repository is behind the remote. */\n behind: number;\n}\n\n/**\n * A node in the resolved dependency tree (returned by `AssetManager.tree()`).\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface DependencyNode {\n /** Asset ref (`kind:name`) or `\"project\"` for the root node. */\n ref: string;\n /** Transitive dependencies resolved by this node. */\n children: DependencyNode[];\n}\n\n/**\n * A missing dependency detected by `AssetManager.doctor()`.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface DepIssue {\n /** Kind of the asset that has the unsatisfied requirement. */\n assetKind: string;\n /** Name of the asset that has the unsatisfied requirement. */\n assetName: string;\n /** Kind of the missing dependency. */\n depKind: string;\n /** Name of the missing dependency. */\n depName: string;\n /** `true` when the missing dependency exists in a configured repository but has not been installed. */\n inRepos: boolean;\n}\n\n/**\n * A single deployed asset shown in the workspace overview.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface OverviewEntry {\n /** Asset kind (`skill`, `agent`, `prompt`, `flow`, `contract`). */\n kind: string;\n /** Asset name. */\n name: string;\n /** Domain the asset belongs to (from the lock file; `\"unknown\"` when unresolvable). */\n domain: string;\n /** Repository that provides this asset. */\n publisher: string;\n /** Version string from the lock file. */\n version: string;\n /**\n * Sync status relative to the source repository.\n * - `\"synced\"` — local clone matches remote HEAD\n * - `\"outdated\"` — local clone is behind the remote\n * - `\"local\"` — sourced from a local path, no remote to compare\n * - `\"error\"` — status check failed\n * - `\"unknown\"` — repository not found or lock entry missing\n */\n syncStatus: string;\n}\n\n/**\n * Aggregated workspace overview returned by `AssetManager.overview()`.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface OverviewResult {\n /** Entries grouped by domain, sorted alphabetically. Each group is sorted by kind then name. */\n byDomain: Map<string, OverviewEntry[]>;\n /** Total number of deployed assets. */\n total: number;\n /** Sync status for each configured repository. */\n repos: RepoStatusInfo[];\n}\n\n// ── AssetManager ─────────────────────────────────────────────────────────────\n\n/**\n * Options for constructing an {@link AssetManager}.\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport interface AssetManagerOptions {\n /** Absolute or relative path to the workspace root (must contain `skaile.yaml`). */\n projectDir: string;\n /**\n * Agent framework to target for asset deployment.\n * Determines which framework directories (``.claude/``, ``.omp/``, etc.) are used.\n * Defaults to `\"claude-code\"`.\n */\n driverTarget?: DriverTarget;\n /**\n * When `true`, assets are installed into the global Skaile cache rather than the\n * project workspace. Skips `skaile.yaml` dependency updates.\n */\n global?: boolean;\n}\n\n/** Canonical git URL identity for the bundled factory source. Never fetched —\n * the bytes live inside the package (`factory-assets/`); the URL is only the\n * match key the provenance walker and `candidateToCatalogEntry` key off. */\nconst FACTORY_SOURCE_URL = \"https://github.com/skaile-ai/ai-assets\";\n\n/**\n * Locate the built-in first-party skills/bundles shipped inside the package.\n *\n * Resolves through the shared {@link factoryAssetRoots} helper — the\n * `SKAILE_FACTORY_ASSETS_DIR` override layer (when set) ahead of the bundled\n * tree (in-repo source during dev, `dist/factory-assets/` after install), so a\n * container's override is honoured here identically to `serve`. Returns the\n * highest-precedence root that carries a `skaile.manifest.yaml` (the publication\n * manifest that names the source's publisher), or `null` when none qualifies —\n * the factory source is then simply not injected rather than erroring.\n */\nfunction resolveFactoryAssetsDir(): string | null {\n for (const dir of factoryAssetRoots()) {\n if (existsSync(join(dir, \"skaile.manifest.yaml\"))) return dir;\n }\n return null;\n}\n\n/** Read the declared `publisher` from a source's root `skaile.manifest.yaml`. */\nfunction readDeclaredPublisher(sourceDir: string): string | undefined {\n try {\n const raw = parseYaml(readFileSync(join(sourceDir, \"skaile.manifest.yaml\"), \"utf8\")) as {\n publisher?: unknown;\n } | null;\n return raw && typeof raw.publisher === \"string\" && raw.publisher.length > 0\n ? raw.publisher\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The bundled factory source `{ dir, publisher }`, or `null` when no usable\n * bundle is present. Resolved once per process — the package location and the\n * bundled `skaile.manifest.yaml` are immutable for the process lifetime, so the\n * `require.resolve` + `existsSync` probes + YAML parse run a single time rather\n * than on every `loadConfig()` call. `undefined` = not yet computed.\n */\nlet factorySourceCache: { dir: string; publisher: string } | null | undefined;\n\nfunction resolveFactorySource(): { dir: string; publisher: string } | null {\n if (factorySourceCache !== undefined) return factorySourceCache;\n const dir = resolveFactoryAssetsDir();\n const publisher = dir ? readDeclaredPublisher(dir) : undefined;\n factorySourceCache = dir && publisher ? { dir, publisher } : null;\n return factorySourceCache;\n}\n\n/**\n * Programmatic API for managing AI assets in a Skaile workspace.\n *\n * `AssetManager` wraps repository management, catalog search, asset installation,\n * lock-file tracking, patch workflows, and workspace diagnostics. The CLI delegates\n * all `skaile catalog`, `skaile repo`, `skaile install`, `skaile add`, and\n * `skaile init` commands to this class.\n *\n * @example\n * ```typescript\n * import { AssetManager } from \"@skaile/workspaces/asset-manager\";\n *\n * const am = new AssetManager({ projectDir: \"/my-project\" });\n *\n * // Install all dependencies declared in skaile.yaml\n * const result = await am.install();\n * console.log(`Deployed: ${result.deployed.join(\", \")}`);\n *\n * // Add a single skill (resolves transitive deps, updates skaile.yaml)\n * const deployed = am.add(\"skill:my-skill\");\n *\n * // Search the catalog\n * const skills = am.search(\"code review\", \"skill\");\n * ```\n *\n * @docLink packages/asset-manager/concepts#asset-manager\n */\nexport class AssetManager {\n /** Resolved absolute path to the workspace root. */\n readonly projectDir: string;\n /** Agent framework driver target used for all deploy operations. */\n readonly driverTarget: DriverTarget;\n /** Whether this instance operates in global-install mode. */\n readonly global: boolean;\n\n constructor(opts: AssetManagerOptions) {\n this.projectDir = resolve(opts.projectDir);\n this.driverTarget = opts.driverTarget ?? (\"claude-code\" as DriverTarget);\n this.global = opts.global ?? false;\n }\n\n private get reposDir(): string {\n return join(this.projectDir, \".skaile\", \"repos\");\n }\n\n private get lockPath(): string {\n return join(this.projectDir, \"skaile.lock.yaml\");\n }\n\n private get patchDir(): string {\n return join(this.projectDir, \".skaile\", \"patches\");\n }\n\n private get deployOpts(): DeployOptions {\n return { driverTarget: this.driverTarget, global: this.global, cwd: this.projectDir };\n }\n\n private loadConfig(): {\n repositories: Record<string, SourceDeclaration>;\n sources: SourceEntry[];\n stores: StoreEntry[];\n dependencies: string[];\n overrides: OverrideEntry[];\n patches: Record<string, string>;\n config: SkWorkspaceConfig;\n } {\n // resolveSkWorkspaceConfig runs the canonical normalizer and throws on\n // legacy keys (`repositories:` / `ai_resources:`) — propagate to the caller.\n const config = resolveSkWorkspaceConfig(this.projectDir);\n\n const sources = config.sources ?? [];\n const stores = config.stores ?? [];\n const dependencies = config.dependencies ?? [];\n const overrides = config.overrides ?? [];\n const patches = config.patches ?? {};\n\n // Internal install-pipeline map: slug (derived from the source URL) →\n // SourceDeclaration pointing at the machine-cache clone under\n // ~/.skaile/sources/<slug>/. The slug is also the cache key for ensureRepo.\n const skaileHome = process.env.SKAILE_HOME ?? join(homedir(), \".skaile\");\n const sourcesDir = join(skaileHome, \"sources\");\n const repositories: Record<string, SourceDeclaration> = {};\n for (const s of sources) {\n const slug = sourceSlug(s.url);\n if (repositories[slug]) continue;\n repositories[slug] = { path: join(sourcesDir, slug), url: s.url };\n }\n\n // Implicit built-in source: the first-party assets shipped inside the\n // package (`dist/factory-assets/`). Always available, zero config — keyed by\n // its declared publisher so refs (`kind:@<publisher>/name`) and `info`\n // resolve cleanly. Skipped when the user already declares the same source\n // explicitly (avoids duplicate catalog entries) or when no bundle is present.\n const factory = resolveFactorySource();\n const factoryUrl = normalizeRepoUrl(FACTORY_SOURCE_URL);\n const alreadyDeclared = Object.values(repositories).some(\n (d) => d.url !== undefined && normalizeRepoUrl(d.url) === factoryUrl,\n );\n if (factory && !alreadyDeclared && !repositories[factory.publisher]) {\n repositories[factory.publisher] = {\n path: factory.dir,\n url: FACTORY_SOURCE_URL,\n factory: true,\n };\n }\n\n return { repositories, sources, stores, dependencies, overrides, patches, config };\n }\n\n /** Build provenance-index clones from the resolved source declarations. */\n private buildClones(repositories: Record<string, SourceDeclaration>): SourceClone[] {\n const clones: SourceClone[] = [];\n for (const [slug, decl] of Object.entries(repositories)) {\n const localPath = this.resolveRepoDir(decl, slug);\n if (!localPath || !existsSync(localPath)) continue;\n const commit = getRepoCommit(localPath) ?? \"0\".repeat(40);\n clones.push({\n localPath,\n sourceUrl: decl.url ?? localPath,\n commit,\n tag: decl.branch,\n });\n }\n return clones;\n }\n\n /**\n * Bridge a resolved {@link ProvenanceCandidate} to a {@link CatalogEntry} for\n * the deploy pipeline. `source` is the absolute path to the asset's primary\n * manifest (or its directory) inside the clone; `publisher` is set to the\n * clone slug so `deployAll`'s repositories lookup resolves local-vs-remote.\n */\n private candidateToCatalogEntry(\n c: ProvenanceCandidate,\n repositories: Record<string, SourceDeclaration>,\n ): CatalogEntry | null {\n // Find the clone slug whose declaration URL matches the candidate's source.\n let slug: string | undefined;\n let cloneDir: string | undefined;\n for (const [s, decl] of Object.entries(repositories)) {\n if (decl.url === c.sourceUrl) {\n slug = s;\n cloneDir = this.resolveRepoDir(decl, s) ?? undefined;\n break;\n }\n }\n if (!cloneDir) {\n // Store-resolved or unknown source — fall back to the first source clone.\n const first = Object.entries(repositories)[0];\n if (first) {\n slug = first[0];\n cloneDir = this.resolveRepoDir(first[1], first[0]) ?? undefined;\n }\n }\n if (!cloneDir || !slug) return null;\n\n const MD_BY_KIND: Record<string, string> = {\n skill: \"SKILL.md\",\n agent: \"AGENT.md\",\n bundle: \"BUNDLE.md\",\n \"mcp-server\": \"MCP.md\",\n connector: \"CONNECTOR.md\",\n prompt: \"PROMPT.md\",\n contract: \"CONTRACT.md\",\n };\n const mdName = MD_BY_KIND[c.kind];\n const mdRel = c.files.find((f) => (mdName ? f.path.endsWith(mdName) : false))?.path;\n const source = mdRel ? join(cloneDir, mdRel) : cloneDir;\n\n const entry: CatalogEntry = {\n name: c.name,\n kind: c.kind as CatalogEntry[\"kind\"],\n description: c.description ?? \"\",\n source,\n publisher: slug,\n version: c.version,\n requires: [],\n // Manifest-declared deps are authoritative for the candidate's deps.\n dependencies: c.deps ?? [],\n metadata: c.metadata,\n };\n if (c.category != null) entry.category = c.category;\n if (c.keywords && c.keywords.length > 0) entry.keywords = c.keywords;\n if (c.license != null) entry.license = c.license;\n if (c.homepage != null) entry.homepage = c.homepage;\n return entry;\n }\n\n // ── Install / resolve ──────────────────────────────────────────────────\n\n /**\n * Install all dependencies declared in `skaile.yaml`.\n *\n * Steps: clone/pull repositories → resolve transitive dependencies → reconcile\n * (remove stale assets) → deploy new assets → write `skaile.lock.yaml` → record history.\n *\n * @param opts - Optional installation options.\n * @param opts.locked - When `true`, restore the exact versions recorded in the existing\n * lock file instead of resolving from source. Throws if no lock file is found.\n * @returns {@link InstallResult} summarising what was deployed, what was missing, and any collisions.\n */\n async install(opts?: { locked?: boolean }): Promise<InstallResult> {\n const { repositories, sources, stores, dependencies, overrides, patches } = this.loadConfig();\n\n if (opts?.locked) {\n return this.installLocked(repositories, patches);\n }\n\n // 1. Ensure all source clones are present/up to date.\n const pinBySlug = new Map(sources.map((s) => [sourceSlug(s.url), s.pin]));\n for (const [name, decl] of Object.entries(repositories)) {\n try {\n ensureRepo(decl, name, this.reposDir, {\n projectDir: this.projectDir,\n pin: pinBySlug.get(name),\n });\n } catch (err) {\n return {\n deployed: [],\n removed: [],\n missing: [`source:${name} (${err instanceof Error ? err.message : String(err)})`],\n lockWritten: false,\n };\n }\n }\n\n // 2. Build the provenance index from the clones and resolve.\n const provenanceIndex = buildProvenanceIndex(this.buildClones(repositories), {\n projectDir: this.projectDir,\n });\n const { resolved, missing, overridesApplied } = await resolveAll(dependencies, {\n provenanceIndex,\n overrides,\n stores,\n storeFetcher: this.buildStoreFetcher(stores),\n projectDir: this.projectDir,\n });\n\n // 3. Reconcile: remove stale assets (in old lock but not in new resolved set).\n const oldLock = this.tryReadLock();\n const resolvedRefs = new Set(\n resolved.map((c) => `${c.publisher}/${c.kind}:${c.name}@${c.version}`),\n );\n const removed: string[] = [];\n if (oldLock) {\n for (const ref of Object.keys(oldLock.assets)) {\n if (!resolvedRefs.has(ref)) {\n const { kind, name } = parseCanonicalLockKey(ref);\n if (kind && name) {\n removeAsset(kind, name, this.deployOpts);\n removed.push(ref);\n }\n }\n }\n }\n\n // 4. Map candidates to catalog entries and deploy.\n const entries = resolved\n .map((c) => this.candidateToCatalogEntry(c, repositories))\n .filter((e): e is CatalogEntry => e !== null);\n const deployed = deployAll(entries, repositories, patches, this.deployOpts);\n\n // 5. Write the v2 lock file.\n writeLock(this.lockPath, buildLockFile(resolved, overridesApplied));\n\n // 6. Record history.\n for (const ref of deployed) {\n appendHistory(this.projectDir, {\n ref,\n action: \"add\",\n timestamp: new Date().toISOString(),\n context: this.global ? \"global\" : \"project\",\n });\n }\n for (const ref of removed) {\n appendHistory(this.projectDir, {\n ref,\n action: \"remove\",\n timestamp: new Date().toISOString(),\n context: this.global ? \"global\" : \"project\",\n });\n }\n\n // 7. Install npm peer deps for any mount/connector declared in skaile.yaml.\n const { npmInstalled, npmFailed } = await this.installRuntimeAssetDeps();\n\n return { deployed, removed, missing, lockWritten: true, npmInstalled, npmFailed };\n }\n\n /** Read the lock, returning null on a legacy v1 lock instead of throwing. */\n private tryReadLock(): LockFile | null {\n try {\n return readLock(this.lockPath);\n } catch {\n return null;\n }\n }\n\n /** Build a store fetcher from the configured stores, or undefined when none. */\n private buildStoreFetcher(stores: StoreEntry[]): StoreFetcher | undefined {\n if (stores.length === 0) return undefined;\n return {\n getInstallManifest: async (storeUrl, ref) => {\n const { RemoteCatalogSource, CatalogHttpError } = await import(\n \"@skaile/workspaces/library\"\n );\n const src = new RemoteCatalogSource({ baseUrl: storeUrl });\n try {\n const m = await src.getInstallManifest(ref);\n return {\n sourceUrl: m.source.url,\n commit: m.source.commitSha,\n sha256: m.sha256,\n files: m.files,\n };\n } catch (err) {\n if (err instanceof CatalogHttpError && err.status === 404) return null;\n throw err;\n }\n },\n getCanonicalDigest: async (storeUrl, ref) => {\n const { RemoteCatalogSource } = await import(\"@skaile/workspaces/library\");\n const src = new RemoteCatalogSource({ baseUrl: storeUrl });\n return src.getCanonicalDigest(ref);\n },\n };\n }\n\n /**\n * Resolve runtime assets and install any missing npm peer deps.\n *\n * - Required deps: installed via `bun add --optional`. Failure is recorded\n * in `npmFailed` but does not throw — install() proceeds so users get a\n * useful error message rather than a hung command.\n * - Optional deps: not installed automatically (would force every consumer\n * to pull every connector's deps). Future: add a flag to opt in.\n */\n private async installRuntimeAssetDeps(): Promise<{\n npmInstalled: string[];\n npmFailed: string[];\n }> {\n const npmInstalled: string[] = [];\n const npmFailed: string[] = [];\n let runtimeAssets: Awaited<ReturnType<typeof resolveRuntimeAssets>> | null = null;\n try {\n runtimeAssets = await resolveRuntimeAssets(this.projectDir);\n } catch {\n // Non-fatal — projects with no skaile.yaml or unresolvable factory-assets\n // simply have no runtime deps to install.\n return { npmInstalled, npmFailed };\n }\n\n const required = runtimeAssets.requiredNpmDeps.required;\n if (required.length === 0) return { npmInstalled, npmFailed };\n\n const { findMissingPackages, installNpmPackages } = await import(\n \"@skaile/workspaces/connectors\"\n );\n const missing = findMissingPackages(required, this.projectDir);\n if (missing.length === 0) return { npmInstalled, npmFailed };\n\n const result = await installNpmPackages(missing, this.projectDir);\n if (result.success) {\n npmInstalled.push(...missing);\n } else {\n npmFailed.push(...missing);\n }\n return { npmInstalled, npmFailed };\n }\n\n private installLocked(\n repositories: Record<string, SourceDeclaration>,\n patches: Record<string, string>,\n ): InstallResult {\n const lock = this.tryReadLock();\n if (!lock) {\n throw new Error(\"No lock file found. Run `skaile install` first.\");\n }\n\n // Ensure every contributing source clone exists at its pinned commit. Sources\n // are keyed by URL slug; the lock's `sources[]` carries the URL + commit.\n const declBySlug = new Map(Object.entries(repositories));\n for (const src of lock.sources) {\n const slug = sourceSlug(src.url);\n const decl = declBySlug.get(slug) ?? { url: src.url };\n ensureRepo(decl, slug, this.reposDir, { projectDir: this.projectDir, pin: src.commit });\n }\n\n // Resolve a source URL to its on-disk clone for verification.\n const resolveCloneDir = (sourceUrl: string): string | null => {\n const slug = sourceSlug(sourceUrl);\n const decl = declBySlug.get(slug) ?? { url: sourceUrl };\n return this.resolveRepoDir(decl, slug);\n };\n\n // Verify integrity against the v2 lock.\n const verification = verifyLock(lock, resolveCloneDir);\n if (!verification.ok) {\n const issues = [\n ...verification.drifted.map((r) => `drifted: ${r}`),\n ...verification.missing.map((r) => `missing: ${r}`),\n ];\n throw new Error(`Lock file verification failed:\\n ${issues.join(\"\\n \")}`);\n }\n\n // Rebuild catalog entries from the lock and deploy.\n const resolved: CatalogEntry[] = [];\n for (const [ref, entry] of Object.entries(lock.assets)) {\n const { publisher, kind, name } = parseCanonicalLockKey(ref);\n if (!publisher || !kind || !name) continue;\n const slug = sourceSlug(entry.source.url);\n const cloneDir = resolveCloneDir(entry.source.url) ?? join(this.reposDir, slug);\n const mdRel =\n entry.files.find((f) => /\\.(md|yaml)$/i.test(f.path))?.path ?? entry.files[0]?.path ?? \"\";\n resolved.push({\n name,\n kind: kind as CatalogEntry[\"kind\"],\n description: \"\",\n source: mdRel ? join(cloneDir, mdRel) : cloneDir,\n publisher: slug,\n version: entry.source.commit,\n requires: [],\n dependencies: [],\n });\n // Ensure the repositories map has an entry for deployAll's local/remote check.\n if (!repositories[slug]) repositories[slug] = { url: entry.source.url, path: cloneDir };\n }\n\n const deployed = deployAll(resolved, repositories, patches, this.deployOpts);\n return { deployed, removed: [], missing: [], lockWritten: false };\n }\n\n /**\n * Add a single asset (and its transitive dependencies) to the workspace.\n *\n * Resolves `ref`, deploys the asset and all requirements, then records the ref\n * in `skaile.yaml` `dependencies` so subsequent `skaile install` runs re-deploy it.\n *\n * @param ref - Asset ref in `kind:name` or `repo/kind:name` form (e.g. `skill:my-skill`).\n * @returns Array of asset refs that were deployed in this call.\n * @throws When the asset cannot be found in any configured repository.\n */\n async add(ref: string): Promise<string[]> {\n const { repositories, stores, overrides, patches } = this.loadConfig();\n const parsed = parseAssetRef(ref);\n\n // Ensure clones.\n for (const [name, decl] of Object.entries(repositories)) {\n try {\n ensureRepo(decl, name, this.reposDir, { projectDir: this.projectDir });\n } catch {}\n }\n\n const provenanceIndex = buildProvenanceIndex(this.buildClones(repositories), {\n projectDir: this.projectDir,\n });\n const { resolved, missing } = await resolveAll([ref], {\n provenanceIndex,\n overrides,\n stores,\n storeFetcher: this.buildStoreFetcher(stores),\n projectDir: this.projectDir,\n });\n if (resolved.length === 0) {\n throw new Error(\n `Asset not found: ${ref}${missing.length ? ` (missing: ${missing.join(\", \")})` : \"\"}`,\n );\n }\n\n const entries = resolved\n .map((c) => this.candidateToCatalogEntry(c, repositories))\n .filter((e): e is CatalogEntry => e !== null);\n const deployed = deployAll(entries, repositories, patches, this.deployOpts);\n\n // Add to skaile.yaml dependencies (canonical ref string).\n this.addDependencyToConfig(ref);\n\n for (const d of deployed) {\n appendHistory(this.projectDir, {\n ref: d,\n action: \"add\",\n timestamp: new Date().toISOString(),\n context: this.global ? \"global\" : \"project\",\n });\n }\n\n return deployed;\n }\n\n /**\n * Remove a deployed asset and unregister it from `skaile.yaml`.\n *\n * @param ref - Asset ref in `kind:name` form (e.g. `skill:my-skill`).\n * @returns `true` if the asset was found and removed, `false` if it was not deployed.\n */\n remove(ref: string): boolean {\n const parsed = parseAssetRef(ref);\n const ok = removeAsset(parsed.kind, parsed.name, this.deployOpts);\n if (ok) {\n const depRef = `${parsed.kind}:${parsed.name}`;\n this.removeDependencyFromConfig(depRef);\n\n appendHistory(this.projectDir, {\n ref: depRef,\n action: \"remove\",\n timestamp: new Date().toISOString(),\n context: this.global ? \"global\" : \"project\",\n });\n }\n return ok;\n }\n\n // ── Query ──────────────────────────────────────────────────────────────\n\n /**\n * Search the catalog across all configured repositories.\n *\n * @param query - Substring to match against entry names and descriptions (case-insensitive).\n * Omit to return all entries.\n * @param kind - Filter by asset kind (`\"skill\"`, `\"agent\"`, `\"prompt\"`, `\"flow\"`, `\"contract\"`).\n * Omit to return all kinds.\n * @returns Array of matching {@link CatalogEntry} objects from all accessible repositories.\n */\n search(query?: string, kind?: string): CatalogEntry[] {\n const { repositories } = this.loadConfig();\n let all: CatalogEntry[] = [];\n\n for (const [name, decl] of Object.entries(repositories)) {\n const repoDir = this.resolveRepoDir(decl, name);\n if (!repoDir) continue;\n all = [...all, ...scanRepo(repoDir, name)];\n }\n\n if (kind) all = all.filter((e) => e.kind === kind);\n if (query) {\n const q = query.toLowerCase();\n all = all.filter(\n (e) => e.name.toLowerCase().includes(q) || e.description.toLowerCase().includes(q),\n );\n }\n return all;\n }\n\n /**\n * Look up a single asset's full catalog entry.\n *\n * @param ref - Asset ref in `kind:name` or `repo/kind:name` form.\n * @returns The matching {@link CatalogEntry}, or `null` when not found.\n */\n info(ref: string): CatalogEntry | null {\n const { repositories } = this.loadConfig();\n const parsed = parseAssetRef(ref);\n\n for (const [name, decl] of Object.entries(repositories)) {\n const repoDir = this.resolveRepoDir(decl, name);\n if (!repoDir) continue;\n // Match on the entry's scanned (manifest) publisher, not the repo map key\n // (= URL slug). The two are unrelated identities under canonical schema.\n const entries = scanRepo(repoDir, name);\n const match = entries.find(\n (e) =>\n e.kind === parsed.kind &&\n e.name === parsed.name &&\n (!parsed.publisher || e.publisher === parsed.publisher),\n );\n if (match) return match;\n }\n return null;\n }\n\n /**\n * List all assets currently deployed in the workspace (or global cache).\n *\n * Scans the framework deploy directories rather than the lock file, so it\n * also returns assets that were installed manually or outside of `skaile install`.\n *\n * @param kind - Filter by asset kind. Omit to return all kinds.\n * @returns Shallow {@link CatalogEntry} objects (description and version will be empty).\n */\n listDeployed(kind?: string): CatalogEntry[] {\n // Bundles are dependency groups, not deployed as files — exclude from scan\n const kinds = (\n kind ? [kind] : [\"skill\", \"agent\", \"prompt\", \"flow\", \"contract\"]\n ) as AiComponent[];\n const result: CatalogEntry[] = [];\n const seen = new Set<string>();\n for (const k of kinds) {\n try {\n const base = deployedBase(k, this.driverTarget, this.global, this.projectDir);\n if (!existsSync(base)) continue;\n for (const item of readdirSync(base, { withFileTypes: true })) {\n // Directories and symlinks use the directory name directly (skills, omp agents, etc.)\n // Files use the stem without extension (claude-code agents → .md, codex agents → .toml,\n // prompts → .prompt.md, flows → .flow.yaml/.flow.json)\n let name: string;\n if (item.isDirectory() || item.isSymbolicLink()) {\n name = item.name;\n } else if (item.isFile()) {\n name = item.name\n .replace(/\\.prompt\\.md$/, \"\")\n .replace(/\\.flow\\.(yaml|json)$/, \"\")\n .replace(/\\.bundle\\.yaml$/, \"\")\n .replace(/\\.(md|toml|yaml|json)$/, \"\");\n } else {\n continue;\n }\n const key = `${k}:${name}`;\n if (seen.has(key)) continue;\n seen.add(key);\n result.push({\n name,\n kind: k as any,\n description: \"\",\n source: join(base, item.name),\n version: \"\",\n requires: [],\n dependencies: [],\n });\n }\n } catch {}\n }\n return result;\n }\n\n /**\n * Build an aggregated workspace overview with domain grouping and sync status.\n *\n * Combines deployed assets, lock file metadata, and live repository status\n * into a single structured result. Used by `skaile status`.\n *\n * @returns {@link OverviewResult} with entries grouped by domain and per-repo sync status.\n */\n overview(): OverviewResult {\n const { repositories } = this.loadConfig();\n const lock = this.tryReadLock();\n const deployed = this.listDeployed();\n\n // Get repo sync status\n const repoStatuses = new Map<string, RepoStatusInfo>();\n for (const [name, decl] of Object.entries(repositories)) {\n const status = checkRepoStatus(decl, name, this.reposDir);\n repoStatuses.set(name, {\n name,\n kind: status.kind,\n behind: status.behind,\n upToDate: status.upToDate,\n error: status.error,\n });\n }\n\n // Index lock entries by their <kind>:<name> suffix for deployed-asset lookup.\n const lockByKindName = new Map<string, { publisher: string; version: string; url: string }>();\n for (const [key] of Object.entries(lock?.assets ?? {})) {\n const parsed = parseCanonicalLockKey(key);\n if (parsed.kind && parsed.name && parsed.publisher && parsed.version) {\n lockByKindName.set(`${parsed.kind}:${parsed.name}`, {\n publisher: parsed.publisher,\n version: parsed.version,\n url: lock!.assets[key]!.source.url,\n });\n }\n }\n\n // Build entries with publisher + sync info. Domain grouping is by publisher\n // now that the lock no longer records a project-local domain.\n const entries: OverviewEntry[] = [];\n for (const d of deployed) {\n const lockEntry = lockByKindName.get(`${d.kind}:${d.name}`);\n const publisher = lockEntry?.publisher ?? \"\";\n const version = lockEntry?.version ?? \"\";\n const slug = lockEntry ? sourceSlug(lockEntry.url) : \"\";\n let syncStatus = \"unknown\";\n if (slug) {\n const repoStatus = repoStatuses.get(slug);\n if (!repoStatus) syncStatus = \"unknown\";\n else if (repoStatus.kind === \"local\") syncStatus = \"local\";\n else if (repoStatus.error) syncStatus = \"error\";\n else if (repoStatus.upToDate) syncStatus = \"synced\";\n else syncStatus = \"outdated\";\n }\n const domain = publisher || \"unknown\";\n entries.push({ kind: d.kind, name: d.name, domain, publisher, version, syncStatus });\n }\n\n // Group by domain (= publisher)\n const byDomain = new Map<string, OverviewEntry[]>();\n for (const e of entries) {\n if (!byDomain.has(e.domain)) byDomain.set(e.domain, []);\n byDomain.get(e.domain)!.push(e);\n }\n\n // Sort domains alphabetically, entries within domain by kind then name\n const sorted = new Map<string, OverviewEntry[]>();\n for (const key of [...byDomain.keys()].sort()) {\n sorted.set(\n key,\n byDomain\n .get(key)!\n .sort((a, b) =>\n a.kind !== b.kind ? a.kind.localeCompare(b.kind) : a.name.localeCompare(b.name),\n ),\n );\n }\n\n return {\n byDomain: sorted,\n total: entries.length,\n repos: [...repoStatuses.values()],\n };\n }\n\n /**\n * Build the resolved dependency tree from the lock file.\n *\n * @returns Root {@link DependencyNode} with `ref === \"project\"` whose children\n * are the directly-declared dependencies, each with their own transitive subtrees.\n * Returns a single node with `ref === \"(no lock file)\"` when no lock exists.\n */\n tree(): DependencyNode {\n const lock = this.tryReadLock();\n if (!lock) return { ref: \"(no lock file)\", children: [] };\n\n // v2 lock no longer records per-asset parent provenance — every locked asset\n // is shown as a direct child of the project (flat tree).\n return {\n ref: \"project\",\n children: Object.keys(lock.assets).map((ref) => ({ ref, children: [] })),\n };\n }\n\n /**\n * Explain why an asset is installed by tracing its dependency chain in the lock file.\n *\n * @param ref - Asset ref in `kind:name` form.\n * @returns Chain of refs from the asset back to `\"direct (skaile.yaml)\"`, or `[]` when\n * the asset is not in the lock file.\n */\n why(ref: string): string[] {\n const lock = this.tryReadLock();\n if (!lock) return [];\n if (!lock.assets[ref]) return []; // not in lock file\n // v2 lock no longer records a dep chain — every locked asset is reported as\n // directly declared. (Transitive provenance reconstruction is out of scope.)\n return [ref, \"direct (skaile.yaml)\"];\n }\n\n /**\n * List installed assets whose source repository is behind the remote.\n *\n * Only remote repositories (not local paths) are checked for staleness.\n *\n * @returns Array of {@link OutdatedEntry} objects, one per asset in a repository\n * that has commits not yet pulled locally.\n */\n outdated(): OutdatedEntry[] {\n const { repositories } = this.loadConfig();\n const lock = this.tryReadLock();\n if (!lock) return [];\n\n const result: OutdatedEntry[] = [];\n for (const src of lock.sources) {\n const slug = sourceSlug(src.url);\n const decl = repositories[slug];\n if (!decl || decl.path) continue; // skip unknown / local sources\n const status = checkRepoStatus(decl, slug, this.reposDir);\n if (status.behind <= 0) continue;\n for (const [ref, entry] of Object.entries(lock.assets)) {\n if (entry.source.url !== src.url) continue;\n const { publisher, kind, name, version } = parseCanonicalLockKey(ref);\n if (!kind || !name) continue;\n result.push({\n kind,\n name,\n publisher: publisher ?? slug,\n currentVersion: version ?? \"\",\n behind: status.behind,\n });\n }\n }\n return result;\n }\n\n /**\n * Produce a unified diff between the deployed asset and its catalog source.\n *\n * Useful for detecting manual edits to deployed files or verifying that a patch\n * was applied correctly.\n *\n * @param ref - Asset ref in `kind:name` form.\n * @returns Unified diff string, or `null` when there are no differences or the\n * asset is not deployed/resolvable.\n */\n diff(ref: string): string | null {\n const parsed = parseAssetRef(ref);\n const entry = this.info(ref);\n if (!entry) return null;\n\n const deployedPath = join(\n deployedBase(parsed.kind as AiComponent, this.driverTarget, this.global, this.projectDir),\n parsed.name,\n );\n if (!existsSync(deployedPath) || !existsSync(entry.source)) return null;\n\n const r = spawnSync(\"diff\", [\"-ruN\", entry.source, deployedPath], { encoding: \"utf8\" });\n return r.status === 1 ? r.stdout : null;\n }\n\n // ── Lock ───────────────────────────────────────────────────────────────\n\n /**\n * Resolve all declared dependencies and write (or overwrite) `skaile.lock.yaml`.\n *\n * Performs repository sync and full dependency resolution without deploying assets.\n * Use this to regenerate the lock file after manually editing `skaile.yaml`.\n *\n * @returns The written {@link LockFile} data.\n */\n async lock(): Promise<LockFile> {\n const { repositories, stores, dependencies, overrides } = this.loadConfig();\n\n for (const [name, decl] of Object.entries(repositories)) {\n try {\n ensureRepo(decl, name, this.reposDir, { projectDir: this.projectDir });\n } catch {}\n }\n\n const provenanceIndex = buildProvenanceIndex(this.buildClones(repositories), {\n projectDir: this.projectDir,\n });\n const { resolved, overridesApplied } = await resolveAll(dependencies, {\n provenanceIndex,\n overrides,\n stores,\n storeFetcher: this.buildStoreFetcher(stores),\n projectDir: this.projectDir,\n });\n const lockData = buildLockFile(resolved, overridesApplied);\n writeLock(this.lockPath, lockData);\n return lockData;\n }\n\n // ── Patch workflow ─────────────────────────────────────────────────────\n\n /**\n * Extract a deployed asset into a patch working directory for editing.\n *\n * Copies the deployed asset to `.skaile/patches/<kind>-<name>/` so changes\n * can be made there and then committed as a patch file via `patchCommit`.\n *\n * @param ref - Asset ref in `kind:name` form.\n * @returns Absolute path to the patch working directory.\n * @throws When the asset cannot be found in the catalog.\n */\n patch(ref: string): string {\n const entry = this.info(ref);\n if (!entry) throw new Error(`Asset not found: ${ref}`);\n return extractForPatch(entry, this.patchDir);\n }\n\n /**\n * Generate a `.patch` file from changes made in the patch working directory.\n *\n * Diffs the patch working directory against the original catalog source and\n * writes the result to `.skaile/patches/<kind>-<name>.patch`.\n *\n * @param ref - Asset ref in `kind:name` form.\n * @returns Absolute path to the generated `.patch` file.\n * @throws When the patch working directory does not exist or no differences are found.\n */\n patchCommit(ref: string): string {\n const parsed = parseAssetRef(ref);\n const entry = this.info(ref);\n if (!entry) throw new Error(`Asset not found: ${ref}`);\n\n const patchedDir = join(this.patchDir, `${parsed.kind}-${parsed.name}`);\n if (!existsSync(patchedDir)) {\n throw new Error(`No patch working dir found. Run \\`skaile patch ${ref}\\` first.`);\n }\n\n const originalDir = dirname(entry.source);\n const content = generatePatch(originalDir, patchedDir);\n if (!content) throw new Error(\"No differences found.\");\n\n const patchFile = join(this.patchDir, `${parsed.kind}-${parsed.name}.patch`);\n savePatch(patchFile, content);\n return patchFile;\n }\n\n /**\n * Apply the committed patch file to the repository clone and open a contribution branch.\n *\n * Applies `.skaile/patches/<kind>-<name>.patch` to the repository clone, creates a\n * `patch/<kind>-<name>` branch, and stages a commit — ready to push via `contribPush`.\n *\n * @param ref - Asset ref in `kind:name` form.\n * @throws When the asset is not found, has no repository, or the patch file is missing.\n */\n patchSubmit(ref: string): void {\n const parsed = parseAssetRef(ref);\n const entry = this.info(ref);\n if (!entry?.publisher) throw new Error(`Asset not found or no publisher: ${ref}`);\n\n const { repositories } = this.loadConfig();\n const decl = repositories[entry.publisher];\n if (!decl?.url) throw new Error(\"Can only submit patches for remote sources.\");\n\n // Resolve through the same helper search/info use so patch + read agree on the clone dir.\n const repoDir = this.resolveRepoDir(decl, entry.publisher);\n if (!repoDir) throw new Error(`Repository clone not found for ${entry.publisher}.`);\n const branchName = `patch/${parsed.kind}-${parsed.name}`;\n\n // Apply patch to repo clone\n const patchFile = join(this.patchDir, `${parsed.kind}-${parsed.name}.patch`);\n if (!existsSync(patchFile)) throw new Error(\"No patch file. Run `skaile patch-commit` first.\");\n\n coreApplyPatch(repoDir, patchFile);\n commitChanges(repoDir, `fix: improve ${parsed.kind} ${parsed.name}`, branchName);\n }\n\n /**\n * Delete the patch working directory and patch file for an asset.\n *\n * @param ref - Asset ref in `kind:name` form.\n */\n patchRemove(ref: string): void {\n const parsed = parseAssetRef(ref);\n const patchFile = join(this.patchDir, `${parsed.kind}-${parsed.name}.patch`);\n const patchedDir = join(this.patchDir, `${parsed.kind}-${parsed.name}`);\n try {\n rmSync(patchFile);\n } catch {}\n try {\n rmSync(patchedDir, { recursive: true });\n } catch {}\n }\n\n // ── Doctor ─────────────────────────────────────────────────────────────\n\n /**\n * Scan deployed assets for unsatisfied transitive dependencies.\n *\n * For each deployed asset, checks that all entries in its `requires` list are\n * also deployed. Returns a list of issues with a flag indicating whether the\n * missing dependency can be resolved from a configured repository.\n *\n * @returns Array of {@link DepIssue} objects. An empty array means the workspace is healthy.\n */\n doctor(): DepIssue[] {\n const { repositories } = this.loadConfig();\n const deployed = this.listDeployed();\n const issues: DepIssue[] = [];\n\n for (const entry of deployed) {\n const full = this.info(`${entry.kind}:${entry.name}`);\n if (!full) continue;\n for (const req of full.requires) {\n if (\n !isDeployed(\n req.kind as AiComponent,\n req.name,\n this.driverTarget,\n this.global,\n this.projectDir,\n )\n ) {\n const inRepos =\n resolveAsset({ kind: req.kind, name: req.name }, repositories, this.reposDir) !== null;\n issues.push({\n assetKind: entry.kind,\n assetName: entry.name,\n depKind: req.kind,\n depName: req.name,\n inRepos,\n });\n }\n }\n }\n return issues;\n }\n\n // ── Scaffold ───────────────────────────────────────────────────────────\n\n /**\n * Create a minimal asset scaffold directory (delegates to {@link createScaffold}).\n *\n * @param name - Asset name (also used as the directory name).\n * @param kind - Asset kind: `skill` | `agent` | `bundle` | `flow` | `prompt` | `contract`.\n * @param destDir - Parent directory to create the asset in.\n * @returns `{ ok: true, path }` on success, `{ ok: false, path: errorMessage }` if the\n * directory already exists.\n */\n create(name: string, kind: string, destDir: string): { ok: boolean; path: string } {\n return createScaffold(name, kind, destDir);\n }\n\n // ── Contrib (REMOVED 2026-05-12) ───────────────────────────────────────\n //\n // The `contribChanges / contribDiff / contribCommit / contribPush /\n // contribCompare` methods were retired alongside `skaile repo contrib *`.\n // The refinement push-back workflow is being re-introduced in Phase 4 as\n // `skaile publish` + `skaile preset push` against the Library Source model.\n\n // ── History ────────────────────────────────────────────────────────────\n\n /**\n * Return recent asset action history entries, newest first.\n *\n * @param limit - Maximum number of entries to return. Defaults to `20`.\n * @returns Array of {@link HistoryEntry} objects in reverse-chronological order.\n */\n history(limit = 20): HistoryEntry[] {\n return getRecentHistory(this.projectDir, limit);\n }\n\n /**\n * Erase all asset action history for this workspace.\n */\n clearHistory(): void {\n clearHistory(this.projectDir);\n }\n\n // ── Clean ───────────────────────────────────────────────────────────────\n\n /**\n * Remove deployed assets tracked by the lock file and report unmanaged ones.\n *\n * With `opts.all`, also deletes `.skaile/history.yaml`, `.skaile/patches/`,\n * `.skaile/repos/`, and `skaile.lock.yaml` — effectively resetting the workspace\n * to a pre-install state.\n *\n * @param opts - Optional cleanup options.\n * @param opts.all - When `true`, remove all Skaile-managed state in addition to deployed assets.\n * @returns Object with `removed` (successfully cleaned refs), `skipped` (with reasons),\n * and `unmanaged` (deployed assets not in the lock file).\n */\n clean(opts?: { all?: boolean }): {\n removed: string[];\n skipped: Array<{ ref: string; reason: string }>;\n unmanaged: string[];\n } {\n const lock = this.tryReadLock();\n const removed: string[] = [];\n const skipped: Array<{ ref: string; reason: string }> = [];\n\n if (lock) {\n for (const ref of Object.keys(lock.assets)) {\n const { kind, name } = parseCanonicalLockKey(ref);\n if (!kind || !name) continue;\n const dest = deployedDir(\n kind as AiComponent,\n name,\n this.driverTarget,\n this.global,\n this.projectDir,\n );\n\n try {\n const stat = lstatSync(dest);\n if (stat.isSymbolicLink()) unlinkSync(dest);\n else rmSync(dest, { recursive: true, force: true });\n removed.push(ref);\n } catch {\n // Already gone — count as removed\n removed.push(ref);\n }\n }\n }\n\n // Collect unmanaged assets for reporting. Deployed assets are keyed by\n // <kind>:<name>; map lock canonical refs to that shape for comparison.\n const lockRefs = lock\n ? new Set(\n Object.keys(lock.assets).map((r) => {\n const p = parseCanonicalLockKey(r);\n return p.kind && p.name ? `${p.kind}:${p.name}` : r;\n }),\n )\n : new Set<string>();\n const unmanaged: string[] = [];\n const allDeployed = this.listDeployed();\n for (const d of allDeployed) {\n const ref = `${d.kind}:${d.name}`;\n if (!lockRefs.has(ref)) {\n unmanaged.push(ref);\n }\n }\n\n if (opts?.all) {\n // Delete history file\n const historyFile = join(this.projectDir, \".skaile\", \"history.yaml\");\n try {\n unlinkSync(historyFile);\n } catch {}\n\n // Remove patches dir\n try {\n rmSync(this.patchDir, { recursive: true, force: true });\n } catch {}\n\n // Remove repos dir\n try {\n rmSync(this.reposDir, { recursive: true, force: true });\n } catch {}\n\n // Remove lock file\n try {\n unlinkSync(this.lockPath);\n } catch {}\n }\n\n return { removed, skipped, unmanaged };\n }\n\n // ── Helpers ────────────────────────────────────────────────────────────\n\n /** Add a dependency ref to skaile.yaml if not already present. */\n private addDependencyToConfig(ref: string): void {\n if (this.global) return; // global installs don't modify skaile.yaml\n const configPath = join(this.projectDir, \"skaile.yaml\");\n if (!existsSync(configPath)) return;\n const raw = parseYaml(readFileSync(configPath, \"utf8\")) ?? {};\n if (!raw.dependencies) raw.dependencies = [];\n if (!raw.dependencies.includes(ref)) {\n raw.dependencies.push(ref);\n writeFileSync(configPath, stringifyYaml(raw, { lineWidth: 120 }));\n }\n }\n\n /** Remove a dependency ref from skaile.yaml. */\n private removeDependencyFromConfig(ref: string): void {\n if (this.global) return;\n const configPath = join(this.projectDir, \"skaile.yaml\");\n if (!existsSync(configPath)) return;\n const raw = parseYaml(readFileSync(configPath, \"utf8\")) ?? {};\n if (!raw.dependencies) return;\n const idx = raw.dependencies.indexOf(ref);\n if (idx !== -1) {\n raw.dependencies.splice(idx, 1);\n writeFileSync(configPath, stringifyYaml(raw, { lineWidth: 120 }));\n }\n }\n\n private resolveRepoDir(decl: SourceDeclaration, name: string): string | null {\n // Check links first\n const links = readLinks(this.projectDir);\n if (links[name]) {\n return existsSync(links[name]) ? links[name] : null;\n }\n\n if (decl.path) {\n const resolved = resolve(this.projectDir, decl.path);\n return existsSync(resolved) ? resolved : null;\n }\n\n // Check project-local symlink, then global cache\n const dest = join(this.reposDir, name);\n if (existsSync(dest)) return dest;\n\n const globalDest = join(getGlobalCacheDir(), name);\n if (existsSync(join(globalDest, \".git\"))) return globalDest;\n\n return null;\n }\n}\n\n// ── Agent install (renders GitAgent packages to framework-native files) ──\n\nexport { installAgent } from \"./install-agent.js\";\n\n// ── Renderers ─────────────────────────────────────────────────────────────\n\nexport type { AgentRenderer, AgentRenderInput, AgentRenderResult } from \"./renderers.js\";\nexport {\n AGENT_RENDERERS,\n claudeCodeRenderer,\n codexRenderer,\n driverTargetSupportsAgents,\n ompRenderer,\n} from \"./renderers.js\";\n\n// ── Fragments ─────────────────────────────────────────────────────────────\n\nexport type {\n AbilityRef,\n ConnectorRef,\n ContractRef,\n FragmentContext,\n FragmentId,\n} from \"./fragments.js\";\nexport { BUILT_IN_FRAGMENTS, loadPromptExtensions, resolveFragments } from \"./fragments.js\";\n"]}
@@ -87,7 +87,24 @@ var SkillMetadataSchema = CommonMetadataSchema.extend({
87
87
  prerequisites: z.object({
88
88
  files: z.array(FilePrerequisiteSchema).optional(),
89
89
  inputs_required: z.array(UserInputSchema).optional(),
90
- inputs_optional: z.array(UserInputSchema).optional()
90
+ inputs_optional: z.array(UserInputSchema).optional(),
91
+ // Parsed by the resolver's parseSkillRequirements; Zod would strip them otherwise.
92
+ reads: z.array(z.object({ path: z.string(), description: z.string().optional() })).optional(),
93
+ produces: z.array(z.object({ path: z.string(), description: z.string().optional() })).optional(),
94
+ resources: z.array(
95
+ z.object({
96
+ id: z.string(),
97
+ operations: z.array(z.string()).optional(),
98
+ optional: z.boolean().optional(),
99
+ description: z.string().optional()
100
+ })
101
+ ).optional(),
102
+ connectors: z.array(
103
+ z.object({
104
+ driver: z.string(),
105
+ access: z.enum(["read-only", "read-write"]).optional()
106
+ })
107
+ ).optional()
91
108
  }).optional(),
92
109
  produces: z.array(z.object({ path: z.string(), description: z.string().optional() })).optional()
93
110
  });
@@ -339,5 +356,5 @@ function validateByKind(kind, data) {
339
356
  }
340
357
 
341
358
  export { ANTHROPIC_FULL_ID_PATTERN, ANTHROPIC_MODEL_ALIASES, AgentComposeItemSchema, AgentManifestSchema, ArtifactRefSchema, AssetKindSchema, AssetKindValues, BaseFrontmatterSchema, BindingSchema, BindingValues, CommonMetadataSchema, ConnectorManifestSchema, ContractManifestSchema, FieldSchema, FilePrerequisiteSchema, McpServerManifestSchema, ModelIdSchema, MountManifestSchema, PersonaManifestSchema, PlaceholderSchema, PlaceholderTypeSchema, PresetItemSchema, PresetManifestSchema, PromptManifestSchema, RulesetManifestSchema, SkillManifestSchema, UserInputSchema, normalizeAnthropicModel, validateAgent, validateByKind, validateConnector, validateContract, validateManifest, validateMcpServer, validateMount, validatePersona, validatePreset, validatePrompt, validateRuleset, validateSkill };
342
- //# sourceMappingURL=chunk-NELZIQ2E.js.map
343
- //# sourceMappingURL=chunk-NELZIQ2E.js.map
359
+ //# sourceMappingURL=chunk-QDJKE557.js.map
360
+ //# sourceMappingURL=chunk-QDJKE557.js.map