@skaile/workspaces 5.5.0 → 5.6.1

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 (423) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-KTFUB7EX.js → asset-feeds-LU7NHOAP.js} +27 -14
  4. package/dist/asset-feeds-LU7NHOAP.js.map +1 -0
  5. package/dist/asset-manager/catalog-deployer.js +9 -9
  6. package/dist/asset-manager/index.js +18 -18
  7. package/dist/asset-manager/installer.js +11 -11
  8. package/dist/asset-manager/renderers.js +20 -2
  9. package/dist/asset-manager/src/index.d.ts +66 -24
  10. package/dist/asset-manager/src/index.d.ts.map +1 -1
  11. package/dist/asset-manager/src/install-agent.d.ts +22 -14
  12. package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
  13. package/dist/asset-manager/src/install-instances.d.ts +55 -0
  14. package/dist/asset-manager/src/install-instances.d.ts.map +1 -0
  15. package/dist/asset-manager/src/installer.d.ts +30 -7
  16. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  17. package/dist/asset-manager/src/renderers.d.ts +29 -8
  18. package/dist/asset-manager/src/renderers.d.ts.map +1 -1
  19. package/dist/bridge/drivers/claude-sdk.js +14 -14
  20. package/dist/bridge/drivers/codex.js +20 -14
  21. package/dist/bridge/drivers/codex.js.map +1 -1
  22. package/dist/bridge/drivers/continue.js +11 -11
  23. package/dist/bridge/drivers/echo.js +3 -3
  24. package/dist/bridge/drivers/gemini.js +6 -6
  25. package/dist/bridge/drivers/goose.js +11 -11
  26. package/dist/bridge/drivers/omp.js +4 -4
  27. package/dist/bridge/drivers/opencode.js +11 -11
  28. package/dist/bridge/drivers/qwen.js +6 -6
  29. package/dist/bridge/index.js +15 -15
  30. package/dist/bridge/src/codex/native-policy.d.ts +1 -1
  31. package/dist/bridge/src/drivers/codex.d.ts +2 -1
  32. package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
  33. package/dist/{chunk-LCULZ4ED.js → chunk-27HS2DHB.js} +4 -4
  34. package/dist/{chunk-LCULZ4ED.js.map → chunk-27HS2DHB.js.map} +1 -1
  35. package/dist/{chunk-X4GO3GJZ.js → chunk-2GRB5ITE.js} +4 -4
  36. package/dist/{chunk-X4GO3GJZ.js.map → chunk-2GRB5ITE.js.map} +1 -1
  37. package/dist/{chunk-75EX5GY4.js → chunk-2KOKBTR4.js} +197 -118
  38. package/dist/chunk-2KOKBTR4.js.map +1 -0
  39. package/dist/{chunk-ES2FXWQ4.js → chunk-2NYXQYHN.js} +4 -4
  40. package/dist/{chunk-ES2FXWQ4.js.map → chunk-2NYXQYHN.js.map} +1 -1
  41. package/dist/{chunk-ORUHADS6.js → chunk-2W4LBLIN.js} +386 -60
  42. package/dist/chunk-2W4LBLIN.js.map +1 -0
  43. package/dist/{chunk-SNVOASTL.js → chunk-2XFUXGV6.js} +3 -3
  44. package/dist/{chunk-SNVOASTL.js.map → chunk-2XFUXGV6.js.map} +1 -1
  45. package/dist/{chunk-ZDKJHQY2.js → chunk-3TXEJN4W.js} +2 -2
  46. package/dist/{chunk-ZDKJHQY2.js.map → chunk-3TXEJN4W.js.map} +1 -1
  47. package/dist/{chunk-JELTQ4H7.js → chunk-45VFGT7A.js} +3 -3
  48. package/dist/{chunk-JELTQ4H7.js.map → chunk-45VFGT7A.js.map} +1 -1
  49. package/dist/{chunk-XGIS325V.js → chunk-46OVMT76.js} +3 -3
  50. package/dist/{chunk-XGIS325V.js.map → chunk-46OVMT76.js.map} +1 -1
  51. package/dist/{chunk-37GBJLF5.js → chunk-47ZD34KB.js} +3 -3
  52. package/dist/{chunk-37GBJLF5.js.map → chunk-47ZD34KB.js.map} +1 -1
  53. package/dist/{chunk-LFEGIZTW.js → chunk-4GNJELPH.js} +2 -2
  54. package/dist/{chunk-LFEGIZTW.js.map → chunk-4GNJELPH.js.map} +1 -1
  55. package/dist/{chunk-V7VDSFPS.js → chunk-5B5IZVEP.js} +2 -2
  56. package/dist/{chunk-V7VDSFPS.js.map → chunk-5B5IZVEP.js.map} +1 -1
  57. package/dist/{chunk-EJYZ3MKJ.js → chunk-65EYRFZJ.js} +4 -4
  58. package/dist/{chunk-EJYZ3MKJ.js.map → chunk-65EYRFZJ.js.map} +1 -1
  59. package/dist/{chunk-CODXK5L5.js → chunk-6NPINANG.js} +6 -6
  60. package/dist/{chunk-CODXK5L5.js.map → chunk-6NPINANG.js.map} +1 -1
  61. package/dist/{chunk-XBM5ND55.js → chunk-7KLC4LZO.js} +8 -8
  62. package/dist/{chunk-XBM5ND55.js.map → chunk-7KLC4LZO.js.map} +1 -1
  63. package/dist/{chunk-SR4RFKHM.js → chunk-7ZHLYXTI.js} +3 -3
  64. package/dist/{chunk-SR4RFKHM.js.map → chunk-7ZHLYXTI.js.map} +1 -1
  65. package/dist/{chunk-WX74MVNA.js → chunk-AO7VJ6G6.js} +3 -24
  66. package/dist/chunk-AO7VJ6G6.js.map +1 -0
  67. package/dist/{chunk-DPMKI26Y.js → chunk-AOAZCSDI.js} +4 -3
  68. package/dist/chunk-AOAZCSDI.js.map +1 -0
  69. package/dist/{chunk-YK7WJSTD.js → chunk-BF33SCLY.js} +10 -5
  70. package/dist/chunk-BF33SCLY.js.map +1 -0
  71. package/dist/{chunk-VKSA2CDJ.js → chunk-BTISGSK4.js} +4 -4
  72. package/dist/{chunk-VKSA2CDJ.js.map → chunk-BTISGSK4.js.map} +1 -1
  73. package/dist/{chunk-TOSHZX4C.js → chunk-CPSIPIX7.js} +2 -2
  74. package/dist/chunk-CPSIPIX7.js.map +1 -0
  75. package/dist/{chunk-5Y3L7XWH.js → chunk-D2V42LUE.js} +15 -15
  76. package/dist/chunk-D2V42LUE.js.map +1 -0
  77. package/dist/{chunk-K2K7OF4P.js → chunk-DMLDYFDS.js} +23 -6
  78. package/dist/chunk-DMLDYFDS.js.map +1 -0
  79. package/dist/{chunk-QMWMSZQ4.js → chunk-FK6HPLQA.js} +3 -3
  80. package/dist/{chunk-QMWMSZQ4.js.map → chunk-FK6HPLQA.js.map} +1 -1
  81. package/dist/chunk-FRHE7FFB.js +655 -0
  82. package/dist/chunk-FRHE7FFB.js.map +1 -0
  83. package/dist/{chunk-UFS3FEBA.js → chunk-GP6ZL7PE.js} +3 -3
  84. package/dist/{chunk-UFS3FEBA.js.map → chunk-GP6ZL7PE.js.map} +1 -1
  85. package/dist/{chunk-P6KFWTGP.js → chunk-I4QBZLOR.js} +7 -12
  86. package/dist/chunk-I4QBZLOR.js.map +1 -0
  87. package/dist/{chunk-C4GF7RSQ.js → chunk-KUFNKVBM.js} +3 -3
  88. package/dist/{chunk-C4GF7RSQ.js.map → chunk-KUFNKVBM.js.map} +1 -1
  89. package/dist/{chunk-GCYD4EGY.js → chunk-KYXOGHY6.js} +4 -4
  90. package/dist/{chunk-GCYD4EGY.js.map → chunk-KYXOGHY6.js.map} +1 -1
  91. package/dist/{chunk-G474PBUQ.js → chunk-LLKKLKZJ.js} +3 -3
  92. package/dist/{chunk-G474PBUQ.js.map → chunk-LLKKLKZJ.js.map} +1 -1
  93. package/dist/{chunk-AC2N5BRP.js → chunk-MX3UQXLU.js} +18 -30
  94. package/dist/chunk-MX3UQXLU.js.map +1 -0
  95. package/dist/{chunk-BNUZEYC3.js → chunk-NARITJS2.js} +3 -3
  96. package/dist/{chunk-BNUZEYC3.js.map → chunk-NARITJS2.js.map} +1 -1
  97. package/dist/{chunk-Y4QWHIHB.js → chunk-OGLDAJFL.js} +4 -4
  98. package/dist/{chunk-Y4QWHIHB.js.map → chunk-OGLDAJFL.js.map} +1 -1
  99. package/dist/chunk-OLLAQLFJ.js +17 -0
  100. package/dist/chunk-OLLAQLFJ.js.map +1 -0
  101. package/dist/{chunk-LFMX2UEF.js → chunk-PA7WLID3.js} +86 -69
  102. package/dist/chunk-PA7WLID3.js.map +1 -0
  103. package/dist/{chunk-K2NUT3HO.js → chunk-PJS2YWGG.js} +6 -6
  104. package/dist/{chunk-K2NUT3HO.js.map → chunk-PJS2YWGG.js.map} +1 -1
  105. package/dist/{chunk-MMC24L2W.js → chunk-PTO2YDDG.js} +286 -121
  106. package/dist/chunk-PTO2YDDG.js.map +1 -0
  107. package/dist/{chunk-3665M43C.js → chunk-QD772CGQ.js} +5 -5
  108. package/dist/{chunk-3665M43C.js.map → chunk-QD772CGQ.js.map} +1 -1
  109. package/dist/{chunk-G2O2AARG.js → chunk-RGXVQZOV.js} +6021 -3099
  110. package/dist/chunk-RGXVQZOV.js.map +1 -0
  111. package/dist/{chunk-JKWU6ULI.js → chunk-SDFROXSA.js} +3 -3
  112. package/dist/{chunk-JKWU6ULI.js.map → chunk-SDFROXSA.js.map} +1 -1
  113. package/dist/{chunk-WHSQSVN2.js → chunk-SX4UIDKT.js} +3 -3
  114. package/dist/{chunk-WHSQSVN2.js.map → chunk-SX4UIDKT.js.map} +1 -1
  115. package/dist/{chunk-3JHFFIQ6.js → chunk-TZCQ7ZWQ.js} +83 -9
  116. package/dist/chunk-TZCQ7ZWQ.js.map +1 -0
  117. package/dist/{chunk-UHLBDAJR.js → chunk-UAP2XHRF.js} +10 -10
  118. package/dist/{chunk-UHLBDAJR.js.map → chunk-UAP2XHRF.js.map} +1 -1
  119. package/dist/{chunk-LAI7X6I2.js → chunk-VBBBZDI7.js} +3 -3
  120. package/dist/{chunk-LAI7X6I2.js.map → chunk-VBBBZDI7.js.map} +1 -1
  121. package/dist/{chunk-R4G7XI7A.js → chunk-VJENKWXF.js} +4 -5
  122. package/dist/chunk-VJENKWXF.js.map +1 -0
  123. package/dist/{chunk-TNWXGHLD.js → chunk-VKSXST23.js} +51 -42
  124. package/dist/chunk-VKSXST23.js.map +1 -0
  125. package/dist/{chunk-HTKZ4AOW.js → chunk-VSQFGU5D.js} +3 -3
  126. package/dist/{chunk-HTKZ4AOW.js.map → chunk-VSQFGU5D.js.map} +1 -1
  127. package/dist/{chunk-JBPG5KQC.js → chunk-VX3INFBA.js} +4 -4
  128. package/dist/{chunk-JBPG5KQC.js.map → chunk-VX3INFBA.js.map} +1 -1
  129. package/dist/{chunk-N3Y43LMZ.js → chunk-WIHQWVWL.js} +34 -11
  130. package/dist/chunk-WIHQWVWL.js.map +1 -0
  131. package/dist/{chunk-Y7UBRRKG.js → chunk-XOGG7VDZ.js} +40 -31
  132. package/dist/chunk-XOGG7VDZ.js.map +1 -0
  133. package/dist/{chunk-JAJG4G5E.js → chunk-ZBBM6O6P.js} +3 -3
  134. package/dist/{chunk-JAJG4G5E.js.map → chunk-ZBBM6O6P.js.map} +1 -1
  135. package/dist/cli/index.js +5025 -3406
  136. package/dist/cli/index.js.map +1 -1
  137. package/dist/cli/src/asset-feeds.d.ts.map +1 -1
  138. package/dist/cli/src/commands/catalog.d.ts +7 -7
  139. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  140. package/dist/cli/src/commands/connector.d.ts +2 -2
  141. package/dist/cli/src/commands/connector.d.ts.map +1 -1
  142. package/dist/cli/src/commands/diff.d.ts.map +1 -1
  143. package/dist/cli/src/commands/history.d.ts.map +1 -1
  144. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  145. package/dist/cli/src/commands/manage.d.ts.map +1 -1
  146. package/dist/cli/src/commands/migrate-agents.d.ts +131 -0
  147. package/dist/cli/src/commands/migrate-agents.d.ts.map +1 -0
  148. package/dist/cli/src/commands/migrate-assets.d.ts +54 -0
  149. package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -0
  150. package/dist/cli/src/commands/migrate-files.d.ts +52 -0
  151. package/dist/cli/src/commands/migrate-files.d.ts.map +1 -0
  152. package/dist/cli/src/commands/migrate-providers.d.ts +5 -8
  153. package/dist/cli/src/commands/migrate-providers.d.ts.map +1 -1
  154. package/dist/cli/src/commands/migrate.d.ts +21 -0
  155. package/dist/cli/src/commands/migrate.d.ts.map +1 -0
  156. package/dist/cli/src/commands/npx.d.ts.map +1 -1
  157. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  158. package/dist/cli/src/commands/patch.d.ts.map +1 -1
  159. package/dist/cli/src/commands/preset-cmd.d.ts.map +1 -1
  160. package/dist/cli/src/commands/project.d.ts +13 -1
  161. package/dist/cli/src/commands/project.d.ts.map +1 -1
  162. package/dist/cli/src/commands/rebuild.d.ts.map +1 -1
  163. package/dist/cli/src/commands/run.d.ts.map +1 -1
  164. package/dist/cli/src/commands/show.d.ts.map +1 -1
  165. package/dist/cli/src/commands/tree.d.ts.map +1 -1
  166. package/dist/cli/src/commands/update.d.ts.map +1 -1
  167. package/dist/cli/src/commands/validate-instances.d.ts +17 -0
  168. package/dist/cli/src/commands/validate-instances.d.ts.map +1 -0
  169. package/dist/cli/src/commands/validate.d.ts +14 -0
  170. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  171. package/dist/cli/src/commands/why.d.ts.map +1 -1
  172. package/dist/cli/src/helpers.d.ts.map +1 -1
  173. package/dist/cli/src/open-library.d.ts.map +1 -1
  174. package/dist/cli/src/open-registry.d.ts +13 -16
  175. package/dist/cli/src/open-registry.d.ts.map +1 -1
  176. package/dist/cli/src/type-guards.d.ts +3 -0
  177. package/dist/cli/src/type-guards.d.ts.map +1 -0
  178. package/dist/connectors/config.js +6 -6
  179. package/dist/connectors/index.js +19 -19
  180. package/dist/{connectors-MPYCSQNG.js → connectors-HWENZFKW.js} +22 -22
  181. package/dist/{connectors-MPYCSQNG.js.map → connectors-HWENZFKW.js.map} +1 -1
  182. package/dist/connectors-shared/index.js +2 -2
  183. package/dist/core/driver-targets.js +1 -1
  184. package/dist/core/index.js +8 -8
  185. package/dist/core/manifest.js +2 -2
  186. package/dist/core/models.js +1 -1
  187. package/dist/core/publish-manifest.js +2 -2
  188. package/dist/core/ref.js +1 -1
  189. package/dist/core/runtime-assets.js +6 -6
  190. package/dist/core/src/agent-instances.d.ts +93 -0
  191. package/dist/core/src/agent-instances.d.ts.map +1 -0
  192. package/dist/core/src/agent-prompt-sections.d.ts +90 -0
  193. package/dist/core/src/agent-prompt-sections.d.ts.map +1 -0
  194. package/dist/core/src/driver-targets.d.ts +4 -2
  195. package/dist/core/src/driver-targets.d.ts.map +1 -1
  196. package/dist/core/src/index.d.ts +12 -8
  197. package/dist/core/src/index.d.ts.map +1 -1
  198. package/dist/core/src/manifest.d.ts +71 -27
  199. package/dist/core/src/manifest.d.ts.map +1 -1
  200. package/dist/core/src/models.d.ts +6 -92
  201. package/dist/core/src/models.d.ts.map +1 -1
  202. package/dist/core/src/repo-manager.d.ts +47 -3
  203. package/dist/core/src/repo-manager.d.ts.map +1 -1
  204. package/dist/core/src/type-guards.d.ts +3 -0
  205. package/dist/core/src/type-guards.d.ts.map +1 -0
  206. package/dist/core/src/walker.d.ts +7 -3
  207. package/dist/core/src/walker.d.ts.map +1 -1
  208. package/dist/core/src/workspace-config.d.ts +19 -15
  209. package/dist/core/src/workspace-config.d.ts.map +1 -1
  210. package/dist/core/store.js +2 -2
  211. package/dist/core/workspace-config.js +5 -5
  212. package/dist/deploy/index.js +8 -8
  213. package/dist/discovery/index.js +6 -6
  214. package/dist/discovery/src/builtin-providers.d.ts +5 -4
  215. package/dist/discovery/src/builtin-providers.d.ts.map +1 -1
  216. package/dist/discovery/src/default-registry.d.ts +23 -0
  217. package/dist/discovery/src/default-registry.d.ts.map +1 -0
  218. package/dist/discovery/src/discover.d.ts +0 -6
  219. package/dist/discovery/src/discover.d.ts.map +1 -1
  220. package/dist/discovery/src/index.d.ts +2 -1
  221. package/dist/discovery/src/index.d.ts.map +1 -1
  222. package/dist/discovery/src/tree-entries.d.ts +1 -1
  223. package/dist/discovery/src/tree-entries.d.ts.map +1 -1
  224. package/dist/{ensure-sources-QFRA46DJ.js → ensure-sources-DSTSXJWK.js} +21 -21
  225. package/dist/{ensure-sources-QFRA46DJ.js.map → ensure-sources-DSTSXJWK.js.map} +1 -1
  226. package/dist/factory-assets/README.md +3 -3
  227. package/dist/factory-assets/connectors/box.js +19 -19
  228. package/dist/factory-assets/connectors/deploy.js +19 -19
  229. package/dist/factory-assets/connectors/devserver.js +19 -19
  230. package/dist/factory-assets/connectors/flow/adapter.js +19 -19
  231. package/dist/factory-assets/connectors/flow/engine/flow-kind-provider.d.ts.map +1 -1
  232. package/dist/factory-assets/connectors/flow/engine.js +9 -9
  233. package/dist/factory-assets/connectors/flow/run-flow.js +21 -21
  234. package/dist/factory-assets/connectors/flow.js +19 -19
  235. package/dist/factory-assets/connectors/git.js +19 -19
  236. package/dist/factory-assets/connectors/gmail.js +19 -19
  237. package/dist/factory-assets/connectors/googledrive.js +19 -19
  238. package/dist/factory-assets/connectors/local.js +19 -19
  239. package/dist/factory-assets/connectors/mattermost.js +19 -19
  240. package/dist/factory-assets/connectors/memory.js +19 -19
  241. package/dist/factory-assets/connectors/minio.js +19 -19
  242. package/dist/factory-assets/connectors/postgres.js +19 -19
  243. package/dist/factory-assets/connectors/s3.js +19 -19
  244. package/dist/factory-assets/connectors/sharepoint.js +19 -19
  245. package/dist/factory-assets/connectors/sqlite.js +19 -19
  246. package/dist/factory-assets/connectors/static-server.js +19 -19
  247. package/dist/factory-assets/connectors/tunnel.js +19 -19
  248. package/dist/factory-assets/connectors/webdav.js +19 -19
  249. package/dist/factory-assets/connectors/xstate-store.js +19 -19
  250. package/dist/factory-assets/connectors/xstate.js +19 -19
  251. package/dist/factory-assets/index.js.map +1 -1
  252. package/dist/factory-assets/presets/workspaces-authoring/workspaces-authoring.preset.yaml +9 -0
  253. package/dist/factory-assets/skaile.manifest.yaml +2 -2
  254. package/dist/factory-assets/skills/authoring-skaile-assets/SKILL.md +16 -12
  255. package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +8 -8
  256. package/dist/factory-assets/skills/authoring-skaile-manifests/references/dependency-standard.md +13 -11
  257. package/dist/factory-assets/skills/skaile-manage-workspace/SKILL.md +1 -1
  258. package/dist/{flows-KCARGXRT.js → flows-ENQY2DV7.js} +13 -13
  259. package/dist/{flows-KCARGXRT.js.map → flows-ENQY2DV7.js.map} +1 -1
  260. package/dist/{helpers-PSROT7CU.js → helpers-R44RUTDY.js} +21 -21
  261. package/dist/{helpers-PSROT7CU.js.map → helpers-R44RUTDY.js.map} +1 -1
  262. package/dist/library/index.js +13 -13
  263. package/dist/library/install.js +3 -3
  264. package/dist/library/src/index.d.ts +2 -2
  265. package/dist/library/src/index.d.ts.map +1 -1
  266. package/dist/library/src/library.d.ts +2 -12
  267. package/dist/library/src/library.d.ts.map +1 -1
  268. package/dist/library/src/local/local-catalog-source.d.ts +2 -2
  269. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  270. package/dist/library/src/manifest-writer.d.ts +4 -1
  271. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  272. package/dist/library/src/sync/manifest-writeback.d.ts.map +1 -1
  273. package/dist/{library-publish-YAI7WOXC.js → library-publish-LFOJJVMK.js} +27 -27
  274. package/dist/{library-publish-YAI7WOXC.js.map → library-publish-LFOJJVMK.js.map} +1 -1
  275. package/dist/open-library-4WUMQHES.js +40 -0
  276. package/dist/{open-library-Z5NJU4Z5.js.map → open-library-4WUMQHES.js.map} +1 -1
  277. package/dist/open-registry-NVPCQPND.js +32 -0
  278. package/dist/{open-registry-TYUVN5SG.js.map → open-registry-NVPCQPND.js.map} +1 -1
  279. package/dist/paths-YUCP7K6U.js +22 -0
  280. package/dist/{paths-HKAXUR3W.js.map → paths-YUCP7K6U.js.map} +1 -1
  281. package/dist/{plugin-store-N6SI2TYM.js → plugin-store-66QFBNEO.js} +10 -10
  282. package/dist/{plugin-store-N6SI2TYM.js.map → plugin-store-66QFBNEO.js.map} +1 -1
  283. package/dist/plugins/index.js +1 -1
  284. package/dist/plugins/src/asset-kind-provider.d.ts +14 -2
  285. package/dist/plugins/src/asset-kind-provider.d.ts.map +1 -1
  286. package/dist/plugins/src/index.d.ts +1 -1
  287. package/dist/plugins/src/index.d.ts.map +1 -1
  288. package/dist/project-VMOHUXBD.js +41 -0
  289. package/dist/{project-SVS4UMGL.js.map → project-VMOHUXBD.js.map} +1 -1
  290. package/dist/resolver/index.js +9 -9
  291. package/dist/runner/index.js +34 -29
  292. package/dist/runner/src/agent-capabilities.d.ts +101 -0
  293. package/dist/runner/src/agent-capabilities.d.ts.map +1 -0
  294. package/dist/runner/src/agent.d.ts.map +1 -1
  295. package/dist/runner/src/agents/in-process-host.d.ts +56 -0
  296. package/dist/runner/src/agents/in-process-host.d.ts.map +1 -0
  297. package/dist/runner/src/agents/instances.d.ts +62 -0
  298. package/dist/runner/src/agents/instances.d.ts.map +1 -0
  299. package/dist/runner/src/agents/json-schema.d.ts +16 -0
  300. package/dist/runner/src/agents/json-schema.d.ts.map +1 -0
  301. package/dist/runner/src/agents/memory-run-store.d.ts +19 -0
  302. package/dist/runner/src/agents/memory-run-store.d.ts.map +1 -0
  303. package/dist/runner/src/agents/run-controller.d.ts +208 -0
  304. package/dist/runner/src/agents/run-controller.d.ts.map +1 -0
  305. package/dist/runner/src/agents/standalone-surface.d.ts +30 -0
  306. package/dist/runner/src/agents/standalone-surface.d.ts.map +1 -0
  307. package/dist/runner/src/capability-registry.d.ts.map +1 -1
  308. package/dist/runner/src/composition/bootstrap.d.ts +13 -51
  309. package/dist/runner/src/composition/bootstrap.d.ts.map +1 -1
  310. package/dist/runner/src/composition/compile.d.ts +43 -27
  311. package/dist/runner/src/composition/compile.d.ts.map +1 -1
  312. package/dist/runner/src/composition/content-source.d.ts +94 -0
  313. package/dist/runner/src/composition/content-source.d.ts.map +1 -0
  314. package/dist/runner/src/composition/dry-run.d.ts +34 -0
  315. package/dist/runner/src/composition/dry-run.d.ts.map +1 -0
  316. package/dist/runner/src/composition/errors.d.ts +41 -0
  317. package/dist/runner/src/composition/errors.d.ts.map +1 -0
  318. package/dist/runner/src/composition/index.d.ts +10 -3
  319. package/dist/runner/src/composition/index.d.ts.map +1 -1
  320. package/dist/runner/src/composition/prompt-sections.d.ts +31 -0
  321. package/dist/runner/src/composition/prompt-sections.d.ts.map +1 -0
  322. package/dist/runner/src/composition/resolve-instance.d.ts +140 -0
  323. package/dist/runner/src/composition/resolve-instance.d.ts.map +1 -0
  324. package/dist/runner/src/composition/resolve.d.ts +43 -25
  325. package/dist/runner/src/composition/resolve.d.ts.map +1 -1
  326. package/dist/runner/src/composition/revision-hash.d.ts +58 -0
  327. package/dist/runner/src/composition/revision-hash.d.ts.map +1 -0
  328. package/dist/runner/src/composition/run-snapshot.d.ts +37 -0
  329. package/dist/runner/src/composition/run-snapshot.d.ts.map +1 -0
  330. package/dist/runner/src/composition/types.d.ts +79 -12
  331. package/dist/runner/src/composition/types.d.ts.map +1 -1
  332. package/dist/runner/src/index.d.ts +2 -0
  333. package/dist/runner/src/index.d.ts.map +1 -1
  334. package/dist/runner/src/manifest.d.ts +1 -1
  335. package/dist/runner/src/manifest.d.ts.map +1 -1
  336. package/dist/runner/src/mixin-resolver.d.ts +14 -15
  337. package/dist/runner/src/mixin-resolver.d.ts.map +1 -1
  338. package/dist/runner/src/serve.d.ts +6 -0
  339. package/dist/runner/src/serve.d.ts.map +1 -1
  340. package/dist/runner/src/session-builder.d.ts +35 -6
  341. package/dist/runner/src/session-builder.d.ts.map +1 -1
  342. package/dist/sdk/asset-manager.js +18 -18
  343. package/dist/sdk/bridge.js +15 -15
  344. package/dist/sdk/core.js +8 -8
  345. package/dist/sdk/flow.js +9 -9
  346. package/dist/sdk/index.js +34 -29
  347. package/dist/sdk/index.js.map +1 -1
  348. package/dist/sdk/resolver.js +9 -9
  349. package/dist/sdk/runner.js +34 -29
  350. package/dist/sdk/session.js +2 -2
  351. package/dist/sdk/types.js +1 -1
  352. package/dist/secrets/index.js +2 -2
  353. package/dist/session/index.js +2 -2
  354. package/dist/{setup-IOEZGJNC.js → setup-PYY23HGZ.js} +28 -28
  355. package/dist/{setup-IOEZGJNC.js.map → setup-PYY23HGZ.js.map} +1 -1
  356. package/dist/skills-CS7NE5TT.js +26 -0
  357. package/dist/{skills-HW6I6ZZ7.js.map → skills-CS7NE5TT.js.map} +1 -1
  358. package/dist/source-JCF6KSQN.js +41 -0
  359. package/dist/{source-OKRJT53H.js.map → source-JCF6KSQN.js.map} +1 -1
  360. package/dist/{source-manifest-publish-MILEQDRD.js → source-manifest-publish-O6P7G2M7.js} +27 -27
  361. package/dist/{source-manifest-publish-MILEQDRD.js.map → source-manifest-publish-O6P7G2M7.js.map} +1 -1
  362. package/dist/tui/index.js +34 -29
  363. package/dist/tui/index.js.map +1 -1
  364. package/dist/types/index.js +1 -1
  365. package/dist/types/manifests.js +1 -1
  366. package/dist/types/src/agent-lifecycle.d.ts +402 -0
  367. package/dist/types/src/agent-lifecycle.d.ts.map +1 -0
  368. package/dist/types/src/capabilities.d.ts +0 -4
  369. package/dist/types/src/capabilities.d.ts.map +1 -1
  370. package/dist/types/src/delivery.d.ts.map +1 -1
  371. package/dist/types/src/events.d.ts +66 -4
  372. package/dist/types/src/events.d.ts.map +1 -1
  373. package/dist/types/src/index.d.ts +3 -1
  374. package/dist/types/src/index.d.ts.map +1 -1
  375. package/dist/types/src/lifecycle.d.ts +21 -3
  376. package/dist/types/src/lifecycle.d.ts.map +1 -1
  377. package/dist/types/src/manifests/_shared.d.ts +1 -16
  378. package/dist/types/src/manifests/_shared.d.ts.map +1 -1
  379. package/dist/types/src/manifests/agent-composition.d.ts +44 -0
  380. package/dist/types/src/manifests/agent-composition.d.ts.map +1 -0
  381. package/dist/types/src/manifests/agent.d.ts +184 -6
  382. package/dist/types/src/manifests/agent.d.ts.map +1 -1
  383. package/dist/types/src/manifests/index.d.ts +6 -15
  384. package/dist/types/src/manifests/index.d.ts.map +1 -1
  385. package/dist/types/src/manifests/preset.d.ts +5 -5
  386. package/dist/types/src/version.d.ts +16 -1
  387. package/dist/types/src/version.d.ts.map +1 -1
  388. package/dist/workspace-plugin/adapters/mcp.js +26 -26
  389. package/dist/workspace-plugin/adapters/omp.js +14 -14
  390. package/dist/workspace-plugin/index.js +1 -1
  391. package/package.json +3 -1
  392. package/dist/asset-feeds-KTFUB7EX.js.map +0 -1
  393. package/dist/chunk-2D2P7HSR.js +0 -15
  394. package/dist/chunk-2D2P7HSR.js.map +0 -1
  395. package/dist/chunk-3JHFFIQ6.js.map +0 -1
  396. package/dist/chunk-5CYEWBPB.js +0 -440
  397. package/dist/chunk-5CYEWBPB.js.map +0 -1
  398. package/dist/chunk-5Y3L7XWH.js.map +0 -1
  399. package/dist/chunk-75EX5GY4.js.map +0 -1
  400. package/dist/chunk-AC2N5BRP.js.map +0 -1
  401. package/dist/chunk-DPMKI26Y.js.map +0 -1
  402. package/dist/chunk-G2O2AARG.js.map +0 -1
  403. package/dist/chunk-K2K7OF4P.js.map +0 -1
  404. package/dist/chunk-LFMX2UEF.js.map +0 -1
  405. package/dist/chunk-MMC24L2W.js.map +0 -1
  406. package/dist/chunk-N3Y43LMZ.js.map +0 -1
  407. package/dist/chunk-ORUHADS6.js.map +0 -1
  408. package/dist/chunk-P6KFWTGP.js.map +0 -1
  409. package/dist/chunk-R4G7XI7A.js.map +0 -1
  410. package/dist/chunk-TNWXGHLD.js.map +0 -1
  411. package/dist/chunk-TOSHZX4C.js.map +0 -1
  412. package/dist/chunk-WX74MVNA.js.map +0 -1
  413. package/dist/chunk-Y7UBRRKG.js.map +0 -1
  414. package/dist/chunk-YK7WJSTD.js.map +0 -1
  415. package/dist/factory-assets/bundles/workspaces-authoring/workspaces-authoring.bundle.yaml +0 -9
  416. package/dist/open-library-Z5NJU4Z5.js +0 -40
  417. package/dist/open-registry-TYUVN5SG.js +0 -32
  418. package/dist/paths-HKAXUR3W.js +0 -22
  419. package/dist/project-SVS4UMGL.js +0 -36
  420. package/dist/skills-HW6I6ZZ7.js +0 -26
  421. package/dist/source-OKRJT53H.js +0 -41
  422. package/dist/types/src/manifests/mount.d.ts +0 -21
  423. package/dist/types/src/manifests/mount.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../factory-assets/connectors/flow/engine/bindings.ts","../factory-assets/connectors/flow/engine/router-settlement.ts","../factory-assets/connectors/flow/engine/engine.ts","../factory-assets/connectors/flow/engine/output-schema.ts","../factory-assets/connectors/flow/engine/flow-output.ts","../factory-assets/connectors/flow/engine/node-deadline.ts","../factory-assets/connectors/flow/engine/node-attempts.ts","../factory-assets/connectors/flow/engine/optional-failure.ts","../factory-assets/connectors/flow/engine/check-provenance.ts","../factory-assets/connectors/flow/engine/flow-manifest.ts","../factory-assets/connectors/flow/engine/flow-kind-provider.ts","../factory-assets/connectors/flow/engine/loader.ts","../factory-assets/connectors/flow/engine/locate.ts"],"names":["process","path","parseYaml","fs"],"mappings":"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","file":"chunk-AOAZCSDI.js","sourcesContent":["import {\n resolveFlowBindings,\n stableFlowJson,\n type BindingOrigin,\n type FlowExpressionContext,\n type ResolvedNodeBindings,\n} from \"../contract/expression.js\";\nimport { isAgentNode, isSubFlowNode, isSubpromptNode, nodeBindings } from \"./node-shape.js\";\nimport type { FlowDefinition, FlowNode, NodeExecutionSnapshot } from \"./types.js\";\n\n/** Build the bounded expression context from immutable definition and snapshot state. */\nexport function buildFlowExpressionContext(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): FlowExpressionContext {\n const nodes: FlowExpressionContext[\"nodes\"] = {};\n for (const node of flow.nodes) {\n const snapshot = snapshots.get(node.id);\n const output =\n snapshot?.status === \"complete\" && snapshot.output?.fields\n ? { fields: snapshot.output.fields }\n : undefined;\n nodes[node.id] = { status: snapshot?.status ?? \"not_started\", output };\n }\n return {\n flow: { input: flow.defaults?.run_input ?? {} },\n defaults: flow.defaults,\n nodes,\n };\n}\n\n/**\n * Classify what one producer node's output counts as for a downstream binding.\n *\n * Transitive by induction, in a single lookup: a producer's persisted\n * `inputOrigins` were themselves classified under this rule when it ran, so\n * they already carry any taint from its own ancestors — no graph walk. Absent\n * origins read as `\"agent\"` (fail-closed): a snapshot persisted before the\n * field existed cannot prove the node's inputs were clean, and this label is\n * one a human approver acts on. `{}` — a node that bound nothing — is\n * `\"runtime\"`.\n */\nexport function producerOutputObtainedBy(\n producer: FlowNode,\n snapshot: NodeExecutionSnapshot | undefined,\n): \"agent\" | \"runtime\" {\n // A subprompt's output is model-generated the same as an agent's, even though\n // the runtime (not the session agent) makes the call — so a downstream check\n // must derive \"asserted\", never \"verified\", over it. See engine/check-provenance.ts.\n // A sub-flow returns what any node inside the child produced, agents included;\n // its inputOrigins cover only what the parent passed in, so they cannot clear it.\n if (isAgentNode(producer) || isSubpromptNode(producer) || isSubFlowNode(producer)) {\n return \"agent\";\n }\n const inputOrigins = snapshot?.inputOrigins;\n if (!inputOrigins) return \"agent\";\n const tainted = Object.values(inputOrigins).some((origins) =>\n // A hydrated snapshot is host-supplied and only shape-checked as JSON, so a\n // malformed entry is unreadable rather than clean — fail closed, never throw.\n Array.isArray(origins) ? origins.some((origin) => origin?.obtainedBy === \"agent\") : true,\n );\n return tainted ? \"agent\" : \"runtime\";\n}\n\n/** Resolve one node's named inputs and derive their runtime/agent origins. */\nexport function resolveNodeBindings(\n flow: FlowDefinition,\n node: FlowNode,\n snapshots: Map<string, NodeExecutionSnapshot>,\n flowInputOrigins: Record<string, BindingOrigin[]> = {},\n): ResolvedNodeBindings {\n const origins = Object.fromEntries(\n flow.nodes.map((producer) => [\n producer.id,\n producerOutputObtainedBy(producer, snapshots.get(producer.id)),\n ]),\n ) as Record<string, \"agent\" | \"runtime\">;\n return resolveFlowBindings(\n nodeBindings(node),\n buildFlowExpressionContext(flow, snapshots),\n origins,\n flowInputOrigins,\n );\n}\n\n/** Interpolate named, already-resolved binding values into an agent instruction. */\nexport function interpolateNodeInstruction(\n instruction: string,\n values: Record<string, unknown>,\n): string {\n return instruction.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_-]*)\\}/g, (_placeholder, name: string) => {\n if (!Object.hasOwn(values, name)) {\n throw new Error(`Node instruction binding ${name} is missing`);\n }\n const value = values[name];\n return typeof value === \"string\" ? value : stableFlowJson(value);\n });\n}\n","import type { NodeOutput } from \"@skaile/workspaces/types\";\nimport { evaluateFlowExpression, FlowExpressionError } from \"../contract/expression.js\";\nimport { buildFlowExpressionContext } from \"./bindings.js\";\nimport { isRouterNode } from \"./node-shape.js\";\nimport type { FlowDefinition, FlowNode, NodeExecutionSnapshot } from \"./types.js\";\n\nconst ROUTER_SELECTION_MARKER = \"\\n\\n[skaile:flow-router-selection:\";\n\n/** One deterministic router choice being settled in the current atomic batch. */\nexport interface RouterSettlement {\n routerNodeId: string;\n selectedTarget: string | null;\n}\n\n/**\n * Internal result of evaluating one already-admitted router. `failed` carries a\n * route expression error that no later stimulus can clear (a missing field on a\n * terminal producer, non-comparable operands): the router is decided, and what\n * it decided is to fail.\n */\nexport type RouterSelection =\n | { selectedTarget: string | null }\n | { unresolved: \"not-ready\" | \"no-match\" }\n | { failed: FlowExpressionError };\n\nfunction pendingProducerOutput(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n missingPath: string | undefined,\n): boolean {\n if (!missingPath) return false;\n const segments = missingPath.split(\".\");\n if (\n segments.length < 5 ||\n segments[0] !== \"nodes\" ||\n segments[2] !== \"output\" ||\n segments[3] !== \"fields\"\n ) {\n return false;\n }\n const producer = flow.nodes.find(({ id }) => id === segments[1]);\n if (!producer?.contract?.output?.fields) return false;\n // Only a producer that can still produce is worth waiting for — a terminal\n // one never will, and calling it \"pending\" parks the router forever.\n return ![\"complete\", \"skipped\", \"failed\"].includes(\n snapshots.get(producer.id)?.status ?? \"not_started\",\n );\n}\n\n/** Evaluate ordered routes for a router whose availability was already established. */\nexport function evaluateRouterSelection(\n flow: FlowDefinition,\n router: FlowNode,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): RouterSelection {\n if (!isRouterNode(router)) return { unresolved: \"no-match\" };\n const context = buildFlowExpressionContext(flow, snapshots);\n for (const route of router.run.routes) {\n try {\n if (evaluateFlowExpression(route.when, context)) {\n return { selectedTarget: route.target };\n }\n } catch (error) {\n if (\n error instanceof FlowExpressionError &&\n pendingProducerOutput(flow, snapshots, error.missingPath)\n ) {\n return { unresolved: \"not-ready\" };\n }\n // Rethrowing here escaped the whole drain and wedged the run: the router\n // stayed available and threw again on every later stimulus.\n if (error instanceof FlowExpressionError) return { failed: error };\n throw error;\n }\n }\n return { unresolved: \"no-match\" };\n}\n\n/** Encode a router choice in the existing durable node-output envelope. */\nexport function routerSelectionOutput(selectedTarget: string | null): NodeOutput {\n const summary =\n selectedTarget === null\n ? \"Router completed without selecting a target.\"\n : `Router selected ${selectedTarget}.`;\n return {\n summary: `${summary}${ROUTER_SELECTION_MARKER}${JSON.stringify(selectedTarget)}]`,\n artifacts: [],\n };\n}\n\nfunction routeTargets(router: FlowNode): string[] {\n if (!isRouterNode(router)) return [];\n return [...new Set(router.run.routes.flatMap(({ target }) => (target === null ? [] : [target])))];\n}\n\ninterface RouterOwnershipIndex {\n routers: FlowNode[];\n outgoing: Map<string, string[]>;\n}\n\n/** Index router-to-router ownership through route targets and hard-flow descendants. */\nfunction routerOwnershipIndex(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): RouterOwnershipIndex {\n const routers = flow.nodes.filter(\n (node) =>\n isRouterNode(node) &&\n ![\"complete\", \"failed\", \"skipped\"].includes(snapshots.get(node.id)?.status ?? \"not_started\"),\n );\n const routerIds = new Set(routers.map(({ id }) => id));\n const hardOutgoing = new Map<string, string[]>();\n for (const edge of flow.edges) {\n if (edge.type !== \"flow\") continue;\n const targets = hardOutgoing.get(edge.source) ?? [];\n targets.push(edge.target);\n hardOutgoing.set(edge.source, targets);\n }\n\n const outgoing = new Map<string, string[]>();\n for (const router of routers) {\n const owned = new Set<string>();\n const visited = new Set<string>();\n const queue = routeTargets(router);\n for (let index = 0; index < queue.length; index++) {\n const nodeId = queue[index];\n if (visited.has(nodeId)) continue;\n visited.add(nodeId);\n if (routerIds.has(nodeId)) owned.add(nodeId);\n queue.push(...(hardOutgoing.get(nodeId) ?? []));\n }\n outgoing.set(router.id, [...owned]);\n }\n return { routers, outgoing };\n}\n\n/**\n * Return every member of each source router-ownership SCC.\n *\n * Route ownership is deliberately not a dependency arc and may cycle even though hard flow is\n * acyclic. Source SCC members are ungated so normal hard-edge/precondition admission and ordered\n * decidability select the settlement frontier. Ordinary parent components remain ahead of nested\n * children, while self-targeting and mutually targeting routers cannot deadlock admission. The\n * graph is preindexed and both SCC passes are iterative.\n */\nfunction routerOwnershipSourceComponents(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): string[][] {\n const { routers, outgoing } = routerOwnershipIndex(flow, snapshots);\n const reverse = new Map<string, string[]>();\n for (const router of routers) reverse.set(router.id, []);\n for (const [source, targets] of outgoing) {\n for (const target of targets) reverse.get(target)?.push(source);\n }\n\n const visited = new Set<string>();\n const finished: string[] = [];\n for (const router of routers) {\n if (visited.has(router.id)) continue;\n const stack: Array<{ nodeId: string; exiting: boolean }> = [\n { nodeId: router.id, exiting: false },\n ];\n while (stack.length > 0) {\n const frame = stack.pop();\n if (!frame) break;\n if (frame.exiting) {\n finished.push(frame.nodeId);\n continue;\n }\n if (visited.has(frame.nodeId)) continue;\n visited.add(frame.nodeId);\n stack.push({ nodeId: frame.nodeId, exiting: true });\n const targets = outgoing.get(frame.nodeId) ?? [];\n for (let index = targets.length - 1; index >= 0; index--) {\n if (!visited.has(targets[index])) {\n stack.push({ nodeId: targets[index], exiting: false });\n }\n }\n }\n }\n\n const componentByRouter = new Map<string, number>();\n const components: string[][] = [];\n for (let index = finished.length - 1; index >= 0; index--) {\n const start = finished[index];\n if (componentByRouter.has(start)) continue;\n const componentId = components.length;\n const component: string[] = [];\n const stack = [start];\n componentByRouter.set(start, componentId);\n while (stack.length > 0) {\n const nodeId = stack.pop();\n if (!nodeId) break;\n component.push(nodeId);\n for (const source of reverse.get(nodeId) ?? []) {\n if (componentByRouter.has(source)) continue;\n componentByRouter.set(source, componentId);\n stack.push(source);\n }\n }\n components.push(component);\n }\n\n const incomingComponents = new Set<number>();\n for (const [source, targets] of outgoing) {\n const sourceComponent = componentByRouter.get(source);\n for (const target of targets) {\n const targetComponent = componentByRouter.get(target);\n if (\n sourceComponent !== undefined &&\n targetComponent !== undefined &&\n sourceComponent !== targetComponent\n ) {\n incomingComponents.add(targetComponent);\n }\n }\n }\n\n const definitionOrder = new Map(flow.nodes.map((node, index) => [node.id, index]));\n const sourceComponents = components.filter(\n (_, componentId) => !incomingComponents.has(componentId),\n );\n for (const component of sourceComponents) {\n component.sort(\n (left, right) =>\n (definitionOrder.get(left) ?? Number.MAX_SAFE_INTEGER) -\n (definitionOrder.get(right) ?? Number.MAX_SAFE_INTEGER),\n );\n }\n return sourceComponents.sort(\n (left, right) =>\n (definitionOrder.get(left[0]) ?? Number.MAX_SAFE_INTEGER) -\n (definitionOrder.get(right[0]) ?? Number.MAX_SAFE_INTEGER),\n );\n}\n\n/** Decode and validate a completed router's engine-owned selection summary. */\nexport function persistedRouterSelection(\n router: FlowNode,\n snapshot: NodeExecutionSnapshot | undefined,\n): { selectedTarget: string | null } | undefined {\n if (!isRouterNode(router) || snapshot?.status !== \"complete\") return undefined;\n const summary = snapshot.output?.summary;\n const markerIndex = summary?.lastIndexOf(ROUTER_SELECTION_MARKER) ?? -1;\n if (!summary || markerIndex < 0 || !summary.endsWith(\"]\")) return undefined;\n let selectedTarget: unknown;\n try {\n selectedTarget = JSON.parse(summary.slice(markerIndex + ROUTER_SELECTION_MARKER.length, -1));\n } catch {\n return undefined;\n }\n if (\n selectedTarget !== null &&\n (typeof selectedTarget !== \"string\" || !routeTargets(router).includes(selectedTarget))\n ) {\n return undefined;\n }\n if (selectedTarget === null && !router.run.routes.some(({ target }) => target === null)) {\n return undefined;\n }\n return summary === routerSelectionOutput(selectedTarget).summary ? { selectedTarget } : undefined;\n}\n\nfunction edgeKey(source: string, target: string): string {\n return `${source}\\u0000${target}`;\n}\n\n/**\n * Plan exclusive branch skips for all known router choices as one coordinated settlement.\n *\n * Only hard `flow` edges participate. The graph is indexed once, then each distinct losing\n * target performs a linear adjacency walk; optional and parallel edges can neither spread nor\n * preserve exclusivity. A selected route, a still-live unsettled router, shared convergence, or\n * an incoming hard predecessor outside the losing region protects that node and its descendants.\n */\nexport function planRouterSkips(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n settlements: readonly RouterSettlement[],\n): string[] {\n const routers = flow.nodes.filter(isRouterNode);\n const currentSelections = new Map(\n settlements.map(({ routerNodeId, selectedTarget }) => [routerNodeId, selectedTarget]),\n );\n const knownSelections = new Map<string, string | null>();\n for (const router of routers) {\n if (currentSelections.has(router.id)) {\n knownSelections.set(router.id, currentSelections.get(router.id) ?? null);\n continue;\n }\n const persisted = persistedRouterSelection(router, snapshots.get(router.id));\n if (persisted) knownSelections.set(router.id, persisted.selectedTarget);\n }\n\n const outgoing = new Map<string, string[]>();\n const incoming = new Map<string, string[]>();\n for (const edge of flow.edges) {\n if (edge.type !== \"flow\") continue;\n const targets = outgoing.get(edge.source) ?? [];\n targets.push(edge.target);\n outgoing.set(edge.source, targets);\n const sources = incoming.get(edge.target) ?? [];\n sources.push(edge.source);\n incoming.set(edge.target, sources);\n }\n\n const losingRoots = new Set<string>();\n const selectedRoots = new Set<string>();\n const losingRouteEdges = new Set<string>();\n for (const router of routers) {\n if (!knownSelections.has(router.id)) continue;\n const selectedTarget = knownSelections.get(router.id) ?? null;\n if (selectedTarget !== null) selectedRoots.add(selectedTarget);\n for (const target of routeTargets(router)) {\n if (target === selectedTarget) continue;\n losingRoots.add(target);\n losingRouteEdges.add(edgeKey(router.id, target));\n }\n }\n\n const candidateOrigins = new Map<string, Set<string>>();\n for (const root of losingRoots) {\n const visited = new Set<string>();\n const queue = [root];\n for (let index = 0; index < queue.length; index++) {\n const nodeId = queue[index];\n if (visited.has(nodeId)) continue;\n visited.add(nodeId);\n const origins = candidateOrigins.get(nodeId) ?? new Set<string>();\n origins.add(root);\n candidateOrigins.set(nodeId, origins);\n for (const target of outgoing.get(nodeId) ?? []) queue.push(target);\n }\n }\n const candidates = new Set(candidateOrigins.keys());\n\n const protectionQueue = [...selectedRoots];\n for (const [nodeId, origins] of candidateOrigins) {\n if (origins.size >= 2) protectionQueue.push(nodeId);\n for (const source of incoming.get(nodeId) ?? []) {\n if (candidates.has(source)) continue;\n if (losingRouteEdges.has(edgeKey(source, nodeId))) continue;\n if ([\"failed\", \"skipped\"].includes(snapshots.get(source)?.status ?? \"not_started\")) continue;\n protectionQueue.push(nodeId);\n break;\n }\n }\n\n const unknownSelections = new Map<string, string[]>();\n for (const router of routers) {\n if (knownSelections.has(router.id)) continue;\n const status = snapshots.get(router.id)?.status ?? \"not_started\";\n if (status === \"failed\" || status === \"skipped\") continue;\n const targets = routeTargets(router);\n unknownSelections.set(router.id, targets);\n if (!candidates.has(router.id)) protectionQueue.push(...targets);\n }\n\n const protectedNodes = new Set<string>();\n for (let index = 0; index < protectionQueue.length; index++) {\n const nodeId = protectionQueue[index];\n if (protectedNodes.has(nodeId)) continue;\n protectedNodes.add(nodeId);\n protectionQueue.push(...(outgoing.get(nodeId) ?? []));\n protectionQueue.push(...(unknownSelections.get(nodeId) ?? []));\n }\n\n return flow.nodes.flatMap((node) =>\n candidates.has(node.id) && !protectedNodes.has(node.id) ? [node.id] : [],\n );\n}\n\n/**\n * Return every possible target branch gated by an unsettled router.\n *\n * Gating follows hard `flow` descendants only. A selected route, shared convergence, or another\n * live hard predecessor protects a node, matching settlement pruning without mutating snapshots.\n */\nexport function unsettledRouterBranchIds(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): Set<string> {\n const unsettled = flow.nodes.filter(\n (node) =>\n isRouterNode(node) &&\n ![\"complete\", \"failed\", \"skipped\"].includes(snapshots.get(node.id)?.status ?? \"not_started\"),\n );\n const branches = new Set(\n planRouterSkips(\n flow,\n snapshots,\n unsettled.map(({ id }) => ({ routerNodeId: id, selectedTarget: null })),\n ),\n );\n for (const component of routerOwnershipSourceComponents(flow, snapshots)) {\n for (const routerId of component) branches.delete(routerId);\n }\n return branches;\n}\n\n/**\n * Return one actually available, decidable router per source ownership component.\n *\n * Every source-component member remains ungated for normal admission. Within a settlement wave,\n * definition order chooses the first member that is both available and decidable; unresolved or\n * blocked peers cannot starve it. Limiting each component to one choice prevents a router from\n * completing atomically after that same wave makes its branch losing. Independent source\n * components can still settle together.\n */\nexport function availableRouterFrontier(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): FlowNode[] {\n const nodesById = new Map(flow.nodes.map((node) => [node.id, node]));\n return routerOwnershipSourceComponents(flow, snapshots).flatMap((component) => {\n for (const routerId of component) {\n const node = nodesById.get(routerId);\n if (!node || snapshots.get(routerId)?.status !== \"available\") continue;\n if (\"unresolved\" in evaluateRouterSelection(flow, node, snapshots)) continue;\n return [node];\n }\n return [];\n });\n}\n","import type {\n FlowDefinition,\n FlowEdge,\n FlowNode,\n FlowState,\n NodeExecutionSnapshot,\n NodePreconditionFailure,\n NodeState,\n NodeStatus,\n} from \"./types.js\";\nimport { evaluateFlowExpression, type FlowExpressionContext } from \"../contract/expression.js\";\nimport { buildFlowExpressionContext } from \"./bindings.js\";\nimport {\n isActiveRuntimeNode,\n isRouterNode,\n nodeIsOptional,\n nodeLabel,\n nodeSkillId,\n} from \"./node-shape.js\";\nimport {\n evaluateRouterSelection,\n planRouterSkips,\n unsettledRouterBranchIds,\n} from \"./router-settlement.js\";\n\n// ---------------------------------------------------------------------------\n// Core engine — stateless, pure functions\n// ---------------------------------------------------------------------------\n\n/** Return nodes with state owned by the current runtime. */\nfunction activeRuntimeNodes(flow: FlowDefinition): FlowNode[] {\n return flow.nodes.filter(isActiveRuntimeNode);\n}\n\n/** Evaluate every authored admission condition without mutating runtime state. */\nfunction failedPreconditions(\n node: FlowNode,\n context: FlowExpressionContext,\n): NodePreconditionFailure[] {\n const failures: NodePreconditionFailure[] = [];\n for (const requirement of node.contract?.requires ?? []) {\n const message = requirement.message ?? `Precondition failed: ${requirement.expr}`;\n try {\n if (!evaluateFlowExpression(requirement.expr, context)) {\n failures.push({ expression: requirement.expr, message, reason: \"false\" });\n }\n } catch (error) {\n failures.push({\n expression: requirement.expr,\n message,\n reason: \"error\",\n detail: error instanceof Error ? error.message : \"Flow expression evaluation failed\",\n });\n }\n }\n return failures;\n}\n\n/** Build adjacency: target → sources[] (incoming edges per node) */\nfunction buildIncoming(edges: FlowEdge[]): Map<string, FlowEdge[]> {\n const map = new Map<string, FlowEdge[]>();\n for (const edge of edges) {\n if (!map.has(edge.target)) map.set(edge.target, []);\n map.get(edge.target)!.push(edge);\n }\n return map;\n}\n\n/** Build adjacency: source → targets[] (outgoing edges per node) */\nfunction buildOutgoing(edges: FlowEdge[]): Map<string, FlowEdge[]> {\n const map = new Map<string, FlowEdge[]>();\n for (const edge of edges) {\n if (!map.has(edge.source)) map.set(edge.source, []);\n map.get(edge.source)!.push(edge);\n }\n return map;\n}\n\n/** Result of resolving one available router against the current expression context. */\nexport interface RouterResolution {\n /** First matching route target. `null` means every branch loses. */\n selectedTarget: string | null;\n /** Exclusive nodes belonging only to unselected route targets, in definition order. */\n skippedNodeIds: string[];\n}\n\n/** Available router that cannot make a deterministic choice from the current snapshot. */\nexport interface UnresolvedRouterResolution {\n /** Why the router remains available for a later drain pass. */\n unresolved: \"not-ready\" | \"no-match\";\n}\n\n/**\n * Resolve the first matching route for a router that is currently available.\n *\n * Route conditions use the same bounded context as node preconditions and bindings. Resolution\n * is deliberately separate from state computation: unavailable routers return `undefined`\n * without evaluating any route. Losing route targets and their exclusive downstream paths are\n * returned for the caller to mark skipped. Exclusivity follows hard `flow` edges only and keeps\n * selected routes, unsettled-router targets, shared convergence, and externally reachable nodes\n * live. A declared producer output that is not complete yet returns a retryable unresolved result;\n * malformed expressions still throw their path-bearing evaluator error.\n *\n * @param flow - Parsed flow containing the router and branch graph.\n * @param routerNodeId - Router execution identity.\n * @param snapshots - Current node snapshots used for admission and expression values.\n * @returns The selected target and losing nodes, an unresolved reason while available but not\n * decidable, or `undefined` while the router is unavailable.\n */\nexport function resolveAvailableRouter(\n flow: FlowDefinition,\n routerNodeId: string,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): RouterResolution | UnresolvedRouterResolution | undefined {\n const router = flow.nodes.find((node) => node.id === routerNodeId);\n if (!router || !isRouterNode(router)) return undefined;\n const state = computeFlowStateFromSnapshots(flow, snapshots);\n if (!state.available.includes(routerNodeId)) return undefined;\n\n const selected = evaluateRouterSelection(flow, router, snapshots);\n if (\"unresolved\" in selected) return selected;\n if (\"failed\" in selected) throw selected.failed;\n\n return {\n selectedTarget: selected.selectedTarget,\n skippedNodeIds: planRouterSkips(flow, snapshots, [\n { routerNodeId, selectedTarget: selected.selectedTarget },\n ]),\n };\n}\n\n/**\n * Compute the full {@link FlowState} from a flow definition and caller-supplied node ID sets.\n *\n * This is the primary engine function. It is stateless and side-effect-free — calling it\n * twice with the same arguments always returns an equivalent result.\n *\n * Edge semantics applied during computation:\n * - `'flow'` — hard dependency: target cannot start until source is `complete` or `skipped`.\n * - `'parallel'` — soft dependency: target may run while source is still running.\n * - `'optional'` — advisory: target can start regardless of source state.\n *\n * A node is `available` when every incoming `'flow'`-type edge has a complete or skipped source\n * and every authored precondition evaluates true.\n * A node is `not_started` when at least one hard predecessor is still pending.\n * The flow is `done` when every non-optional node is `complete` or `skipped`.\n *\n * This set-based overload has statuses but no completed output fields. Use\n * {@link computeFlowStateFromSnapshots} when a precondition reads node output.\n *\n * Prefer {@link computeFlowStateFromSnapshots} for callers that track full `NodeExecution`\n * state (interaction statuses such as `awaiting_approval`, `awaiting_input`, `failed`).\n *\n * @param flow - The parsed flow definition.\n * @param completedIds - Set of node IDs that have finished successfully.\n * @param runningIds - Set of node IDs currently executing. Defaults to an empty set.\n * @param skippedIds - Set of node IDs that were explicitly skipped. Skipped nodes count\n * as satisfied for downstream dependency checks. Defaults to an empty set.\n * @returns A {@link FlowState} describing every active runtime node.\n * @docLink packages/flow-engine/concepts#compute-flow-state\n */\nexport function computeFlowState(\n flow: FlowDefinition,\n completedIds: Set<string>,\n runningIds: Set<string> = new Set(),\n skippedIds: Set<string> = new Set(),\n): FlowState {\n const nodes = activeRuntimeNodes(flow);\n const incoming = buildIncoming(flow.edges);\n const snapshots = new Map<string, NodeExecutionSnapshot>();\n for (const node of nodes) {\n const status: NodeStatus = completedIds.has(node.id)\n ? \"complete\"\n : runningIds.has(node.id)\n ? \"running\"\n : skippedIds.has(node.id)\n ? \"skipped\"\n : \"not_started\";\n snapshots.set(node.id, { status });\n }\n const gatedBranches = unsettledRouterBranchIds(flow, snapshots);\n const context = buildFlowExpressionContext(flow, snapshots);\n\n const nodeStates: NodeState[] = nodes.map((node) => {\n const optional = nodeIsOptional(node);\n const skillId = nodeSkillId(node);\n const label = nodeLabel(node);\n\n if (completedIds.has(node.id)) {\n return {\n nodeId: node.id,\n skillId,\n label,\n status: \"complete\",\n optional,\n canRun: false,\n blockers: [],\n failedPreconditions: [],\n };\n }\n if (runningIds.has(node.id)) {\n return {\n nodeId: node.id,\n skillId,\n label,\n status: \"running\",\n optional,\n canRun: false,\n blockers: [],\n failedPreconditions: [],\n };\n }\n if (skippedIds.has(node.id)) {\n return {\n nodeId: node.id,\n skillId,\n label,\n status: \"skipped\",\n optional,\n canRun: false,\n blockers: [],\n failedPreconditions: [],\n };\n }\n\n if (gatedBranches.has(node.id)) {\n return {\n nodeId: node.id,\n skillId,\n label,\n status: \"not_started\",\n optional,\n canRun: false,\n blockers: [],\n failedPreconditions: [],\n };\n }\n\n const edges = incoming.get(node.id) ?? [];\n\n // Hard blockers: flow-type edges whose source is neither complete nor skipped\n const hardBlockers = edges\n .filter((e) => e.type === \"flow\")\n .filter((e) => !completedIds.has(e.source) && !skippedIds.has(e.source))\n .map((e) => e.source);\n\n const preconditionFailures = failedPreconditions(node, context);\n const canRun = hardBlockers.length === 0 && preconditionFailures.length === 0;\n\n let status: NodeStatus;\n if (!canRun) {\n status = \"not_started\";\n } else {\n status = \"available\";\n }\n\n return {\n nodeId: node.id,\n skillId,\n label,\n status,\n optional,\n canRun,\n blockers: hardBlockers,\n failedPreconditions: preconditionFailures,\n };\n });\n\n const _stateMap = new Map(nodeStates.map((s) => [s.nodeId, s]));\n\n const available = nodeStates.filter((s) => s.status === \"available\").map((s) => s.nodeId);\n const completed = nodeStates.filter((s) => s.status === \"complete\").map((s) => s.nodeId);\n const focus = nodeStates\n .filter(\n (s) =>\n s.status === \"running\" || s.status === \"awaiting_approval\" || s.status === \"awaiting_input\",\n )\n .map((s) => s.nodeId);\n\n // Flow is done when all required nodes are complete or skipped\n const requiredNodes = nodes.filter((n) => !nodeIsOptional(n));\n const done = requiredNodes.every((n) => completedIds.has(n.id) || skippedIds.has(n.id));\n\n return { flowId: flow.id, nodes: nodeStates, available, completed, focus, done };\n}\n\n/**\n * Snapshot-based variant of {@link computeFlowState}.\n *\n * Accepts a map of `NodeExecutionSnapshot` values carrying the current status and\n * interaction metadata for every node the caller knows about. Nodes absent from the\n * map are treated as `not_started`.\n *\n * This is the preferred API for the turn-based runner, which has a full `FlowExecution`\n * and needs to convey richer statuses (`awaiting_approval`, `awaiting_input`, `failed`)\n * back to the engine so downstream availability is computed correctly.\n *\n * Engine semantics:\n * - A node is `available` when all its incoming `'flow'`-type predecessors are `complete`\n * or `skipped`. Any other upstream status — including `awaiting_approval`,\n * `awaiting_input`, and `failed` — is treated as blocking. Every authored precondition\n * must also evaluate true against the snapshot expression context.\n * - Optionality is **not** a term here: `failed` blocks whether or not the node is optional.\n * An optional node's dependents proceed because an optional node never reaches a terminal\n * `failed` in the first place — its exhausted failure resolves to `skipped`\n * (`resolveTerminalFailureStatus`), which passes. The one exception is a router, which\n * stays `failed` even when optional.\n * - The flow is `done` when every non-optional node is `complete` or `skipped`. A single\n * required node stuck in `failed` keeps `done` false.\n *\n * @param flow - The parsed flow definition.\n * @param snapshots - Map from node ID to its current {@link NodeExecutionSnapshot}.\n * Missing entries default to `not_started` with no interaction metadata.\n * @returns A {@link FlowState} describing every active runtime node,\n * including interaction fields (`approval`, `input`, `output`, `error`) copied\n * from the matching snapshot.\n * @docLink packages/flow-engine/concepts#compute-flow-state-from-snapshots\n */\nexport function computeFlowStateFromSnapshots(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): FlowState {\n const nodes = activeRuntimeNodes(flow);\n const incoming = buildIncoming(flow.edges);\n const gatedBranches = unsettledRouterBranchIds(flow, snapshots);\n const context = buildFlowExpressionContext(flow, snapshots);\n\n /** Resolve the effective status for a node — defaulting to `not_started`. */\n const statusFor = (nodeId: string): NodeStatus => snapshots.get(nodeId)?.status ?? \"not_started\";\n\n /** A predecessor \"passes\" when it is complete or skipped. */\n const passed = (nodeId: string): boolean => {\n const s = statusFor(nodeId);\n return s === \"complete\" || s === \"skipped\";\n };\n\n const nodeStates: NodeState[] = nodes.map((node) => {\n const snapshot = snapshots.get(node.id);\n const optional = nodeIsOptional(node);\n const skillId = nodeSkillId(node);\n const label = nodeLabel(node);\n const status = snapshot?.status ?? \"not_started\";\n\n const edges = incoming.get(node.id) ?? [];\n const flowPreds = edges.filter((e) => e.type === \"flow\");\n const hardBlockers = flowPreds.filter((e) => !passed(e.source)).map((e) => e.source);\n\n const isAdmissionState = status === \"not_started\" || status === \"available\";\n const preconditionFailures = isAdmissionState ? failedPreconditions(node, context) : [];\n\n // Recompute admission in both directions after fresh start or hydrate.\n let effectiveStatus: NodeStatus = status;\n if (isAdmissionState && gatedBranches.has(node.id)) {\n effectiveStatus = \"not_started\";\n } else if (isAdmissionState) {\n effectiveStatus =\n hardBlockers.length === 0 && preconditionFailures.length === 0\n ? \"available\"\n : \"not_started\";\n }\n\n return {\n nodeId: node.id,\n skillId,\n label,\n status: effectiveStatus,\n optional,\n canRun:\n hardBlockers.length === 0 &&\n preconditionFailures.length === 0 &&\n effectiveStatus === \"available\",\n blockers: hardBlockers,\n failedPreconditions: preconditionFailures,\n approval: snapshot?.approval,\n input: snapshot?.input,\n output: snapshot?.output,\n error: snapshot?.error,\n };\n });\n\n const available = nodeStates.filter((s) => s.status === \"available\").map((s) => s.nodeId);\n const completed = nodeStates.filter((s) => s.status === \"complete\").map((s) => s.nodeId);\n const focus = nodeStates\n .filter(\n (s) =>\n s.status === \"running\" || s.status === \"awaiting_approval\" || s.status === \"awaiting_input\",\n )\n .map((s) => s.nodeId);\n\n const requiredNodes = nodes.filter((n) => !nodeIsOptional(n));\n const done = requiredNodes.every((n) => {\n const s = statusFor(n.id);\n return s === \"complete\" || s === \"skipped\";\n });\n\n return { flowId: flow.id, nodes: nodeStates, available, completed, focus, done };\n}\n\n/**\n * Returns `true` when the given status prevents downstream nodes from starting.\n *\n * Only `'complete'` and `'skipped'` satisfy a hard (`'flow'`-type) edge dependency.\n * All other statuses — including `'awaiting_approval'`, `'awaiting_input'`, and\n * `'failed'` — are considered blocking.\n *\n * Use this helper in the FlowAdapter and the turn-based orchestrator instead of\n * hard-coding the two-value whitelist inline.\n *\n * @param status - The {@link NodeStatus} to evaluate.\n * @returns `true` if the status prevents dependents from becoming `available`.\n * @docLink packages/flow-engine/concepts#is-blocking\n */\nexport function isBlocking(status: NodeStatus): boolean {\n return status !== \"complete\" && status !== \"skipped\";\n}\n\n/**\n * Returns the IDs of nodes that become newly `available` after a specific node completes.\n *\n * More efficient than recomputing the full {@link FlowState} when only the downstream\n * impact of a single completion is needed. Only the direct successors of `justCompleted`\n * are evaluated — the rest of the graph is untouched.\n *\n * @param flow - The parsed flow definition.\n * @param justCompleted - ID of the node that just finished (will be added to the\n * effective completed set before evaluating successors).\n * @param completedIds - Set of node IDs already known to be complete before this call.\n * @param skippedIds - Set of node IDs that were explicitly skipped. Defaults to an empty set.\n * @returns Array of node IDs whose hard dependencies are now fully satisfied and that\n * were not already available before `justCompleted` finished. Unlike executable-node-filtered\n * helpers, this walks raw edge targets and does not filter by node type — if a `group`,\n * `sub-flow`, or `router` node is a direct successor, its ID can appear here. Callers that\n * dispatch these IDs are responsible for filtering inert nodes.\n * @docLink packages/flow-engine/concepts#resolve-next-nodes\n */\nexport function resolveNextNodes(\n flow: FlowDefinition,\n justCompleted: string,\n completedIds: Set<string>,\n skippedIds: Set<string> = new Set(),\n): string[] {\n const outgoing = buildOutgoing(flow.edges);\n const incoming = buildIncoming(flow.edges);\n const candidates = (outgoing.get(justCompleted) ?? []).map((e) => e.target);\n\n const nextCompleted = new Set([...completedIds, justCompleted]);\n const result: string[] = [];\n\n for (const candidateId of candidates) {\n const edges = incoming.get(candidateId) ?? [];\n const hardBlockers = edges\n .filter((e) => e.type === \"flow\")\n .filter((e) => !nextCompleted.has(e.source) && !skippedIds.has(e.source));\n if (hardBlockers.length === 0) {\n result.push(candidateId);\n }\n }\n\n return result;\n}\n\n/**\n * Returns the IDs of optional nodes that have not yet started and can be safely skipped.\n *\n * A node is skippable when it is:\n * 1. Not yet complete (absent from `completedIds`).\n * 2. Marked `optional` (`FlowNode.data.optional === true`).\n * 3. Not connected via a `'flow'`-type edge to any non-optional downstream node\n * (i.e. skipping it cannot starve a required node of a hard dependency).\n *\n * The runner may call this to present the user with a list of nodes they can bypass\n * without breaking the flow's required path.\n *\n * @param flow - The parsed flow definition.\n * @param completedIds - Set of node IDs that have already completed (excluded from results).\n * @returns Array of node IDs that are safe to skip at this point in the execution.\n * @docLink packages/flow-engine/concepts#compute-skippable\n */\nexport function computeSkippable(flow: FlowDefinition, completedIds: Set<string>): string[] {\n const nodes = activeRuntimeNodes(flow);\n const outgoing = buildOutgoing(flow.edges);\n\n return nodes\n .filter((n) => !completedIds.has(n.id))\n .filter(nodeIsOptional)\n .filter((n) => {\n // A node is skippable if none of its outgoing flow-type edges go to a required node\n const deps = (outgoing.get(n.id) ?? []).filter((e) => e.type === \"flow\");\n return deps.every((e) => {\n const target = flow.nodes.find((t) => t.id === e.target);\n return target ? nodeIsOptional(target) : false;\n });\n })\n .map((n) => n.id);\n}\n","import {\n compileOutputFieldsSchema,\n getConsumedOutputSchema,\n invalidOutputFieldsSchemaMessage,\n} from \"../contract/output-fields.js\";\nimport type { FlowDefinition } from \"./types.js\";\n\nexport { getConsumedOutputSchema };\n\n/** Result of validating fields at a producer's consumed-output boundary. */\nexport interface NodeOutputValidationResult {\n /** Whether the fields may be exposed to downstream consumers. */\n valid: boolean;\n /** Stable, path-bearing failures. Empty when validation is not required. */\n issues: string[];\n}\n\n/** Validate proposed fields only when a downstream deterministic consumer requires them. */\nexport function validateConsumedNodeOutput(\n flow: FlowDefinition,\n producerId: string,\n fields: Record<string, unknown> | undefined,\n): NodeOutputValidationResult {\n const schema = getConsumedOutputSchema(flow, producerId);\n if (!schema) return { valid: true, issues: [] };\n\n try {\n const validator = compileOutputFieldsSchema(schema);\n const parsed = validator.safeParse(fields ?? {});\n if (parsed.success) return { valid: true, issues: [] };\n return {\n valid: false,\n issues: parsed.error.issues\n .map((issue) => {\n const suffix = issue.path.map(String).join(\".\");\n return `fields${suffix ? `.${suffix}` : \"\"}: ${issue.message}`;\n })\n .sort(),\n };\n } catch (error) {\n return {\n valid: false,\n issues: [`fields: ${invalidOutputFieldsSchemaMessage(error)}`],\n };\n }\n}\n","import { FlowExpressionError, resolveFlowBindings } from \"../contract/expression.js\";\nimport {\n compileOutputFieldsSchema,\n invalidOutputFieldsSchemaMessage,\n} from \"../contract/output-fields.js\";\nimport { buildFlowExpressionContext, producerOutputObtainedBy } from \"./bindings.js\";\nimport type { FlowDefinition, NodeExecutionSnapshot } from \"./types.js\";\n\n/**\n * Resolve what a completed flow returns to a parent sub-flow node.\n *\n * `undefined` when the flow declares no `output.bindings`: it returns nothing.\n * Otherwise each binding resolves like a node input binding, and the result is\n * validated against `output.schema`. Throws an error naming the field and the\n * source node when a binding source did not produce its value, or naming the\n * flow when the values do not match the schema.\n */\nexport function resolveFlowOutputFields(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): Record<string, unknown> | undefined {\n const output = flow.output;\n if (output?.bindings === undefined) return undefined;\n\n const context = buildFlowExpressionContext(flow, snapshots);\n // Origins are required by the resolver but discarded: the parent classifies\n // every returned field as agent-obtained, whatever produced it in here.\n const origins = Object.fromEntries(\n flow.nodes.map((node) => [node.id, producerOutputObtainedBy(node, snapshots.get(node.id))]),\n );\n const fields: Record<string, unknown> = {};\n for (const [name, binding] of Object.entries(output.bindings)) {\n try {\n fields[name] = resolveFlowBindings({ [name]: binding }, context, origins).values[name];\n } catch (error) {\n if (!(error instanceof FlowExpressionError) || error.missingPath === undefined) throw error;\n const producer = error.missingPath.startsWith(\"nodes.\")\n ? error.missingPath.split(\".\")[1]\n : undefined;\n const source = producer\n ? `node ${producer} did not produce ${error.missingPath}`\n : `${error.missingPath} is missing`;\n throw new Error(`Flow ${flow.id} output field ${name} has no value: ${source}`);\n }\n }\n\n let validator: ReturnType<typeof compileOutputFieldsSchema>;\n try {\n validator = compileOutputFieldsSchema(output.schema);\n } catch (error) {\n throw new Error(`Flow ${flow.id} output.schema: ${invalidOutputFieldsSchemaMessage(error)}`);\n }\n const parsed = validator.safeParse(fields);\n if (!parsed.success) {\n const issues = parsed.error.issues\n .map((issue) => `${issue.path.map(String).join(\".\") || \"fields\"}: ${issue.message}`)\n .sort();\n throw new Error(`Flow ${flow.id} output does not match output.schema: ${issues.join(\"; \")}`);\n }\n return fields;\n}\n","/**\n * Pure derived-deadline arithmetic for `control.timeoutSec`.\n *\n * \"Active execution only\" is the scope every node-timeout ruling shares: the\n * clock runs from `startedAt` but stops counting while the node was parked\n * for a human decision. Rather than persist a separate \"paused\" duration,\n * this module recomputes the deadline on demand from `startedAt` plus the\n * already-durable `approvalHistory` / `inputHistory` — so it is correct\n * immediately after `hydrate()` or a reconnect with no extra wiring, and a\n * live timer is never the source of truth.\n *\n * @docLink packages/flow-engine/concepts#node-deadline\n */\n\nimport type { NodeExecution } from \"@skaile/workspaces/types\";\n\n/** Milliseconds spent parked in a resolved approval/input wait since `sinceMs`. */\nfunction pausedIntervalMs(execution: NodeExecution, sinceMs: number): number {\n let total = 0;\n for (const approval of execution.approvalHistory) {\n const startMs = Date.parse(approval.requestedAt);\n if (!Number.isFinite(startMs) || startMs < sinceMs) continue;\n if (!approval.decidedAt) continue; // still open — status wouldn't be \"running\" here\n const endMs = Date.parse(approval.decidedAt);\n if (Number.isFinite(endMs) && endMs > startMs) total += endMs - startMs;\n }\n for (const input of execution.inputHistory) {\n const startMs = Date.parse(input.requestedAt);\n if (!Number.isFinite(startMs) || startMs < sinceMs) continue;\n if (!input.providedAt) continue;\n const endMs = Date.parse(input.providedAt);\n if (Number.isFinite(endMs) && endMs > startMs) total += endMs - startMs;\n }\n return total;\n}\n\n/**\n * Milliseconds remaining before `execution`'s active-execution deadline, given\n * `timeoutSec`. Negative once the deadline has passed. `undefined` when no\n * timeout applies — `timeoutSec` is unset, or the node has no `startedAt` to\n * measure from (e.g. it hasn't actually started).\n *\n * Active time is wall-clock since `startedAt` minus every *resolved*\n * approval/input interval recorded at or after that `startedAt` (an\n * interval opened before a retry's fresh `startedAt` never counts against\n * the new attempt; a still-open interval never counts because the node\n * would not be `running` while parked).\n *\n * @param execution - Current node snapshot. Only `startedAt`, `approvalHistory`,\n * and `inputHistory` are read.\n * @param timeoutSec - Authored `control.timeoutSec`, or `undefined` for no timeout.\n * @param nowMs - Caller-supplied wall clock (`Date.now()` in production, injectable\n * for tests).\n * @docLink packages/flow-engine/concepts#remaining-active-execution-ms\n */\nexport function remainingActiveExecutionMs(\n execution: NodeExecution,\n timeoutSec: number | undefined,\n nowMs: number,\n): number | undefined {\n if (timeoutSec === undefined || !execution.startedAt) return undefined;\n const startedAtMs = Date.parse(execution.startedAt);\n if (!Number.isFinite(startedAtMs)) return undefined;\n const pausedMs = pausedIntervalMs(execution, startedAtMs);\n const deadlineMs = startedAtMs + timeoutSec * 1000 + pausedMs;\n return deadlineMs - nowMs;\n}\n\n/**\n * Whether `execution` has exceeded its derived active-execution deadline.\n * `false` when no timeout applies. Convenience wrapper over\n * {@link remainingActiveExecutionMs} for call sites that only need the\n * boolean.\n *\n * @docLink packages/flow-engine/concepts#is-active-execution-expired\n */\nexport function isActiveExecutionExpired(\n execution: NodeExecution,\n timeoutSec: number | undefined,\n nowMs: number,\n): boolean {\n const remaining = remainingActiveExecutionMs(execution, timeoutSec, nowMs);\n return remaining !== undefined && remaining <= 0;\n}\n","/**\n * Pure bookkeeping for `NodeExecution.outputHistory` and the bounded\n * automatic-retry budget derived from `control.retries`.\n *\n * `retries: N` means the first attempt plus N automatic retries — so an\n * automatic retry remains available while fewer than N attempts have\n * already failed. The budget is derived from `outputHistory` itself (a\n * count of prior `'failed'` entries) rather than a separate durable\n * counter, so it composes for free with hydration and needs no new field.\n *\n * The manual `retryNode` operator override never pushes an entry here (it\n * only flips `status` back to `available`). The agent's own\n * `doFailNode(recoverable: true)` self-retry DOES push an entry — every\n * actual start closes out an attempt — but marks it `selfRetry` so\n * `countFailedAttempts` excludes it: neither self-retry nor the manual\n * override consumes the automatic budget this module tracks.\n *\n * @docLink packages/flow-engine/concepts#node-attempts\n */\n\nimport type {\n CheckEvidence,\n NodeError,\n NodeExecutionAttempt,\n NodeOutput,\n} from \"@skaile/workspaces/types\";\n\n/** Next 1-based attempt number given the attempts already recorded. */\nexport function nextAttemptNumber(history: NodeExecutionAttempt[] | undefined): number {\n if (!history || history.length === 0) return 1;\n return Math.max(...history.map((entry) => entry.attempt)) + 1;\n}\n\n/** Rarely-set trailing facts about one appended attempt. */\nexport interface AppendAttemptOptions {\n /** True for the agent's own `doFailNode(recoverable: true)` self-retry: the\n * entry still records a genuine start-to-failure attempt, but is excluded\n * from {@link countFailedAttempts} so it never consumes the automatic\n * `control.retries` budget. */\n selfRetry?: boolean;\n /** Derived check evidence, when this attempt belongs to a `check` node that\n * actually produced a verdict (pass or fail). Omit for every other node\n * kind and for a check's infrastructure failure, which produced no verdict\n * to attach. */\n check?: CheckEvidence;\n}\n\n/**\n * Appends one terminal attempt to `history`, numbered `max(attempt) + 1`.\n * Never mutates `history` — returns a fresh array so callers can assign it\n * straight onto a cloned `NodeExecution`.\n *\n * @param history - Existing attempt history, oldest first (or `undefined`).\n * @param result - True outcome of this attempt — independent of any\n * compatibility status degrade the caller applies separately (e.g. an\n * optional node's failed execution still records `'failed'` here even\n * though its `NodeExecution.status` becomes `'skipped'`).\n * @param startedAtIso - This attempt's actual start time.\n * @param completedAtIso - This attempt's terminal outcome time.\n * @param options - See {@link AppendAttemptOptions}. Both fields default to absent.\n * @docLink packages/flow-engine/concepts#append-attempt\n */\nexport function appendAttempt(\n history: NodeExecutionAttempt[] | undefined,\n result: NodeExecutionAttempt[\"result\"],\n startedAtIso: string,\n completedAtIso: string,\n output: NodeOutput | undefined,\n error: NodeError | undefined,\n options: AppendAttemptOptions = {},\n): NodeExecutionAttempt[] {\n const attempt: NodeExecutionAttempt = {\n attempt: nextAttemptNumber(history),\n result,\n startedAt: startedAtIso,\n completedAt: completedAtIso,\n ...(output !== undefined ? { output } : {}),\n ...(error !== undefined ? { error } : {}),\n ...(options.selfRetry ? { selfRetry: true } : {}),\n ...(options.check !== undefined ? { check: options.check } : {}),\n };\n return [...(history ?? []), attempt];\n}\n\n/**\n * Count of attempts in `history` whose true outcome was `'failed'`,\n * excluding self-retry entries (see {@link appendAttempt}) — this feeds only\n * the automatic-retry budget, which self-retry sits outside of.\n */\nexport function countFailedAttempts(history: NodeExecutionAttempt[] | undefined): number {\n if (!history) return 0;\n return history.filter((entry) => entry.result === \"failed\" && !entry.selfRetry).length;\n}\n\n/**\n * Whether an automatic retry remains, given how many attempts have already\n * failed and the authored `control.retries` budget. `retries: N` allows the\n * first attempt plus N automatic retries — so a retry remains available\n * while `priorFailedAttempts < N`. No `retries` (or `0`) means no automatic\n * retry ever.\n *\n * @docLink packages/flow-engine/concepts#has-automatic-retry-budget\n */\nexport function hasAutomaticRetryBudget(\n priorFailedAttempts: number,\n retries: number | undefined,\n): boolean {\n if (!retries) return false;\n return priorFailedAttempts < retries;\n}\n","/**\n * The single statement of the rule that decides an exhausted failure's\n * terminal status.\n *\n * Previously each terminal-failure write site restated the rule and only two\n * of them implemented it, so `control.optional` meant different things per\n * node kind. Every such site now routes through here.\n *\n * @docLink packages/flow-engine/concepts#optional-failure\n */\n\nimport { isRouterNode, nodeIsOptional } from \"./node-shape.js\";\nimport type { FlowNode } from \"./types.js\";\n\n/**\n * Terminal status for a node whose execution failed with no retry budget left.\n *\n * Invariant: an optional node never ends terminally `failed`. Only `complete`\n * and `skipped` satisfy a hard `flow` edge (see `isBlocking`), so leaving one\n * `failed` stalls every dependent at the node the author called expendable.\n *\n * A router is the deliberate exception: a `skipped` router leaves the gated\n * set (`unsettledRouterBranchIds`) while satisfying every outgoing hard edge,\n * so skipping it admits *all* of its branches instead of selecting one.\n */\nexport function resolveTerminalFailureStatus(node: FlowNode): \"failed\" | \"skipped\" {\n return nodeIsOptional(node) && !isRouterNode(node) ? \"skipped\" : \"failed\";\n}\n","/**\n * Pure derivation of a `check` node's evidence payload — what was compared,\n * where each value came from, and whether that makes the verdict\n * runtime-`\"verified\"` or agent-`\"asserted\"`.\n *\n * Ruling: re-running a check is not required to reproduce the same answer,\n * so there is no snapshot materialization, no hashing, and no reproducibility\n * guarantee here — this module records integrity of *what was observed*, not\n * a promise that observing it again would agree. Provenance is derived\n * exclusively from {@link BindingOrigin.obtainedBy}, the flow engine's\n * existing (and only) provenance mechanism, so it can never be influenced by\n * how a flow author names a binding. That label is transitive before it\n * arrives here — a deterministic node that carries an agent's value forward\n * stays agent-obtained — so this module compares origins as given and makes\n * no one-hop caveat.\n *\n * The claim is that provenance cannot be asserted by flow *configuration*.\n * It is not a claim against a caller holding the read-write connector handle:\n * taint now derives from persisted `NodeExecution.inputOrigins`, which the\n * `hydrate` op writes verbatim. Such a caller could already forge `output`\n * itself, so this widens no existing trust boundary.\n *\n * No I/O and no clock: `observedAt` is supplied by the caller so this stays\n * trivially testable and replayable.\n *\n * @docLink packages/flow-engine/concepts#check-provenance\n */\n\nimport type {\n BindingOrigin,\n CheckComparedValue,\n CheckEvidence,\n CheckInputCurrency,\n CheckProvenance,\n} from \"@skaile/workspaces/types\";\nimport type { ResolvedNodeBindings } from \"../contract/expression.js\";\n\n/** The check's process facts, captured alongside its verdict so a persisted attempt is self-describing. */\nexport interface CheckProcessRecord {\n runtime: \"shell\" | \"node\" | \"python\";\n command: string;\n cwd?: string;\n successExit: number[];\n exitStatus: number;\n passed: boolean;\n}\n\nconst FLOW_LOCAL_SOURCES = new Set<BindingOrigin[\"source\"]>([\"literal\", \"default\", \"flow-input\"]);\n\n/**\n * Derive one check's evidence from its already-resolved bindings and its\n * process outcome. `provenance` and `inputs` are computed only from\n * `bindings.origins` — never from `bindings.values` or their names — so\n * authoring a binding literally named `provenance` or `verified` cannot\n * influence the verdict.\n *\n * `provenance` is `\"verified\"` iff every origin of every compared value has\n * `obtainedBy: \"runtime\"`, `\"asserted\"` if any does not, and **absent** when\n * there are no compared values — neither label is honest about an empty set.\n * `obtainedBy` is already transitive when it reaches here (see\n * `producerOutputObtainedBy`), so `\"verified\"` means no agent-produced value\n * contributed anywhere in the ancestry, not merely one hop back.\n * `inputs` is `\"live\"` — the floor for any check that runs a process —\n * unless there is at least one compared value and every one of them has\n * origins that are all `literal`/`default`/`flow-input`, in which case it is\n * `\"flow-local\"`.\n */\nexport function deriveCheckEvidence(\n bindings: ResolvedNodeBindings,\n process: CheckProcessRecord,\n observedAt: string,\n): CheckEvidence {\n const values: CheckComparedValue[] = Object.entries(bindings.values).map(([name, value]) => {\n const origins = bindings.origins[name] ?? [];\n const obtainedBy = origins.some((origin) => origin.obtainedBy === \"agent\")\n ? \"agent\"\n : \"runtime\";\n return { name, value, origins, obtainedBy };\n });\n const provenance: CheckProvenance | undefined =\n values.length === 0\n ? undefined\n : values.every((compared) => compared.obtainedBy === \"runtime\")\n ? \"verified\"\n : \"asserted\";\n const inputs: CheckInputCurrency =\n values.length > 0 &&\n values.every((compared) =>\n compared.origins.every((origin) => FLOW_LOCAL_SOURCES.has(origin.source)),\n )\n ? \"flow-local\"\n : \"live\";\n return {\n values,\n ...(provenance !== undefined ? { provenance } : {}),\n inputs,\n observedAt,\n ...process,\n };\n}\n","/**\n * Flow manifest schema and validation.\n *\n * Moved from @skaile/workspaces/types/manifests/flow.ts in Phase 1.7.3.\n * This is now the canonical location for flow manifest validation.\n */\n\nimport * as z from \"zod\";\n\n// ---------------------------------------------------------------------------\n// Validation result (inline — avoids importing from types/manifests/_shared)\n// ---------------------------------------------------------------------------\n\nexport interface ManifestValidationSuccess<T> {\n ok: true;\n data: T;\n}\n\nexport interface ManifestValidationFailure {\n ok: false;\n errors: Array<{ path: string; message: string }>;\n}\n\nexport type ManifestValidationResult<T> = ManifestValidationSuccess<T> | ManifestValidationFailure;\n\n// ---------------------------------------------------------------------------\n// Schema\n// ---------------------------------------------------------------------------\n\nconst FlowNodeSchema = z.looseObject({\n id: z.string().min(1),\n skill: z.string().optional(),\n type: z.string().optional(),\n label: z.string().optional(),\n description: z.string().optional(),\n data: z\n .looseObject({\n optional: z.boolean().optional(),\n // Mandatory approval gate — autonomous mode cannot skip it.\n approval: z.looseObject({ mandatory: z.boolean().optional() }).optional(),\n })\n .refine((d) => !(d.optional === true && d.approval?.mandatory === true), {\n // A mandatory gate can never be skipped, so optional+mandatory is a\n // contradiction — reject it rather than silently letting mandatory win.\n message: \"a node cannot be both optional and a mandatory approval gate\",\n })\n .optional(),\n});\n\nconst FlowEdgeSchema = z.looseObject({\n id: z.string().optional(),\n source: z.string().min(1),\n target: z.string().min(1),\n condition: z.string().optional(),\n});\n\nexport const FlowManifestSchema = z.looseObject({\n id: z.string().min(1),\n version: z.string().optional(),\n name: z.string().min(1),\n description: z.string().optional(),\n metadata: z\n .looseObject({\n tags: z.array(z.string()).optional(),\n stage: z.string().optional(),\n icon: z.string().optional(),\n category: z.string().optional(),\n onboarding: z.record(z.string(), z.unknown()).optional(),\n })\n .optional(),\n globals: z.record(z.string(), z.unknown()).optional(),\n modes: z.record(z.string(), z.unknown()).optional(),\n tier_presets: z.record(z.string(), z.record(z.string(), z.unknown())).optional(),\n artifact_handoff: z.unknown().optional(),\n entry: z.string().optional(),\n nodes: z.array(FlowNodeSchema).optional(),\n edges: z.array(FlowEdgeSchema).optional(),\n});\n\nexport type FlowManifest = z.infer<typeof FlowManifestSchema>;\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nexport function validateFlow(data: unknown): ManifestValidationResult<FlowManifest> {\n const result = FlowManifestSchema.safeParse(data);\n if (result.success) {\n return { ok: true, data: result.data };\n }\n return {\n ok: false,\n errors: result.error.issues.map((issue) => ({\n path: issue.path.join(\".\"),\n message: issue.message,\n })),\n };\n}\n","/**\n * Flow asset kind provider.\n *\n * Exported from @skaile/workspaces/factory-assets/connectors/flow/engine for explicit registration\n * by the CLI at bootstrap. Discovery does NOT auto-include this provider\n * (discovery must stay a leaf — no flow-engine imports).\n *\n * Implements IAssetKindProvider with flow-specific:\n * - Discovery patterns: *.flow.yaml, *.flow.json\n * - Manifest validation via FlowManifestSchema\n * - Requires extraction: nodes[].run.assets plus legacy skill/sub-flow references\n * - File filter: just the manifest file (flows are single-file)\n */\n\nimport * as path from \"node:path\";\nimport type {\n AssetKindFileFilter,\n AssetKindRequiresEdge,\n IAssetKindProvider,\n} from \"@skaile/workspaces/plugins\";\nimport { validateFlow } from \"./flow-manifest.js\";\n\n// ---------------------------------------------------------------------------\n// Provider\n// ---------------------------------------------------------------------------\n\nexport const flowKindProvider: IAssetKindProvider = {\n kind: \"flow\",\n displayName: \"Flow\",\n providerVersion: \"1.1.0\",\n installTarget: \"flow\",\n discoveryPatterns: [\"**/*.flow.yaml\", \"**/*.flow.json\"],\n\n matchesPath(relativePath: string): boolean {\n return relativePath.endsWith(\".flow.yaml\") || relativePath.endsWith(\".flow.json\");\n },\n\n validateManifest(data: unknown) {\n return validateFlow(data);\n },\n\n defaultFileFilter(manifestPath: string): AssetKindFileFilter {\n return {\n assetRoot: path.dirname(manifestPath),\n files: [path.basename(manifestPath)],\n };\n },\n\n extractRequires(assetRef: string, manifest: Record<string, unknown>): AssetKindRequiresEdge[] {\n const edges: AssetKindRequiresEdge[] = [];\n const seen = new Set<string>();\n const add = (to: string, field: string): void => {\n if (seen.has(to)) return;\n seen.add(to);\n edges.push({ from: assetRef, to, field });\n };\n\n const nodes = manifest.nodes;\n if (Array.isArray(nodes)) {\n for (const node of nodes) {\n if (typeof node !== \"object\" || node === null) continue;\n const n = node as Record<string, unknown>;\n const data = (\n typeof n.data === \"object\" && n.data !== null ? (n.data as Record<string, unknown>) : {}\n ) as Record<string, unknown>;\n const run =\n typeof n.run === \"object\" && n.run !== null ? (n.run as Record<string, unknown>) : {};\n\n if (Array.isArray(run.assets)) {\n for (const asset of run.assets) {\n if (typeof asset === \"string\") add(asset, \"nodes[].run.assets\");\n }\n }\n\n if (run.kind === \"sub-flow\" && typeof run.flow === \"string\") {\n const flowRef = run.flow.startsWith(\"flow:\") ? run.flow : `flow:${run.flow}`;\n add(flowRef, \"nodes[].run.flow\");\n }\n\n const skill = typeof data.skill === \"string\" ? data.skill : n.skill;\n if (typeof skill === \"string\") {\n add(skill, \"nodes[].data.skill\");\n }\n\n const subFlow = typeof data.flow === \"string\" ? data.flow : n.flow;\n if (typeof subFlow === \"string\") {\n add(subFlow.startsWith(\"flow:\") ? subFlow : `flow:${subFlow}`, \"nodes[].data.flow\");\n }\n }\n }\n\n return edges;\n },\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { findKindDirs } from \"@skaile/workspaces/core\";\nimport { parse as parseYaml } from \"yaml\";\nimport { parseFlowDefinition } from \"../contract/normalize.js\";\nimport type { FlowDefinition } from \"./types.js\";\n\n/**\n * The filename suffixes a flow file may carry, in probe order. `.json` is the\n * legacy bare form and stays last so an explicit `.flow.json` wins a tie.\n *\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport const FLOW_FILE_EXTENSIONS = [\".flow.yaml\", \".flow.yml\", \".flow.json\", \".json\"] as const;\n\n/** A discovered flow paired with the file it was loaded from. */\nexport interface FlowFileEntry {\n flow: FlowDefinition;\n path: string;\n}\n\n/**\n * The conventional on-disk locations of flow `flowId` inside one `flows/` search\n * dir: the flat `<dir>/<id><ext>` and the per-flow-directory\n * `<dir>/<id>/<id><ext>`, for every {@link FLOW_FILE_EXTENSIONS}. Existence is\n * NOT checked. Shared with the CLI's `findFlowFile` so the naming convention has\n * exactly one definition.\n *\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function flowFileCandidates(dirPath: string, flowId: string): string[] {\n return [\n ...FLOW_FILE_EXTENSIONS.map((ext) => path.join(dirPath, `${flowId}${ext}`)),\n ...FLOW_FILE_EXTENSIONS.map((ext) => path.join(dirPath, flowId, `${flowId}${ext}`)),\n ];\n}\n\n/** Matches `flow.yaml` as well as `<anything>.flow.yaml` (and `.yml` / `.json`). */\nconst FLOW_SHAPED_FILE = /(^|\\.)flow\\.(ya?ml|json)$/i;\n\n/** How far below a per-flow directory a stray flow file is still reported. */\nconst STRAY_SCAN_DEPTH = 3;\n\nfunction isDirectory(entry: fs.Dirent, fullPath: string): boolean {\n if (entry.isDirectory()) return true;\n if (!entry.isSymbolicLink()) return false;\n try {\n return fs.statSync(fullPath).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * First flow-shaped file at or below `dirPath`, used only to decide whether a\n * subdirectory that yielded no conventional flow deserves a warning. Deliberately\n * ignores bare `.json` so sibling assets (`package.json`, fixtures) stay silent.\n */\nfunction findStrayFlowFile(dirPath: string, depth: number = STRAY_SCAN_DEPTH): string | undefined {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dirPath, { withFileTypes: true });\n } catch {\n return undefined;\n }\n for (const entry of entries) {\n if (!isDirectory(entry, path.join(dirPath, entry.name)) && FLOW_SHAPED_FILE.test(entry.name)) {\n return path.join(dirPath, entry.name);\n }\n }\n if (depth <= 1) return undefined;\n for (const entry of entries) {\n const full = path.join(dirPath, entry.name);\n if (!isDirectory(entry, full)) continue;\n if (entry.name.startsWith(\"_\") || entry.name.startsWith(\".\") || entry.name === \"node_modules\") {\n continue;\n }\n const stray = findStrayFlowFile(full, depth - 1);\n if (stray) return stray;\n }\n return undefined;\n}\n\n/**\n * Load a single {@link FlowDefinition} from a YAML or JSON file on disk.\n *\n * Format detection is based on file extension:\n * - `.yaml` / `.yml` — parsed with the `yaml` library.\n * - Everything else — parsed as JSON.\n *\n * @param filePath - Absolute path to the flow file.\n * @returns The parsed {@link FlowDefinition}.\n * @throws {Error} If the file does not exist, cannot be read, or fails to parse.\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function loadFlow(filePath: string): FlowDefinition {\n const raw = fs.readFileSync(filePath, \"utf-8\");\n const ext = path.extname(filePath).toLowerCase();\n const authored = ext === \".yaml\" || ext === \".yml\" ? parseYaml(raw) : JSON.parse(raw);\n const parsed = parseFlowDefinition(authored);\n if (!parsed.ok) {\n const details = parsed.errors\n .map((issue) => ` ${issue.path || \"<root>\"}: ${issue.message}`)\n .join(\"\\n\");\n throw new Error(`Invalid flow definition:\\n${details}`);\n }\n return parsed.data;\n}\n\n/**\n * Load every flow in a `flows/` directory, in both supported shapes, keeping the\n * file each one came from.\n *\n * Two tiers, and nothing else:\n * 1. **Flat** — a file directly in `dirPath` ending in one of {@link FLOW_FILE_EXTENSIONS}.\n * 2. **Per-flow directory** — `<dir>/<sub>/<sub><ext>`; the file MUST be named after\n * its directory, which is what lets a flow keep sibling assets (README, fixtures,\n * prompts) without them being parsed as flows.\n *\n * A subdirectory that holds something flow-shaped but no conventional file is\n * **reported** through `onWarn` rather than dropped silently — silence is the\n * defect this contract exists to remove. Files/dirs prefixed with `_` are the\n * explicit opt-out and stay silent. Parse failures are warned about and skipped,\n * never thrown.\n *\n * @param dirPath - Absolute path to the directory to scan.\n * @param opts.onWarn - Sink for warnings; defaults to `stderr`. Pass a no-op on\n * hot paths where a probe miss is normal (e.g. resolving an arbitrary CLI arg).\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function loadFlowEntriesFromDir(\n dirPath: string,\n opts: { onWarn?: (message: string) => void } = {},\n): FlowFileEntry[] {\n const warn = opts.onWarn ?? ((message: string) => void process.stderr.write(`${message}\\n`));\n\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dirPath, { withFileTypes: true });\n } catch {\n return [];\n }\n\n const found: FlowFileEntry[] = [];\n const load = (filePath: string, label: string) => {\n try {\n const def = loadFlow(filePath);\n if (def.id && def.nodes && def.edges) found.push({ flow: def, path: filePath });\n } catch (err) {\n warn(`[agent-flow-engine] skipping ${label}: ${(err as Error).message}`);\n }\n };\n\n for (const entry of entries) {\n if (entry.name.startsWith(\"_\")) continue;\n const full = path.join(dirPath, entry.name);\n\n if (!isDirectory(entry, full)) {\n if (FLOW_FILE_EXTENSIONS.some((ext) => entry.name.endsWith(ext))) load(full, entry.name);\n continue;\n }\n if (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n\n const conventional = FLOW_FILE_EXTENSIONS.map((ext) =>\n path.join(full, `${entry.name}${ext}`),\n ).find((candidate) => fs.existsSync(candidate));\n if (conventional) {\n load(conventional, path.join(entry.name, path.basename(conventional)));\n continue;\n }\n\n const stray = findStrayFlowFile(full);\n if (stray) {\n warn(\n `[agent-flow-engine] ignoring ${stray}: a flow directory must hold ` +\n `${entry.name}.flow.yaml (or .flow.yml / .flow.json / .json)`,\n );\n }\n }\n\n return found;\n}\n\n/**\n * Load all flows from a directory — {@link loadFlowEntriesFromDir} without the\n * originating file paths. See it for the two supported layouts, the warning\n * contract, and the `_`-prefix opt-out.\n *\n * @param dirPath - Absolute path to the directory to scan.\n * @returns Array of successfully parsed {@link FlowDefinition} objects. Empty if the\n * directory does not exist or contains no valid flow files.\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function loadFlowsFromDir(dirPath: string): FlowDefinition[] {\n return loadFlowEntriesFromDir(dirPath).map((entry) => entry.flow);\n}\n\n/**\n * Discover every flow under a content root, keeping the file each came from.\n *\n * Covers every `flows/` directory at any depth under the root via\n * `findKindDirs`, and within each of those both flow layouts via\n * {@link loadFlowEntriesFromDir}. De-duped by **declared id**, first search dir\n * wins — the same identity every other flow surface resolves by.\n *\n * @param aiResourcesRoot - Absolute path to a content root (`ai-assets/` or equivalent).\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function loadAllFlowEntries(\n aiResourcesRoot: string,\n opts: { onWarn?: (message: string) => void } = {},\n): FlowFileEntry[] {\n if (!fs.existsSync(aiResourcesRoot)) return [];\n\n const byId = new Map<string, FlowFileEntry>();\n for (const dir of findKindDirs(aiResourcesRoot, \"flows\")) {\n for (const entry of loadFlowEntriesFromDir(dir, opts)) {\n if (!byId.has(entry.flow.id)) byId.set(entry.flow.id, entry);\n }\n }\n return [...byId.values()];\n}\n\n/**\n * Discover and load all flow definitions under a content root —\n * {@link loadAllFlowEntries} without the originating file paths.\n *\n * @param aiResourcesRoot - Absolute path to the `ai-assets/` directory (or equivalent\n * resource root). Typically the `ai-assets/` folder at the monorepo root.\n * @returns Flat array of all successfully parsed {@link FlowDefinition} objects across\n * all `flows/` directories. Empty if the root directory does not exist.\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function loadAllFlows(aiResourcesRoot: string): FlowDefinition[] {\n return loadAllFlowEntries(aiResourcesRoot).map((entry) => entry.flow);\n}\n","/**\n * locate.ts — the one place that answers \"where do flows live, and what are\n * they called\".\n *\n * It sits in the engine, next to `flowFileCandidates` / `loadAllFlowEntries`,\n * because both sides of the question have to agree: the CLI's *listing*\n * surfaces (`flow list`, completions) and the *resolution* surfaces that live\n * in this tree (`resume`, sub-flow `run.flow` targets, `serve`). They used to\n * hold two hand-maintained candidate lists, and only one of them ever grew.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { aiResourceRoots, findKindDirs } from \"@skaile/workspaces/core\";\nimport { flowFileCandidates, loadAllFlowEntries, loadFlow } from \"./loader.js\";\n\n/** How far up from the project the `ai-assets/` walk looks before giving up. */\nconst AI_ASSETS_WALK_LEVELS = 6;\n\n/**\n * Walk upward from `startDir` (checking at most `AI_ASSETS_WALK_LEVELS`\n * directories, never the filesystem root itself) for an `ai-assets/`\n * subdirectory. Returns its absolute path, or `null` when none is found.\n */\nfunction findAiAssetsDir(startDir: string): string | null {\n let dir = path.resolve(startDir);\n const fsRoot = path.parse(dir).root;\n\n for (let i = 0; i < AI_ASSETS_WALK_LEVELS; i++) {\n const candidate = path.join(dir, \"ai-assets\");\n if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) return candidate;\n const parent = path.dirname(dir);\n if (parent === dir || parent === fsRoot) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Roots that only the *resolution* surfaces prepend: the project's own\n * `ai-assets/` tree, so a workspace can shadow a built-in flow.\n *\n * Returns at most one root — the nearest `ai-assets/` at or above `projectDir`.\n * Listing deliberately does **not** include it; see `cli/src/flow-discovery.ts`.\n *\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function projectAiAssetsRoots(projectDir: string): string[] {\n const found = findAiAssetsDir(projectDir);\n return found ? [found] : [];\n}\n\n/**\n * Every root a flow lookup walks, in priority order: the project's own\n * `ai-assets/` tree first, then every shared content root.\n *\n * `aiResourceRoots(projectDir)` is a **subset** of this — that is the documented\n * relationship between \"a flow `flow list` shows\" and \"a flow `resume` /\n * sub-flow targets / `serve` can find\", and the reason both go through here.\n *\n * The authored `ai-assets/` tree leading is deliberate and is what `skaile run`\n * has always done: a workspace must be able to shadow a built-in flow. It is the\n * opposite of {@link aiResourceRoots}'s own ordering, where the deployed\n * `.skaile/` copy leads because `deployAll` applies `patches:` to it — so for a\n * flow id present in *both*, resolution takes the authored source. Resume must\n * execute the bytes `run` executed; that agreement is the point of this module.\n *\n * @param projectDir - Project whose `.skaile/` and `ai-assets/` roots to\n * include (default: `process.cwd()`).\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function flowLookupRoots(projectDir?: string): string[] {\n const dir = projectDir ?? process.cwd();\n return [...new Set([...projectAiAssetsRoots(dir), ...aiResourceRoots(dir)])];\n}\n\n/**\n * Why a conventional candidate that exists on disk was still not accepted —\n * the difference between \"no such flow\" and \"that file is right there but\n * declares something else\", which a bare \"not found\" used to hide.\n *\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport interface FlowLookupMiss {\n path: string;\n reason: \"unparseable\" | \"id-mismatch\";\n declaredId?: string;\n error?: string;\n}\n\n/** `candidate` resolves inside `dir` rather than escaping it via `..`. */\nfunction contained(dir: string, candidate: string): boolean {\n const relative = path.relative(path.resolve(dir), path.resolve(candidate));\n return !relative.startsWith(\"..\") && !path.isAbsolute(relative);\n}\n\n/**\n * Locate the file of the flow whose **declared id** is `flowId`, across `roots`.\n *\n * Per root: the conventional paths first (every `flows/` directory at any depth\n * via `findKindDirs`, both flow layouts and all four extensions via\n * `flowFileCandidates`), then the full enumeration `loadAllFlowEntries` — the\n * same one `discoverFlows` lists from, which is what keeps listing and\n * resolution agreeing by construction. The fallback stays *inside* the loop so\n * an earlier root always wins over a later one.\n *\n * A candidate that resolves outside the search dir it was built from is\n * **skipped, not thrown**: this is on the `skaile run \"<free-text prompt>\"`\n * path, where a miss is normal and must fall through to single-shot mode.\n *\n * @param opts.onMiss - Called for a conventional candidate that exists but was\n * rejected. Discovery warnings are suppressed regardless.\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function findFlowFileInRoots(\n flowId: string,\n roots: string[],\n opts: { onMiss?: (miss: FlowLookupMiss) => void } = {},\n): string | undefined {\n for (const root of roots) {\n for (const dir of findKindDirs(root, \"flows\")) {\n for (const candidate of flowFileCandidates(dir, flowId)) {\n if (!contained(dir, candidate) || !fs.existsSync(candidate)) continue;\n let declaredId: string;\n try {\n declaredId = loadFlow(candidate).id;\n } catch (err) {\n opts.onMiss?.({\n path: candidate,\n reason: \"unparseable\",\n error: err instanceof Error ? err.message : String(err),\n });\n continue;\n }\n if (declaredId === flowId) return candidate;\n opts.onMiss?.({ path: candidate, reason: \"id-mismatch\", declaredId });\n }\n }\n const entry = loadAllFlowEntries(root, { onWarn: () => {} }).find((e) => e.flow.id === flowId);\n if (entry) return entry.path;\n }\n return undefined;\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { resolveSkWorkspaceConfig, readLinks, getGlobalCacheDir, sourceCacheKey } from './chunk-ORUHADS6.js';
2
- import { scanDirectory, tryWithFsDeadline } from './chunk-LFMX2UEF.js';
1
+ import { resolveSkWorkspaceConfig, readLinks, getGlobalCacheDir, sourceCacheKey } from './chunk-2W4LBLIN.js';
2
+ import { scanDirectory, tryWithFsDeadline } from './chunk-PA7WLID3.js';
3
3
  import { existsSync, readFileSync } from 'fs';
4
4
  import { lstat, stat } from 'fs/promises';
5
5
  import { createRequire } from 'module';
@@ -91,6 +91,7 @@ function resolvePackagedAssetsDir(subdir) {
91
91
  }
92
92
  return null;
93
93
  }
94
+ var CONNECTOR_SCAN_KINDS = /* @__PURE__ */ new Set(["connector"]);
94
95
  async function populate(projectDir, target) {
95
96
  target.catalogEntries = [];
96
97
  target.implicitRefs = [];
@@ -111,7 +112,11 @@ async function populate(projectDir, target) {
111
112
  }
112
113
  try {
113
114
  const repoName = name === FACTORY_ASSETS_OVERRIDE_REPO_NAME ? FACTORY_ASSETS_REPO_NAME : name;
114
- const scanned = await scanDirectory(repoDir, repoName);
115
+ const scanned = await scanDirectory(repoDir, repoName, {
116
+ knownKinds: CONNECTOR_SCAN_KINDS,
117
+ onDiagnostic: () => {
118
+ }
119
+ });
115
120
  const entries = scanned.filter((e) => e.kind === "connector");
116
121
  target.catalogEntries.push(...entries);
117
122
  } catch (err) {
@@ -219,5 +224,5 @@ function findCatalogEntry(entries, query) {
219
224
  }
220
225
 
221
226
  export { FACTORY_ASSETS_REPO_NAME, factoryAssetRoots, resolveFactoryAssetsRoot, resolveFactoryAssetsRootOrNull, resolvePackagedAssetsDir, resolveRuntimeAssets, resolveWorkspacesPackageRoot };
222
- //# sourceMappingURL=chunk-YK7WJSTD.js.map
223
- //# sourceMappingURL=chunk-YK7WJSTD.js.map
227
+ //# sourceMappingURL=chunk-BF33SCLY.js.map
228
+ //# sourceMappingURL=chunk-BF33SCLY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../core/src/runtime-assets.ts"],"names":["resolvePath","require"],"mappings":"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","file":"chunk-BF33SCLY.js","sourcesContent":["/**\n * Runtime asset resolution — read `skaile.yaml`, scan all declared repositories\n * (including the built-in `factory-assets/` directory as an implicit default),\n * and produce a unified view of connector catalog entries plus the implicit refs\n * that the `skaile.yaml` `connectors:` section adds to the dependency graph.\n *\n * This module is the single source of truth for \"which connectors does this\n * project see at runtime, and where do their implementations live on disk\".\n * Both the runner (serve, REPL, flow) and the platform's mid-session\n * `add_resource` flow consume `RuntimeAssetsResult.catalogEntries` and pass\n * it into `ConnectorManager` for catalog-based resolution.\n *\n * `factory-assets/` is the single first-party content tree (built-in connectors\n * + first-party skills + bundles) shipped inside the `@skaile/workspaces`\n * package — not a standalone package.\n *\n * It resolves to an **ordered list of roots** ({@link factoryAssetRoots}), not a\n * single dir. The bundled tree is always the baseline; an optional\n * `SKAILE_FACTORY_ASSETS_DIR` (legacy: `SKAILE_BASE_ASSETS_DIR`) is layered\n * **in front** as an additive override source — the agent container points it at\n * `/app/factory-assets/` (or a bind-mounted host dir) to ship updated skills /\n * flows / bundles / connector manifests without rebuilding the image. The two\n * roots resolve uniformly across every consumer (connector catalog scan, skill /\n * flow / completion discovery, the asset-manager factory source):\n * 1. `SKAILE_FACTORY_ASSETS_DIR` env dir, when set and existing (override layer).\n * 2. the bundled tree via {@link resolvePackagedAssetsDir} — the in-repo source\n * `packages/workspaces/factory-assets/` during dev, else the published\n * `dist/factory-assets/` after install (always-present baseline).\n *\n * Override semantics are **env-first**: on a name conflict the env root wins and\n * the bundled root fills the rest. Connector *code* still loads via the package's\n * static `exports` map, so the env root can override/add skills, flows, bundles,\n * and connector **manifests/metadata**, but cannot ship a new executable\n * connector — its `.js` is not on the package's import graph.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { lstat, stat } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, resolve as resolvePath } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { tryWithFsDeadline } from \"./fs-deadline.js\";\nimport { scanDirectory } from \"./manifest.js\";\nimport type { CatalogEntry } from \"./models.js\";\nimport { getGlobalCacheDir, readLinks, sourceCacheKey } from \"./repo-manager.js\";\nimport type { SourceDeclaration, SourceEntry } from \"./workspace-config.js\";\nimport { resolveSkWorkspaceConfig } from \"./workspace-config.js\";\n\n/**\n * Map declared `sources[]` to internal `SourceDeclaration`s keyed by the\n * collision-free {@link sourceCacheKey} (`<host>/<owner>/<repo>`), pointing at\n * the unified machine-cache clone path (`getGlobalCacheDir()/<key>/`). Keyed by\n * the same function every other cache writer/reader uses so the path resolves.\n */\nfunction sourcesToDeclarations(\n sources: SourceEntry[] | undefined,\n): Record<string, SourceDeclaration> {\n const sourcesDir = getGlobalCacheDir();\n const out: Record<string, SourceDeclaration> = {};\n for (const s of sources ?? []) {\n const key = sourceCacheKey(s.url);\n if (out[key]) continue;\n out[key] = { path: join(sourcesDir, key), url: s.url, branch: s.pin };\n }\n return out;\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/**\n * Catalog entry filtered to mount/connector kinds. Same shape as `CatalogEntry`.\n * @docLink packages/core/concepts#runtime-catalog-entry\n */\nexport type RuntimeCatalogEntry = CatalogEntry;\n\n/**\n * Implicit catalog reference derived from a `connectors:` declaration in `skaile.yaml`.\n * Each connector driver becomes an implicit ref that must be resolved in the catalog.\n * @docLink packages/core/concepts#runtime-asset-ref\n */\nexport interface RuntimeAssetRef {\n kind: \"connector\";\n /** Driver name — matches `RuntimeCatalogEntry.name`. */\n name: string;\n /** Source declaration id from `skaile.yaml`. */\n declarationId: string;\n}\n\n/**\n * Aggregated npm packages required by all resolved mount/connector adapters.\n * Populated from `metadata.npm_deps` in each matched catalog entry.\n * @docLink packages/core/concepts#runtime-npm-deps\n */\nexport interface RuntimeNpmDeps {\n required: string[];\n optional: string[];\n}\n\n/**\n * Non-fatal warning emitted during `resolveRuntimeAssets` when a repo is unavailable\n * or a driver is not found in any catalog.\n * @docLink packages/core/concepts#runtime-asset-warning\n */\nexport interface RuntimeAssetWarning {\n /** Stable code for filtering / structured logging. */\n code: \"missing_driver\" | \"repo_unavailable\" | \"invalid_repo_decl\";\n message: string;\n /** Declaration id when applicable. */\n declarationId?: string;\n /** Driver / repository name when applicable. */\n name?: string;\n}\n\n/**\n * Repository name used for the implicit built-in `factory-assets` catalog entry\n * (the in-package connector tree).\n * @docLink packages/core/concepts#factory-assets-repo-name\n */\nexport const FACTORY_ASSETS_REPO_NAME = \"factory-assets\";\n\n/**\n * Repository name for the optional `SKAILE_FACTORY_ASSETS_DIR` override layer,\n * scanned ahead of (and overriding) the bundled {@link FACTORY_ASSETS_REPO_NAME}.\n */\nconst FACTORY_ASSETS_OVERRIDE_REPO_NAME = \"factory-assets:override\";\n\n/**\n * Result of `resolveRuntimeAssets`.\n * The same object is mutated in place by `refresh()`, allowing callers to hold\n * a stable reference and observe updates after a new repository is cloned or\n * a driver is installed mid-session.\n * @docLink packages/core/concepts#runtime-assets-result\n */\nexport interface RuntimeAssetsResult {\n catalogEntries: RuntimeCatalogEntry[];\n implicitRefs: RuntimeAssetRef[];\n requiredNpmDeps: RuntimeNpmDeps;\n warnings: RuntimeAssetWarning[];\n /** Re-scan repositories and re-derive implicit refs. Mutates in place. */\n refresh(): Promise<void>;\n /**\n * Catalog lookup. When `kind` is omitted and multiple entries share the\n * `name`, returns `undefined` (caller must disambiguate).\n */\n findEntry(query: { kind?: \"connector\"; name: string }): RuntimeCatalogEntry | undefined;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Resolve all runtime assets visible to a project by scanning declared repositories.\n *\n * Reads `skaile.yaml`, scans every declared repository (plus the implicit\n * built-in `factory-assets` repo), and derives implicit refs from `mounts:` /\n * `connectors:` declarations. Does not clone or install anything — purely a\n * read-only scan of what is already on disk. URL-only repositories that have\n * not been cloned yet are reported as `repo_unavailable` warnings.\n *\n * @param projectDir - Absolute path to the project workspace root\n * @returns `RuntimeAssetsResult` with catalog entries, implicit refs, npm deps, and warnings\n * @docLink packages/core/concepts#resolve-runtime-assets\n */\nexport async function resolveRuntimeAssets(projectDir: string): Promise<RuntimeAssetsResult> {\n const result: RuntimeAssetsResult = {\n catalogEntries: [],\n implicitRefs: [],\n requiredNpmDeps: { required: [], optional: [] },\n warnings: [],\n refresh: async () => {\n await populate(projectDir, result);\n },\n findEntry: (query) => findCatalogEntry(result.catalogEntries, query),\n };\n\n await populate(projectDir, result);\n return result;\n}\n\n/**\n * Resolve the ordered list of on-disk roots for the built-in `factory-assets`\n * tree (built-in connectors + first-party skills + bundles). This is the single\n * shared resolver every consumer goes through, so the env override and the\n * bundled baseline are honoured uniformly.\n *\n * Order (env-first = override-wins):\n * 1. `SKAILE_FACTORY_ASSETS_DIR` env dir (legacy: `SKAILE_BASE_ASSETS_DIR`),\n * when set and existing — an additive override layer.\n * 2. {@link resolvePackagedAssetsDir} — the bundled tree (in-repo source in dev,\n * `dist/factory-assets/` after install). Always-present baseline.\n *\n * Returns `[]` only when the package cannot be located at all. De-duplicated, so\n * pointing the env var at the bundled dir collapses to one root.\n *\n * @docLink packages/core/concepts#resolve-factory-assets-root\n */\nexport function factoryAssetRoots(): string[] {\n const roots: string[] = [];\n const envDir = process.env.SKAILE_FACTORY_ASSETS_DIR ?? process.env.SKAILE_BASE_ASSETS_DIR;\n // Deliberately still synchronous after #454: both candidates are\n // container-local (the image's `/app/factory-assets/`, or the installed\n // package tree resolved by `resolvePackagedAssetsDir`), never the FUSE\n // workspace mount. The mount-reachable probes on this module's scan path —\n // the project-relative `sources[].path` candidates in `resolveRepoDir` — are\n // async and deadline-bounded.\n if (envDir && existsSync(envDir)) roots.push(resolvePath(envDir));\n const bundled = resolvePackagedAssetsDir(\"factory-assets\");\n if (bundled) roots.push(bundled);\n return [...new Set(roots)];\n}\n\n/**\n * Resolve the primary on-disk root of the `factory-assets` tree — the first of\n * {@link factoryAssetRoots} (the env override when set, else the bundled tree).\n * Prefer {@link factoryAssetRoots} when you need to scan every layer; this\n * single-dir form is for callers that want one canonical path.\n *\n * @returns Absolute path to the highest-precedence `factory-assets` directory\n * @throws When no root can be located\n * @docLink packages/core/concepts#resolve-factory-assets-root\n */\nexport function resolveFactoryAssetsRoot(): string {\n const hit = resolveFactoryAssetsRootOrNull();\n if (hit) return hit;\n\n throw new Error(\n `Cannot resolve the factory-assets directory. ` +\n `Set SKAILE_FACTORY_ASSETS_DIR to the on-disk path, ` +\n `ensure @skaile/workspaces is installed, ` +\n `or run from within the @skaile/workspaces package tree.`,\n );\n}\n\n/**\n * Non-throwing variant of {@link resolveFactoryAssetsRoot}: the same\n * env-then-packaged resolution tiers, returning `null` instead of throwing when\n * none locate the directory. Callers that treat a missing factory tree as a\n * soft \"not present\" (e.g. the asset-manager's implicit-source injection) MUST\n * use this so they honour the `SKAILE_FACTORY_ASSETS_DIR` container override\n * identically to the runtime path.\n */\nexport function resolveFactoryAssetsRootOrNull(): string | null {\n return factoryAssetRoots()[0] ?? null;\n}\n\n/**\n * Resolve the `@skaile/workspaces` package root — the directory containing its\n * `package.json`. Tries `require.resolve` first (works when installed as a\n * dependency *and* in-repo via the self-reference), then walks upward from this\n * module looking for a `package.json` whose `name` is `@skaile/workspaces`\n * (bounded to 8 levels). Returns `null` when neither locates it.\n *\n * The single source of truth for finding content shipped inside the package —\n * the unified `factory-assets/` tree (built-in connectors + first-party skills\n * + bundles) resolves through {@link resolvePackagedAssetsDir} on top of this.\n *\n * Memoized: the package location is immutable for the process lifetime, but\n * this sits on the CLI hot path (every `findSkills` / flow / completion call\n * funnels through here), so the `require.resolve` + upward `package.json` walk\n * runs once. `undefined` = not yet computed.\n *\n * @docLink packages/core/concepts#resolve-factory-assets-root\n */\nlet workspacesPackageRootCache: string | null | undefined;\n\nexport function resolveWorkspacesPackageRoot(): string | null {\n if (workspacesPackageRootCache !== undefined) return workspacesPackageRootCache;\n workspacesPackageRootCache = computeWorkspacesPackageRoot();\n return workspacesPackageRootCache;\n}\n\nfunction computeWorkspacesPackageRoot(): string | null {\n try {\n const require = createRequire(import.meta.url);\n return dirname(require.resolve(\"@skaile/workspaces/package.json\"));\n } catch {\n // Fall through to the workspace walk.\n }\n let dir: string;\n try {\n dir = dirname(fileURLToPath(import.meta.url));\n } catch {\n return null;\n }\n for (let i = 0; i < 8; i++) {\n const pkgPath = join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as { name?: string };\n if (pkg.name === \"@skaile/workspaces\") return dir;\n } catch {\n // Ignore malformed package.json and keep walking.\n }\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Locate a content-asset directory inside the package. Prefers the in-repo\n * **source** dir `<pkgRoot>/<subdir>` when present — in a dev checkout it is the\n * full tree (e.g. `factory-assets/` keeps the connector `.ts` entry files that\n * `dist/` does not) — then the published `dist/<subdir>` copy (what\n * `files: [\"dist\"]` ships, the only one present after `npm i`). Returns `null`\n * when neither exists.\n *\n * `factory-assets/` resolves to the source tree in dev (code + skills + bundles)\n * and to `dist/factory-assets` post-install (compiled connectors + copied\n * manifests/skills/bundles).\n *\n * @param subdir - `\"factory-assets\"` | …\n * @docLink packages/core/concepts#resolve-factory-assets-root\n */\nexport function resolvePackagedAssetsDir(subdir: string): string | null {\n const root = resolveWorkspacesPackageRoot();\n if (!root) return null;\n for (const cand of [join(root, subdir), join(root, \"dist\", subdir)]) {\n if (existsSync(cand)) return cand;\n }\n return null;\n}\n\n// ─── Internals ────────────────────────────────────────────────────────────────\n\nconst CONNECTOR_SCAN_KINDS: ReadonlySet<string> = new Set([\"connector\"]);\n\nasync function populate(projectDir: string, target: RuntimeAssetsResult): Promise<void> {\n target.catalogEntries = [];\n target.implicitRefs = [];\n target.requiredNpmDeps = { required: [], optional: [] };\n target.warnings = [];\n\n const config = resolveSkWorkspaceConfig(projectDir);\n // Connector catalog scan runs over the project's declared sources[] (resolved\n // to their machine-cache clone paths) plus the implicit factory-assets repo.\n const repositories = buildEffectiveRepositories(sourcesToDeclarations(config.sources));\n const links = readLinks(projectDir);\n\n // Scan each repository for connector entries.\n for (const [name, decl] of Object.entries(repositories)) {\n const repoDir = await resolveRepoDir(name, decl, projectDir, links);\n if (!repoDir) {\n target.warnings.push({\n code: \"repo_unavailable\",\n name,\n message: repoUnavailableMessage(name, decl),\n });\n continue;\n }\n try {\n // Both factory layers carry the same `factory-assets` provenance — the\n // override repo is an internal scan-order device, not a distinct source.\n const repoName = name === FACTORY_ASSETS_OVERRIDE_REPO_NAME ? FACTORY_ASSETS_REPO_NAME : name;\n // Only connector descriptors are consumed here, so only that kind is\n // \"known\": typed manifests of any other kind are irrelevant to this scan.\n const scanned = await scanDirectory(repoDir, repoName, {\n knownKinds: CONNECTOR_SCAN_KINDS,\n onDiagnostic: () => {},\n });\n const entries = scanned.filter((e) => e.kind === \"connector\");\n target.catalogEntries.push(...entries);\n } catch (err) {\n target.warnings.push({\n code: \"repo_unavailable\",\n name,\n message: `Failed to scan repository \"${name}\" at ${repoDir}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n });\n }\n }\n\n // De-duplicate by (kind, name), keeping the first occurrence. Scan order is\n // declared sources → env override → bundled baseline, so an env-supplied\n // connector manifest overrides the bundled one and the bundled one fills the\n // rest (the override layer can refresh built-in manifests in place).\n const seen = new Set<string>();\n target.catalogEntries = target.catalogEntries.filter((e) => {\n const key = `${e.kind}:${e.name}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n\n // Derive implicit refs from skaile.yaml connectors.\n for (const c of config.connectors ?? []) {\n target.implicitRefs.push({ kind: \"connector\", name: c.driver, declarationId: c.id });\n }\n\n // Validate refs and aggregate npm deps.\n const requiredSet = new Set<string>();\n const optionalSet = new Set<string>();\n for (const ref of target.implicitRefs) {\n const entry = findCatalogEntry(target.catalogEntries, ref);\n if (!entry) {\n target.warnings.push({\n code: \"missing_driver\",\n declarationId: ref.declarationId,\n name: ref.name,\n message:\n `Unknown ${ref.kind} driver \"${ref.name}\" referenced by ${ref.kind} \"${ref.declarationId}\". ` +\n `Run \\`skaile ${ref.kind} catalog\\` to see available drivers, ` +\n `or declare a repository in skaile.yaml that provides this driver.`,\n });\n continue;\n }\n const npm = (entry.metadata?.npm_deps ?? {}) as { required?: string[]; optional?: string[] };\n for (const p of npm.required ?? []) requiredSet.add(p);\n for (const p of npm.optional ?? []) optionalSet.add(p);\n }\n target.requiredNpmDeps.required = [...requiredSet];\n target.requiredNpmDeps.optional = [...optionalSet];\n}\n\n/**\n * Build the effective `repositories` map: caller's declarations first, then the\n * implicit built-in `factory-assets` repos. Each {@link factoryAssetRoots} layer\n * becomes its own repo, the env override inserted **before** the bundled\n * baseline so its connector entries win on the first-match dedup downstream.\n * When the package cannot be located at all, a path-less sentinel under\n * {@link FACTORY_ASSETS_REPO_NAME} drives the `repo_unavailable` warning.\n */\nfunction buildEffectiveRepositories(\n declared: Record<string, SourceDeclaration> | undefined,\n): Record<string, SourceDeclaration> {\n const result: Record<string, SourceDeclaration> = { ...(declared ?? {}) };\n const roots = factoryAssetRoots();\n if (roots.length === 0) {\n // Surface as a warning during scan rather than throwing here — let the\n // caller decide whether factory-assets is required. resolveRepoDir() /\n // repoUnavailableMessage re-discover the failure and emit it.\n if (!result[FACTORY_ASSETS_REPO_NAME]) result[FACTORY_ASSETS_REPO_NAME] = { path: \"\" };\n return result;\n }\n // override-first when both layers exist, so the env root's entries are scanned\n // (and matched) ahead of the bundled baseline.\n const keys =\n roots.length > 1\n ? [FACTORY_ASSETS_OVERRIDE_REPO_NAME, FACTORY_ASSETS_REPO_NAME]\n : [FACTORY_ASSETS_REPO_NAME];\n roots.forEach((dir, i) => {\n const key = keys[i] ?? `${FACTORY_ASSETS_REPO_NAME}:${i}`;\n if (!result[key]) result[key] = { path: dir };\n });\n return result;\n}\n\n/**\n * Resolve a repository declaration to an on-disk directory. Order:\n * 1. Linked override (`.skaile/links.yaml`).\n * 2. Local `path` — relative to `projectDir`.\n * 3. Cloned URL repo at `.skaile/cache/sources/<name>/` (must already exist).\n *\n * Returns `null` when none of these resolve. Does not clone.\n *\n * **Async and deadline-bounded since #454.** Every candidate here is a\n * project-relative or operator-supplied path, so a `sources[].path` of\n * `workspace/my-assets` resolves onto the rclone FUSE mount — the same tree the\n * scan that follows walks. Probing it with `existsSync`/`lstatSync` would park\n * the `skaile serve` event loop *before* the (now async) scan ever ran, which\n * would leave the H2 fix meaningless on the very declaration that triggers it.\n * A probe that misses its deadline reads as \"unavailable\", which is what the\n * caller already does with an absent path — it becomes a `repo_unavailable`\n * warning rather than a stall.\n */\nasync function resolveRepoDir(\n name: string,\n decl: SourceDeclaration,\n projectDir: string,\n links: Record<string, string>,\n): Promise<string | null> {\n // 1. Linked override\n const linked = links[name];\n if (linked && (await pathExists(linked))) return linked;\n\n // 2. Local path\n if (decl.path) {\n const resolved = resolvePath(projectDir, decl.path);\n return (await pathExists(resolved)) ? resolved : null;\n }\n\n // 3. URL repo cloned to project's .skaile/cache/sources/<name> — the\n // project-local clone dir (often a symlink into the global cache, which\n // lives at getGlobalCacheDir()); NOT the global clone root itself.\n if (decl.url) {\n const projectDest = join(projectDir, \".skaile\", \"cache\", \"sources\", name);\n // One `lstat` answers both questions the pre-#454 `existsSync` + `lstatSync`\n // pair asked, and `lstat` (not `stat`) keeps the \"a symlink into the global\n // cache counts\" behaviour intact.\n const found = await tryWithFsDeadline(\n `lstat ${projectDest}`,\n async () => {\n await lstat(projectDest);\n return true;\n },\n false,\n );\n return found ? projectDest : null;\n }\n\n return null;\n}\n\n/** Deadline-bounded `existsSync` replacement — a wedged mount reads as absent. */\nfunction pathExists(path: string): Promise<boolean> {\n return tryWithFsDeadline(\n `stat ${path}`,\n async () => {\n await stat(path);\n return true;\n },\n false,\n );\n}\n\nfunction repoUnavailableMessage(name: string, decl: SourceDeclaration): string {\n if (name === FACTORY_ASSETS_REPO_NAME && !decl.path && !decl.url) {\n return (\n `Cannot resolve the built-in factory-assets. ` +\n `Set SKAILE_FACTORY_ASSETS_DIR or ensure @skaile/workspaces is installed.`\n );\n }\n if (decl.url) {\n return `Repository \"${name}\" (${decl.url}) is not available. Register it as a Library Source via \\`skaile source add\\`.`;\n }\n if (decl.path) {\n return `Repository \"${name}\" path not found: ${decl.path}`;\n }\n return `Repository \"${name}\" has neither url nor path.`;\n}\n\nfunction findCatalogEntry(\n entries: RuntimeCatalogEntry[],\n query: { kind?: \"connector\"; name: string },\n): RuntimeCatalogEntry | undefined {\n if (query.kind) {\n return entries.find((e) => e.kind === query.kind && e.name === query.name);\n }\n const matches = entries.filter((e) => e.name === query.name);\n if (matches.length === 1) return matches[0];\n // 0 or >1 with no kind — caller must disambiguate.\n return undefined;\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { compositeSha256 } from './chunk-SR4RFKHM.js';
2
- import { parseAssetRef } from './chunk-WX74MVNA.js';
1
+ import { compositeSha256 } from './chunk-7ZHLYXTI.js';
2
+ import { parseAssetRef } from './chunk-AO7VJ6G6.js';
3
3
  import { createHash } from 'crypto';
4
4
  import { rm, mkdir, writeFile } from 'fs/promises';
5
5
  import { isAbsolute, resolve, sep, join, dirname } from 'path';
@@ -123,5 +123,5 @@ async function installFlat(manifest, targetDir, fetcher) {
123
123
  }
124
124
 
125
125
  export { assertSafeManifestPath, installFromManifest, longestCommonDirPrefix };
126
- //# sourceMappingURL=chunk-VKSA2CDJ.js.map
127
- //# sourceMappingURL=chunk-VKSA2CDJ.js.map
126
+ //# sourceMappingURL=chunk-BTISGSK4.js.map
127
+ //# sourceMappingURL=chunk-BTISGSK4.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../library/src/install/install-from-manifest.ts"],"names":[],"mappings":"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","file":"chunk-VKSA2CDJ.js","sourcesContent":["/**\n * Pointer-only install path.\n *\n * Given an {@link InstallManifest} (the Pointer Triple the Catalog hands\n * clients), this:\n *\n * 1. fetches the asset bytes directly from the upstream repo at the pinned\n * commit (via an injectable fetcher, default {@link fetchAssetFilesFromGitHub});\n * 2. verifies EVERY per-file SHA256 against `manifest.files[].sha256`;\n * 3. verifies the composite SHA256 rollup over the sorted\n * `<path>:<sha256>\\n` lines against `manifest.sha256`;\n * 4. writes the verified bytes under `<libraryRoot>/@<publisher>/<name>/<version>`.\n *\n * Any hash mismatch is a hard failure — bytes are not written if per-file\n * verification fails, and the composite check is the second gate.\n *\n * @docLink packages/library/concepts#install\n */\n\nimport { createHash } from \"node:crypto\";\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, resolve, sep } from \"node:path\";\nimport type { InstallManifest } from \"@skaile/workspaces/types\";\n// Narrow module, not the `core` barrel: the barrel's chunks carry `import.meta`,\n// which breaks consumers that transpile this entry to CommonJS.\nimport { parseAssetRef } from \"../../../core/src/models.js\";\nimport { compositeSha256 } from \"../../../core/src/publish-manifest.js\";\n\n/**\n * Validate a single manifest-supplied file path against path traversal.\n *\n * `manifest.files[].path` comes off the network — the attacker controls the\n * entire manifest (and therefore every hash in it), so hash verification can\n * NEVER mitigate a malicious *destination*. A path like\n * `../../../../home/user/.bashrc` or an absolute path would escape\n * `installPath` and yield an arbitrary file write. Every path is checked\n * BEFORE any fetch or write happens; the first bad path aborts the entire\n * install with a hard throw.\n *\n * A path is rejected if ANY of:\n * - it is empty;\n * - it is absolute (`path.isAbsolute`) or has a leading slash;\n * - it contains a `..` segment;\n * - `path.resolve(installPath, p)` is not `installPath` itself and does not\n * start with `installPath + path.sep` (escapes the install dir).\n *\n * @throws An error matching `/unsafe path in manifest/` on the first bad path.\n */\nexport function assertSafeManifestPath(installPath: string, p: string): void {\n const bad = (): never => {\n throw new Error(`unsafe path in manifest: ${p}`);\n };\n if (!p || p.length === 0) bad();\n if (isAbsolute(p) || p.startsWith(\"/\") || p.startsWith(\"\\\\\")) bad();\n const segments = p.split(/[/\\\\]/);\n if (segments.some((s) => s === \"..\")) bad();\n const resolved = resolve(installPath, p);\n if (resolved !== installPath && !resolved.startsWith(installPath + sep)) bad();\n}\n\n/**\n * Validate one component (publisher / name / version) of the attacker-controlled\n * `manifest.ref`.\n *\n * `installPath` is built by joining these components onto `libraryRoot`. A\n * component containing a path separator or a `..` / leading-dot segment would\n * let `installPath` itself escape `libraryRoot` — yielding an arbitrary file\n * write AND, via the pre-write `rm(installPath, { recursive })`, an arbitrary\n * recursive delete. The per-file `assertSafeManifestPath` guard cannot catch\n * this: it only validates each `f.path` *relative to* `installPath`, never\n * `installPath` itself. Components must be plain identifier-like strings.\n *\n * @throws An error matching `/unsafe ref/` on a bad component.\n */\nfunction assertSafeRefComponent(kind: string, value: string): void {\n // Reject empty, leading-dot (covers `.` and `..`), path separators, and\n // ASCII control characters (NUL et al.) — fails a malformed segment fast\n // with a domain-specific error rather than a raw EINVAL deeper in.\n const hasControlChar = [...value].some((c) => c.charCodeAt(0) < 0x20);\n if (!value || value.startsWith(\".\") || /[/\\\\]/.test(value) || hasControlChar) {\n throw new Error(`unsafe ref ${kind} component in manifest: '${value}'`);\n }\n}\n\n/**\n * Longest common **directory** prefix across manifest paths, compared by whole\n * slash-delimited segments (never raw-string — so `app/` and `app-data/` never\n * collide). Each path's basename is excluded, so the result is always a\n * directory prefix and every path keeps a non-empty remainder after stripping.\n *\n * Used by flat mode to reproduce the platform pointer-installer's asset-rooting:\n * the store persists repo-root-relative paths (e.g. `skaile-platform/mcpo/xls/MCP.md`)\n * but the runner scans `.skaile/assets/<kind>/<name>/` for immediate-child files,\n * so this prefix is stripped from the WRITE path while the fetch keeps the full\n * repo path. Returns `''` when there is no common directory (a no-op strip).\n */\nexport function longestCommonDirPrefix(paths: readonly string[]): string {\n if (paths.length === 0) return \"\";\n const dirSegments = paths.map((p) => p.split(\"/\").slice(0, -1));\n let common = dirSegments[0]!;\n for (let i = 1; i < dirSegments.length && common.length > 0; i++) {\n const segs = dirSegments[i]!;\n let n = 0;\n while (n < common.length && n < segs.length && common[n] === segs[n]) n++;\n common = common.slice(0, n);\n }\n return common.join(\"/\");\n}\n\n/**\n * Fetcher signature — fetches `{ path → Buffer }` for the requested paths at\n * a pinned upstream commit. {@link fetchAssetFilesFromGitHub} is the default\n * production implementation; tests inject a mock.\n */\nexport type AssetFetcher = (opts: {\n url: string;\n commitSha: string;\n paths: string[];\n}) => Promise<Record<string, Buffer>>;\n\n/**\n * Options for {@link installFromManifest}.\n */\nexport interface InstallOpts {\n /** The pointer-only install manifest from the Catalog. */\n manifest: InstallManifest;\n /** Filesystem root the asset is installed under (ref-derived mode). */\n libraryRoot: string;\n /**\n * Pluggable fetcher so tests can inject mock data. Defaults to\n * {@link fetchAssetFilesFromGitHub} in production.\n */\n fetcher?: AssetFetcher;\n /**\n * Flat-layout mode. When set, install-core reproduces the platform\n * pointer-installer's behavior: it ignores `libraryRoot`/ref-derivation, does\n * NOT parse `manifest.ref` and does NOT verify the composite sha256, strips\n * the longest-common-dir prefix from each path, per-file sha256-verifies, and\n * writes the stripped paths as immediate children of `targetDir` (what the\n * runner's `.skaile/assets/<kind>/<name>/` scan requires). `installPath` is\n * `targetDir`. Absent → unchanged ref-derived `@<pub>/name/version/<path>`\n * layout with composite verify.\n */\n targetDir?: string;\n}\n\n/**\n * Result of a successful {@link installFromManifest} call.\n */\nexport interface InstallResult {\n /** Absolute path the asset files were written to. */\n installPath: string;\n}\n\n/**\n * Fetch, verify, and write an asset's files per its {@link InstallManifest}.\n *\n * @throws An error matching `/hash mismatch/i` if any per-file SHA256 differs.\n * @throws An error matching `/composite hash mismatch/i` if the rollup differs.\n * @throws An error if the ref is malformed or the fetcher omits a file.\n */\nexport async function installFromManifest(opts: InstallOpts): Promise<InstallResult> {\n const { manifest, libraryRoot } = opts;\n const fetcher =\n opts.fetcher ?? (await import(\"./source-fetch-github.js\")).fetchAssetFilesFromGitHub;\n\n // Flat mode: reproduce the platform pointer-installer's asset-rooted layout.\n // No ref parse, no composite verify — the platform store may not satisfy a\n // ref-grammar or composite, and the runner only needs immediate-child files.\n if (opts.targetDir !== undefined) {\n return installFlat(manifest, opts.targetDir, fetcher);\n }\n\n // 1. Parse ref into install path: `skill:@x/git#1.0.0` → `<root>/@x/git/1.0.0`.\n // Done first so the C1 path-traversal guard can resolve against installPath\n // BEFORE any network fetch happens. The ref is attacker-controlled, so each\n // segment is further validated as a safe path component (H1) after parsing.\n // `parseAssetRef` is the single canonical grammar (`kind:@publisher/name#version`);\n // the legacy trailing-`@version` shape was removed in core and is rejected here.\n let parsed: ReturnType<typeof parseAssetRef>;\n try {\n parsed = parseAssetRef(manifest.ref);\n } catch (e) {\n throw new Error(`invalid ref: ${manifest.ref}: ${e instanceof Error ? e.message : String(e)}`);\n }\n const publisher = parsed.publisher;\n const name = parsed.name;\n const version = parsed.pin;\n if (!publisher) throw new Error(`invalid ref: ${manifest.ref} (missing publisher)`);\n if (!version) throw new Error(`invalid ref: ${manifest.ref} (missing version pin)`);\n assertSafeRefComponent(\"publisher\", publisher);\n assertSafeRefComponent(\"name\", name);\n assertSafeRefComponent(\"version\", version);\n const root = resolve(libraryRoot);\n const installPath = resolve(join(root, `@${publisher}`, name, version));\n // Defense in depth: even with the segment guards above, assert the built\n // installPath stays strictly inside libraryRoot before any write or `rm`.\n if (installPath !== root && !installPath.startsWith(root + sep)) {\n throw new Error(`unsafe install path: ref '${manifest.ref}' resolves outside the library root`);\n }\n\n // 2. [C1] Validate EVERY manifest path against traversal BEFORE fetching.\n // The attacker controls the manifest (and thus all hashes) — hashes verify\n // content, never destination. Reject the whole install on the first bad path.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n }\n\n // 3. Fetch all files at the pinned commit.\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // 4. Verify per-file SHA256 — hard fail before writing anything. The path\n // key used to read from the fetcher result is re-guarded as defense in depth.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n }\n\n // 5. Verify composite SHA256 over the sorted `<path>:<sha256>\\n` lines.\n const actualComposite = compositeSha256(manifest.files);\n if (actualComposite !== manifest.sha256) {\n throw new Error(`composite hash mismatch: expected ${manifest.sha256}, got ${actualComposite}`);\n }\n\n // 6. [M1] Write all verified files. A failed install must leave NO partial\n // directory: any prior `installPath` is removed first (clean overwrite), and\n // a mid-loop write failure removes the partially-written tree before\n // rethrowing.\n await rm(installPath, { recursive: true, force: true });\n try {\n for (const f of manifest.files) {\n const target = join(installPath, f.path);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, bytes[f.path]!);\n }\n } catch (e) {\n await rm(installPath, { recursive: true, force: true }).catch(() => {});\n throw e;\n }\n\n return { installPath };\n}\n\n/**\n * Flat-layout install — the platform pointer-installer's behavior, made canonical\n * in install-core. Validates every path, fetches with the FULL repo paths, per-file\n * sha256-verifies, then strips the longest-common-dir prefix and writes each file\n * as `join(targetDir, path.slice(assetRoot.length + 1))` — immediate children of\n * `targetDir`. No ref parse, no composite check.\n */\nasync function installFlat(\n manifest: InstallManifest,\n targetDir: string,\n fetcher: AssetFetcher,\n): Promise<InstallResult> {\n const target = resolve(targetDir);\n\n // Gate every path before any fetch — the attacker controls the whole manifest.\n for (const f of manifest.files) {\n assertSafeManifestPath(target, f.path);\n }\n\n // Fetch keys off the FULL repo path (matches the upstream tree).\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // Strip the asset-root dir prefix from the WRITE path only — the fetch above\n // still keyed off the full repo path. Stripping removes leading whole segments\n // (never the basename), so a non-empty remainder always survives.\n const assetRoot = longestCommonDirPrefix(paths);\n\n for (const f of manifest.files) {\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n const relPath = assetRoot ? f.path.slice(assetRoot.length + 1) : f.path;\n // Re-guard the post-strip destination — it is what we actually write.\n assertSafeManifestPath(target, relPath);\n const dest = join(target, relPath);\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, buf);\n }\n\n return { installPath: target };\n}\n"]}
1
+ {"version":3,"sources":["../library/src/install/install-from-manifest.ts"],"names":[],"mappings":"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","file":"chunk-BTISGSK4.js","sourcesContent":["/**\n * Pointer-only install path.\n *\n * Given an {@link InstallManifest} (the Pointer Triple the Catalog hands\n * clients), this:\n *\n * 1. fetches the asset bytes directly from the upstream repo at the pinned\n * commit (via an injectable fetcher, default {@link fetchAssetFilesFromGitHub});\n * 2. verifies EVERY per-file SHA256 against `manifest.files[].sha256`;\n * 3. verifies the composite SHA256 rollup over the sorted\n * `<path>:<sha256>\\n` lines against `manifest.sha256`;\n * 4. writes the verified bytes under `<libraryRoot>/@<publisher>/<name>/<version>`.\n *\n * Any hash mismatch is a hard failure — bytes are not written if per-file\n * verification fails, and the composite check is the second gate.\n *\n * @docLink packages/library/concepts#install\n */\n\nimport { createHash } from \"node:crypto\";\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, resolve, sep } from \"node:path\";\nimport type { InstallManifest } from \"@skaile/workspaces/types\";\n// Narrow module, not the `core` barrel: the barrel's chunks carry `import.meta`,\n// which breaks consumers that transpile this entry to CommonJS.\nimport { parseAssetRef } from \"../../../core/src/models.js\";\nimport { compositeSha256 } from \"../../../core/src/publish-manifest.js\";\n\n/**\n * Validate a single manifest-supplied file path against path traversal.\n *\n * `manifest.files[].path` comes off the network — the attacker controls the\n * entire manifest (and therefore every hash in it), so hash verification can\n * NEVER mitigate a malicious *destination*. A path like\n * `../../../../home/user/.bashrc` or an absolute path would escape\n * `installPath` and yield an arbitrary file write. Every path is checked\n * BEFORE any fetch or write happens; the first bad path aborts the entire\n * install with a hard throw.\n *\n * A path is rejected if ANY of:\n * - it is empty;\n * - it is absolute (`path.isAbsolute`) or has a leading slash;\n * - it contains a `..` segment;\n * - `path.resolve(installPath, p)` is not `installPath` itself and does not\n * start with `installPath + path.sep` (escapes the install dir).\n *\n * @throws An error matching `/unsafe path in manifest/` on the first bad path.\n */\nexport function assertSafeManifestPath(installPath: string, p: string): void {\n const bad = (): never => {\n throw new Error(`unsafe path in manifest: ${p}`);\n };\n if (!p || p.length === 0) bad();\n if (isAbsolute(p) || p.startsWith(\"/\") || p.startsWith(\"\\\\\")) bad();\n const segments = p.split(/[/\\\\]/);\n if (segments.some((s) => s === \"..\")) bad();\n const resolved = resolve(installPath, p);\n if (resolved !== installPath && !resolved.startsWith(installPath + sep)) bad();\n}\n\n/**\n * Validate one component (publisher / name / version) of the attacker-controlled\n * `manifest.ref`.\n *\n * `installPath` is built by joining these components onto `libraryRoot`. A\n * component containing a path separator or a `..` / leading-dot segment would\n * let `installPath` itself escape `libraryRoot` — yielding an arbitrary file\n * write AND, via the pre-write `rm(installPath, { recursive })`, an arbitrary\n * recursive delete. The per-file `assertSafeManifestPath` guard cannot catch\n * this: it only validates each `f.path` *relative to* `installPath`, never\n * `installPath` itself. Components must be plain identifier-like strings.\n *\n * @throws An error matching `/unsafe ref/` on a bad component.\n */\nfunction assertSafeRefComponent(kind: string, value: string): void {\n // Reject empty, leading-dot (covers `.` and `..`), path separators, and\n // ASCII control characters (NUL et al.) — fails a malformed segment fast\n // with a domain-specific error rather than a raw EINVAL deeper in.\n const hasControlChar = [...value].some((c) => c.charCodeAt(0) < 0x20);\n if (!value || value.startsWith(\".\") || /[/\\\\]/.test(value) || hasControlChar) {\n throw new Error(`unsafe ref ${kind} component in manifest: '${value}'`);\n }\n}\n\n/**\n * Longest common **directory** prefix across manifest paths, compared by whole\n * slash-delimited segments (never raw-string — so `app/` and `app-data/` never\n * collide). Each path's basename is excluded, so the result is always a\n * directory prefix and every path keeps a non-empty remainder after stripping.\n *\n * Used by flat mode to reproduce the platform pointer-installer's asset-rooting:\n * the store persists repo-root-relative paths (e.g. `skaile-platform/mcpo/xls/MCP.md`)\n * but the runner scans `.skaile/assets/<kind>/<name>/` for immediate-child files,\n * so this prefix is stripped from the WRITE path while the fetch keeps the full\n * repo path. Returns `''` when there is no common directory (a no-op strip).\n */\nexport function longestCommonDirPrefix(paths: readonly string[]): string {\n if (paths.length === 0) return \"\";\n const dirSegments = paths.map((p) => p.split(\"/\").slice(0, -1));\n let common = dirSegments[0]!;\n for (let i = 1; i < dirSegments.length && common.length > 0; i++) {\n const segs = dirSegments[i]!;\n let n = 0;\n while (n < common.length && n < segs.length && common[n] === segs[n]) n++;\n common = common.slice(0, n);\n }\n return common.join(\"/\");\n}\n\n/**\n * Fetcher signature — fetches `{ path → Buffer }` for the requested paths at\n * a pinned upstream commit. {@link fetchAssetFilesFromGitHub} is the default\n * production implementation; tests inject a mock.\n */\nexport type AssetFetcher = (opts: {\n url: string;\n commitSha: string;\n paths: string[];\n}) => Promise<Record<string, Buffer>>;\n\n/**\n * Options for {@link installFromManifest}.\n */\nexport interface InstallOpts {\n /** The pointer-only install manifest from the Catalog. */\n manifest: InstallManifest;\n /** Filesystem root the asset is installed under (ref-derived mode). */\n libraryRoot: string;\n /**\n * Pluggable fetcher so tests can inject mock data. Defaults to\n * {@link fetchAssetFilesFromGitHub} in production.\n */\n fetcher?: AssetFetcher;\n /**\n * Flat-layout mode. When set, install-core reproduces the platform\n * pointer-installer's behavior: it ignores `libraryRoot`/ref-derivation, does\n * NOT parse `manifest.ref` and does NOT verify the composite sha256, strips\n * the longest-common-dir prefix from each path, per-file sha256-verifies, and\n * writes the stripped paths as immediate children of `targetDir` (what the\n * runner's `.skaile/assets/<kind>/<name>/` scan requires). `installPath` is\n * `targetDir`. Absent → unchanged ref-derived `@<pub>/name/version/<path>`\n * layout with composite verify.\n */\n targetDir?: string;\n}\n\n/**\n * Result of a successful {@link installFromManifest} call.\n */\nexport interface InstallResult {\n /** Absolute path the asset files were written to. */\n installPath: string;\n}\n\n/**\n * Fetch, verify, and write an asset's files per its {@link InstallManifest}.\n *\n * @throws An error matching `/hash mismatch/i` if any per-file SHA256 differs.\n * @throws An error matching `/composite hash mismatch/i` if the rollup differs.\n * @throws An error if the ref is malformed or the fetcher omits a file.\n */\nexport async function installFromManifest(opts: InstallOpts): Promise<InstallResult> {\n const { manifest, libraryRoot } = opts;\n const fetcher =\n opts.fetcher ?? (await import(\"./source-fetch-github.js\")).fetchAssetFilesFromGitHub;\n\n // Flat mode: reproduce the platform pointer-installer's asset-rooted layout.\n // No ref parse, no composite verify — the platform store may not satisfy a\n // ref-grammar or composite, and the runner only needs immediate-child files.\n if (opts.targetDir !== undefined) {\n return installFlat(manifest, opts.targetDir, fetcher);\n }\n\n // 1. Parse ref into install path: `skill:@x/git#1.0.0` → `<root>/@x/git/1.0.0`.\n // Done first so the C1 path-traversal guard can resolve against installPath\n // BEFORE any network fetch happens. The ref is attacker-controlled, so each\n // segment is further validated as a safe path component (H1) after parsing.\n // `parseAssetRef` is the single canonical grammar (`kind:@publisher/name#version`);\n // the legacy trailing-`@version` shape was removed in core and is rejected here.\n let parsed: ReturnType<typeof parseAssetRef>;\n try {\n parsed = parseAssetRef(manifest.ref);\n } catch (e) {\n throw new Error(`invalid ref: ${manifest.ref}: ${e instanceof Error ? e.message : String(e)}`);\n }\n const publisher = parsed.publisher;\n const name = parsed.name;\n const version = parsed.pin;\n if (!publisher) throw new Error(`invalid ref: ${manifest.ref} (missing publisher)`);\n if (!version) throw new Error(`invalid ref: ${manifest.ref} (missing version pin)`);\n assertSafeRefComponent(\"publisher\", publisher);\n assertSafeRefComponent(\"name\", name);\n assertSafeRefComponent(\"version\", version);\n const root = resolve(libraryRoot);\n const installPath = resolve(join(root, `@${publisher}`, name, version));\n // Defense in depth: even with the segment guards above, assert the built\n // installPath stays strictly inside libraryRoot before any write or `rm`.\n if (installPath !== root && !installPath.startsWith(root + sep)) {\n throw new Error(`unsafe install path: ref '${manifest.ref}' resolves outside the library root`);\n }\n\n // 2. [C1] Validate EVERY manifest path against traversal BEFORE fetching.\n // The attacker controls the manifest (and thus all hashes) — hashes verify\n // content, never destination. Reject the whole install on the first bad path.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n }\n\n // 3. Fetch all files at the pinned commit.\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // 4. Verify per-file SHA256 — hard fail before writing anything. The path\n // key used to read from the fetcher result is re-guarded as defense in depth.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n }\n\n // 5. Verify composite SHA256 over the sorted `<path>:<sha256>\\n` lines.\n const actualComposite = compositeSha256(manifest.files);\n if (actualComposite !== manifest.sha256) {\n throw new Error(`composite hash mismatch: expected ${manifest.sha256}, got ${actualComposite}`);\n }\n\n // 6. [M1] Write all verified files. A failed install must leave NO partial\n // directory: any prior `installPath` is removed first (clean overwrite), and\n // a mid-loop write failure removes the partially-written tree before\n // rethrowing.\n await rm(installPath, { recursive: true, force: true });\n try {\n for (const f of manifest.files) {\n const target = join(installPath, f.path);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, bytes[f.path]!);\n }\n } catch (e) {\n await rm(installPath, { recursive: true, force: true }).catch(() => {});\n throw e;\n }\n\n return { installPath };\n}\n\n/**\n * Flat-layout install — the platform pointer-installer's behavior, made canonical\n * in install-core. Validates every path, fetches with the FULL repo paths, per-file\n * sha256-verifies, then strips the longest-common-dir prefix and writes each file\n * as `join(targetDir, path.slice(assetRoot.length + 1))` — immediate children of\n * `targetDir`. No ref parse, no composite check.\n */\nasync function installFlat(\n manifest: InstallManifest,\n targetDir: string,\n fetcher: AssetFetcher,\n): Promise<InstallResult> {\n const target = resolve(targetDir);\n\n // Gate every path before any fetch — the attacker controls the whole manifest.\n for (const f of manifest.files) {\n assertSafeManifestPath(target, f.path);\n }\n\n // Fetch keys off the FULL repo path (matches the upstream tree).\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // Strip the asset-root dir prefix from the WRITE path only — the fetch above\n // still keyed off the full repo path. Stripping removes leading whole segments\n // (never the basename), so a non-empty remainder always survives.\n const assetRoot = longestCommonDirPrefix(paths);\n\n for (const f of manifest.files) {\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n const relPath = assetRoot ? f.path.slice(assetRoot.length + 1) : f.path;\n // Re-guard the post-strip destination — it is what we actually write.\n assertSafeManifestPath(target, relPath);\n const dest = join(target, relPath);\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, buf);\n }\n\n return { installPath: target };\n}\n"]}
@@ -65,5 +65,5 @@ function globalHarnessRoot(target) {
65
65
  }
66
66
 
67
67
  export { DRIVER_TARGETS, SUPPORTED_DRIVER_TARGETS, driverTargetForDriver, globalHarnessRoot };
68
- //# sourceMappingURL=chunk-TOSHZX4C.js.map
69
- //# sourceMappingURL=chunk-TOSHZX4C.js.map
68
+ //# sourceMappingURL=chunk-CPSIPIX7.js.map
69
+ //# sourceMappingURL=chunk-CPSIPIX7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../core/src/driver-targets.ts"],"names":[],"mappings":";;;;AAsDO,IAAM,cAAA,GAAoD;AAAA,EAC/D,aAAA,EAAe;AAAA,IACb,KAAA,EAAO;AAAA,MACL,KAAA,EAAO,gBAAA;AAAA,MACP,KAAA,EAAO,gBAAA;AAAA,MACP,MAAA,EAAQ,kBAAA;AAAA,MACR,IAAA,EAAM,eAAA;AAAA,MACN,QAAA,EAAU;AAAA,KACZ;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO,kBAAA;AAAA,MACP,KAAA,EAAO,kBAAA;AAAA,MACP,MAAA,EAAQ,oBAAA;AAAA,MACR,IAAA,EAAM,iBAAA;AAAA,MACN,QAAA,EAAU;AAAA;AACZ,GACF;AAAA,EACA,GAAA,EAAK;AAAA,IACH,KAAA,EAAO;AAAA,MACL,KAAA,EAAO,aAAA;AAAA,MACP,KAAA,EAAO,aAAA;AAAA,MACP,MAAA,EAAQ,cAAA;AAAA,MACR,IAAA,EAAM,eAAA;AAAA,MACN,QAAA,EAAU;AAAA,KACZ;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO,eAAA;AAAA,MACP,KAAA,EAAO,eAAA;AAAA,MACP,MAAA,EAAQ,gBAAA;AAAA,MACR,IAAA,EAAM,iBAAA;AAAA,MACN,QAAA,EAAU;AAAA;AACZ,GACF;AAAA,EACA,KAAA,EAAO;AAAA,IACL,KAAA,EAAO;AAAA,MACL,KAAA,EAAO,eAAA;AAAA,MACP,KAAA,EAAO,eAAA;AAAA,MACP,MAAA,EAAQ,cAAA;AAAA,MACR,IAAA,EAAM,eAAA;AAAA,MACN,QAAA,EAAU;AAAA,KACZ;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO,iBAAA;AAAA,MACP,KAAA,EAAO,iBAAA;AAAA,MACP,MAAA,EAAQ,gBAAA;AAAA,MACR,IAAA,EAAM,iBAAA;AAAA,MACN,QAAA,EAAU;AAAA;AACZ;AAEJ;AAWO,SAAS,sBAAsB,MAAA,EAAsD;AAC1F,EAAA,IAAI,MAAA,KAAW,cAAc,OAAO,aAAA;AACpC,EAAA,IAAI,WAAW,aAAA,IAAiB,MAAA,KAAW,KAAA,IAAS,MAAA,KAAW,SAAS,OAAO,MAAA;AAC/E,EAAA,OAAO,MAAA;AACT;AAOO,IAAM,wBAAA,GAA2B,MAAA,CAAO,IAAA,CAAK,cAAc;AAa3D,SAAS,kBAAkB,MAAA,EAA8B;AAC9D,EAAA,MAAM,SAAA,GAAY,cAAA,CAAe,MAAM,CAAA,CAAE,MAAA,CAAO,KAAA;AAChD,EAAA,MAAM,YAAA,GAAe,UAAU,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA;AAC/D,EAAA,OAAO,IAAA,CAAK,OAAA,EAAQ,EAAG,YAAY,CAAA;AACrC","file":"chunk-CPSIPIX7.js","sourcesContent":["/**\n * Driver targets — maps agent tool identifiers to their install paths.\n *\n * Only harnesses with a full bridge driver (runtime execution) are included.\n * Render-only targets (cursor, roo, github-copilot, gemini, amp) were removed —\n * add them back when a bridge driver is implemented.\n */\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { AssetInstallTarget } from \"@skaile/workspaces/plugins\";\n\n/**\n * All supported coding-agent driver target identifiers.\n * Only harnesses with a full bridge driver (runtime execution) are included.\n * @docLink packages/core/concepts#driver-target\n */\nexport type DriverTarget = \"claude-code\" | \"omp\" | \"codex\";\n\n/**\n * Filesystem install path configuration for a single driver target.\n * Paths are relative to the project root (`local`) or the home directory (`global`).\n * `~` in global paths is expanded to `$HOME` by `deployedBase`.\n * @docLink packages/core/concepts#agent-target\n */\nexport interface AgentTarget {\n /** Project-relative install paths for each AI component type. */\n local: Record<AiComponent, string>;\n /** Home-relative install paths for each AI component type (`~` = `$HOME`). */\n global: Record<AiComponent, string>;\n}\n\n/**\n * The distinct asset types that can be installed into a driver target directory —\n * the `installTarget` values an `IAssetKindProvider` may declare.\n * Used as keys in `AgentTarget.local` and `AgentTarget.global`.\n * @docLink packages/core/concepts#ai-component\n */\nexport type AiComponent = AssetInstallTarget;\n\n/**\n * Filesystem install path configuration for every supported driver target.\n * `local` paths are relative to the project root; `global` paths are home-relative (`~` = `$HOME`).\n *\n * Only targets with a full bridge driver are included. Removed targets:\n * cursor — no bridge driver\n * roo — no bridge driver\n * github-copilot — no bridge driver\n * gemini — no bridge driver\n * amp — no bridge driver\n * windsurf — no file-based agent support\n * cline — no file-based agent support\n * continue — no file-based agent support\n * @docLink packages/core/concepts#driver-targets\n */\nexport const DRIVER_TARGETS: Record<DriverTarget, AgentTarget> = {\n \"claude-code\": {\n local: {\n skill: \".claude/skills\",\n agent: \".claude/agents\",\n prompt: \".claude/commands\",\n flow: \".skaile/flows\",\n contract: \".claude/contracts\",\n },\n global: {\n skill: \"~/.claude/skills\",\n agent: \"~/.claude/agents\",\n prompt: \"~/.claude/commands\",\n flow: \"~/.skaile/flows\",\n contract: \"~/.claude/contracts\",\n },\n },\n omp: {\n local: {\n skill: \".omp/skills\",\n agent: \".omp/agents\",\n prompt: \".omp/prompts\",\n flow: \".skaile/flows\",\n contract: \".omp/contracts\",\n },\n global: {\n skill: \"~/.omp/skills\",\n agent: \"~/.omp/agents\",\n prompt: \"~/.omp/prompts\",\n flow: \"~/.skaile/flows\",\n contract: \"~/.omp/contracts\",\n },\n },\n codex: {\n local: {\n skill: \".codex/skills\",\n agent: \".codex/agents\",\n prompt: \".codex/rules\",\n flow: \".skaile/flows\",\n contract: \".codex/contracts\",\n },\n global: {\n skill: \"~/.codex/skills\",\n agent: \"~/.codex/agents\",\n prompt: \"~/.codex/rules\",\n flow: \"~/.skaile/flows\",\n contract: \"~/.codex/contracts\",\n },\n },\n};\n\n/**\n * Map a bridge driver id (`skaile.yaml` `agent-config.*.driver`, as written by\n * `skaile init --harness`) to the {@link DriverTarget} whose install dirs it\n * reads: `claude-sdk` → `claude-code`, `omp` → `omp`, `codex` → `codex`.\n *\n * @param driver - Bridge driver id, or a driver-target id (accepted as-is).\n * @returns The matching target, or `undefined` for an unset/unknown driver.\n * @docLink packages/core/concepts#driver-target-for-driver\n */\nexport function driverTargetForDriver(driver: string | undefined): DriverTarget | undefined {\n if (driver === \"claude-sdk\") return \"claude-code\";\n if (driver === \"claude-code\" || driver === \"omp\" || driver === \"codex\") return driver;\n return undefined;\n}\n\n/**\n * Array of all `DriverTarget` values that support file-based asset installation\n * (skills, agents, prompts, flows, contracts).\n * @docLink packages/core/concepts#supported-driver-targets\n */\nexport const SUPPORTED_DRIVER_TARGETS = Object.keys(DRIVER_TARGETS) as DriverTarget[];\n\n/**\n * Absolute path to a driver target's **global harness root** — the home-relative\n * directory that identifies the harness on disk (e.g. `~/.claude`, `~/.omp`,\n * `~/.codex`). Derived from the first path segment of the target's global skill\n * path. Used by `resolveGlobalHarnesses` to auto-detect which harnesses the user\n * runs globally (a harness \"exists globally\" when this dir is present).\n *\n * @param target - Driver target identifier.\n * @returns Absolute path to the harness's home-relative root dir.\n * @docLink packages/core/concepts#global-harness-root\n */\nexport function globalHarnessRoot(target: DriverTarget): string {\n const skillPath = DRIVER_TARGETS[target].global.skill; // e.g. \"~/.claude/skills\"\n const firstSegment = skillPath.replace(/^~\\//, \"\").split(\"/\")[0]; // \".claude\"\n return join(homedir(), firstSegment);\n}\n"]}