@skaile/workspaces 5.11.0 → 5.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. package/CHANGELOG.md +193 -0
  2. package/README.md +4 -4
  3. package/dist/{asset-feeds-CXGQIDFR.js → asset-feeds-ALMTHLPV.js} +26 -23
  4. package/dist/asset-feeds-ALMTHLPV.js.map +1 -0
  5. package/dist/asset-manager/catalog-deployer.js +10 -10
  6. package/dist/asset-manager/fragments.js +1 -1
  7. package/dist/asset-manager/index.js +18 -18
  8. package/dist/asset-manager/installer.js +13 -13
  9. package/dist/asset-manager/renderers.js +11 -11
  10. package/dist/asset-manager/src/fragments.d.ts +5 -0
  11. package/dist/asset-manager/src/fragments.d.ts.map +1 -1
  12. package/dist/asset-manager/src/index.d.ts +140 -12
  13. package/dist/asset-manager/src/index.d.ts.map +1 -1
  14. package/dist/asset-manager/src/install-agent.d.ts +9 -1
  15. package/dist/asset-manager/src/install-agent.d.ts.map +1 -1
  16. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  17. package/dist/asset-manager/src/renderers.d.ts +5 -0
  18. package/dist/asset-manager/src/renderers.d.ts.map +1 -1
  19. package/dist/bridge/drivers/claude-sdk.js +21 -16
  20. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  21. package/dist/bridge/drivers/codex.js +101 -29
  22. package/dist/bridge/drivers/codex.js.map +1 -1
  23. package/dist/bridge/drivers/continue.js +12 -12
  24. package/dist/bridge/drivers/echo.js +2 -2
  25. package/dist/bridge/drivers/gemini.js +7 -7
  26. package/dist/bridge/drivers/goose.js +12 -12
  27. package/dist/bridge/drivers/omp.js +135 -33
  28. package/dist/bridge/drivers/omp.js.map +1 -1
  29. package/dist/bridge/drivers/opencode.js +12 -12
  30. package/dist/bridge/drivers/qwen.js +7 -7
  31. package/dist/bridge/index.js +14 -14
  32. package/dist/bridge/src/codex/config-toml.d.ts +16 -3
  33. package/dist/bridge/src/codex/config-toml.d.ts.map +1 -1
  34. package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
  35. package/dist/bridge/src/drivers/claude-sdk.d.ts +1 -1
  36. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  37. package/dist/bridge/src/drivers/codex.d.ts +6 -0
  38. package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
  39. package/dist/bridge/src/drivers/omp-models-yml.d.ts +32 -0
  40. package/dist/bridge/src/drivers/omp-models-yml.d.ts.map +1 -1
  41. package/dist/bridge/src/drivers/omp.d.ts +29 -6
  42. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  43. package/dist/bridge/src/provider-materialize/credential-env.d.ts +15 -0
  44. package/dist/bridge/src/provider-materialize/credential-env.d.ts.map +1 -1
  45. package/dist/{chunk-T42WRQ4O.js → chunk-2BIESC6S.js} +3 -3
  46. package/dist/{chunk-T42WRQ4O.js.map → chunk-2BIESC6S.js.map} +1 -1
  47. package/dist/{chunk-CPWLNZGJ.js → chunk-4DLQESIY.js} +3 -3
  48. package/dist/{chunk-CPWLNZGJ.js.map → chunk-4DLQESIY.js.map} +1 -1
  49. package/dist/{chunk-HZXUXHIV.js → chunk-4L4R5LV3.js} +89 -12
  50. package/dist/chunk-4L4R5LV3.js.map +1 -0
  51. package/dist/{chunk-CAHB6MHA.js → chunk-4NJ3QQHZ.js} +5 -5
  52. package/dist/{chunk-CAHB6MHA.js.map → chunk-4NJ3QQHZ.js.map} +1 -1
  53. package/dist/{chunk-ZCAJZ4B2.js → chunk-57SF6W6E.js} +147 -4
  54. package/dist/chunk-57SF6W6E.js.map +1 -0
  55. package/dist/{chunk-FH7W6TJ4.js → chunk-5FYOM4RF.js} +106 -25
  56. package/dist/chunk-5FYOM4RF.js.map +1 -0
  57. package/dist/{chunk-R7NHYEJF.js → chunk-5SKVCMRC.js} +15 -7
  58. package/dist/chunk-5SKVCMRC.js.map +1 -0
  59. package/dist/{chunk-CJERAGFY.js → chunk-6GICC4RJ.js} +44 -13
  60. package/dist/chunk-6GICC4RJ.js.map +1 -0
  61. package/dist/{chunk-G4FFOV3N.js → chunk-6JKIOPT3.js} +4 -4
  62. package/dist/{chunk-G4FFOV3N.js.map → chunk-6JKIOPT3.js.map} +1 -1
  63. package/dist/{chunk-T7CTHHG7.js → chunk-6NQDDCIL.js} +3 -3
  64. package/dist/{chunk-T7CTHHG7.js.map → chunk-6NQDDCIL.js.map} +1 -1
  65. package/dist/{chunk-XUSALIEI.js → chunk-7SMP4GNW.js} +6 -6
  66. package/dist/{chunk-XUSALIEI.js.map → chunk-7SMP4GNW.js.map} +1 -1
  67. package/dist/{chunk-Y3HTGHJC.js → chunk-AHCI4V5L.js} +3 -3
  68. package/dist/{chunk-Y3HTGHJC.js.map → chunk-AHCI4V5L.js.map} +1 -1
  69. package/dist/{chunk-M3B6EIJD.js → chunk-B7CZYFB2.js} +4 -4
  70. package/dist/{chunk-M3B6EIJD.js.map → chunk-B7CZYFB2.js.map} +1 -1
  71. package/dist/{chunk-PBBPZYVG.js → chunk-BF422IDP.js} +112 -46
  72. package/dist/chunk-BF422IDP.js.map +1 -0
  73. package/dist/{chunk-47U4GZ4M.js → chunk-BVJU2GKE.js} +20 -3
  74. package/dist/chunk-BVJU2GKE.js.map +1 -0
  75. package/dist/{chunk-PMECEZK3.js → chunk-D54T2F54.js} +5 -4
  76. package/dist/chunk-D54T2F54.js.map +1 -0
  77. package/dist/{chunk-2F5AWQX5.js → chunk-DKGEV6SQ.js} +192 -42
  78. package/dist/chunk-DKGEV6SQ.js.map +1 -0
  79. package/dist/{chunk-DALV4HHP.js → chunk-DKXNKFKP.js} +3 -2
  80. package/dist/{chunk-DALV4HHP.js.map → chunk-DKXNKFKP.js.map} +1 -1
  81. package/dist/chunk-FB3NREF7.js +649 -0
  82. package/dist/chunk-FB3NREF7.js.map +1 -0
  83. package/dist/{chunk-QZNJOHN6.js → chunk-FHDK3BFD.js} +3 -3
  84. package/dist/{chunk-QZNJOHN6.js.map → chunk-FHDK3BFD.js.map} +1 -1
  85. package/dist/{chunk-3SM2DL2T.js → chunk-GMDSRSGI.js} +21 -11
  86. package/dist/chunk-GMDSRSGI.js.map +1 -0
  87. package/dist/chunk-H5U7LNTJ.js +122 -0
  88. package/dist/chunk-H5U7LNTJ.js.map +1 -0
  89. package/dist/{chunk-VLTQGE2E.js → chunk-HBZD3MIW.js} +269 -81
  90. package/dist/chunk-HBZD3MIW.js.map +1 -0
  91. package/dist/{chunk-S3O3GKB7.js → chunk-HWGYJMME.js} +4 -4
  92. package/dist/{chunk-S3O3GKB7.js.map → chunk-HWGYJMME.js.map} +1 -1
  93. package/dist/{chunk-CPSIPIX7.js → chunk-IG5LZ3WU.js} +8 -6
  94. package/dist/chunk-IG5LZ3WU.js.map +1 -0
  95. package/dist/{chunk-ZPWTOUTK.js → chunk-IY5E7Y5W.js} +61 -8
  96. package/dist/chunk-IY5E7Y5W.js.map +1 -0
  97. package/dist/{chunk-6O2X3GPW.js → chunk-J4DB5G36.js} +7 -5
  98. package/dist/chunk-J4DB5G36.js.map +1 -0
  99. package/dist/{chunk-BNMZVPYA.js → chunk-J4OYIYFQ.js} +2 -2
  100. package/dist/{chunk-BNMZVPYA.js.map → chunk-J4OYIYFQ.js.map} +1 -1
  101. package/dist/{chunk-ALEYHUC5.js → chunk-L3ZGYSWY.js} +182 -41
  102. package/dist/chunk-L3ZGYSWY.js.map +1 -0
  103. package/dist/{chunk-SBSA3IQA.js → chunk-M3P4BYRK.js} +49 -14
  104. package/dist/chunk-M3P4BYRK.js.map +1 -0
  105. package/dist/{chunk-IER3KIPH.js → chunk-NDUYFYJB.js} +5 -5
  106. package/dist/{chunk-IER3KIPH.js.map → chunk-NDUYFYJB.js.map} +1 -1
  107. package/dist/{chunk-CGYEHQOX.js → chunk-NOA6EJXE.js} +11 -2
  108. package/dist/chunk-NOA6EJXE.js.map +1 -0
  109. package/dist/{chunk-J4RBUFGM.js → chunk-NVO6WECE.js} +9 -8
  110. package/dist/chunk-NVO6WECE.js.map +1 -0
  111. package/dist/{chunk-OBYKJB4U.js → chunk-O2SYFJWP.js} +79 -5
  112. package/dist/chunk-O2SYFJWP.js.map +1 -0
  113. package/dist/{chunk-5LKOAX7I.js → chunk-OQ5MKDS3.js} +21 -5
  114. package/dist/chunk-OQ5MKDS3.js.map +1 -0
  115. package/dist/{chunk-NWDSLXOX.js → chunk-PHRNUTSG.js} +118 -118
  116. package/dist/chunk-PHRNUTSG.js.map +1 -0
  117. package/dist/chunk-PN44DOGP.js +345 -0
  118. package/dist/chunk-PN44DOGP.js.map +1 -0
  119. package/dist/{chunk-COH6FQAG.js → chunk-PXDWTJ3P.js} +5 -5
  120. package/dist/{chunk-COH6FQAG.js.map → chunk-PXDWTJ3P.js.map} +1 -1
  121. package/dist/{chunk-GV4DZ6MT.js → chunk-PYTTF754.js} +22 -6
  122. package/dist/chunk-PYTTF754.js.map +1 -0
  123. package/dist/chunk-PZOO7L26.js +64 -0
  124. package/dist/chunk-PZOO7L26.js.map +1 -0
  125. package/dist/{chunk-EDYHEMJA.js → chunk-QO7CR3KB.js} +10 -5
  126. package/dist/chunk-QO7CR3KB.js.map +1 -0
  127. package/dist/{chunk-XDKH7XSA.js → chunk-R6QHJEHE.js} +5 -5
  128. package/dist/{chunk-XDKH7XSA.js.map → chunk-R6QHJEHE.js.map} +1 -1
  129. package/dist/chunk-U27JRO5L.js +13 -0
  130. package/dist/chunk-U27JRO5L.js.map +1 -0
  131. package/dist/{chunk-X77SUM4P.js → chunk-USHB5KEY.js} +3 -3
  132. package/dist/{chunk-X77SUM4P.js.map → chunk-USHB5KEY.js.map} +1 -1
  133. package/dist/{chunk-QVFAS5IO.js → chunk-V5JHD4I2.js} +3 -3
  134. package/dist/{chunk-QVFAS5IO.js.map → chunk-V5JHD4I2.js.map} +1 -1
  135. package/dist/{chunk-PQFHMQHQ.js → chunk-VLBIME5L.js} +6 -6
  136. package/dist/{chunk-PQFHMQHQ.js.map → chunk-VLBIME5L.js.map} +1 -1
  137. package/dist/{chunk-D3B36CYC.js → chunk-X3RMRJNR.js} +4 -3
  138. package/dist/chunk-X3RMRJNR.js.map +1 -0
  139. package/dist/{chunk-TCHRMVTO.js → chunk-XBYSURMK.js} +4 -4
  140. package/dist/{chunk-TCHRMVTO.js.map → chunk-XBYSURMK.js.map} +1 -1
  141. package/dist/{chunk-MZG34MBZ.js → chunk-XJYBCDY2.js} +3 -3
  142. package/dist/{chunk-MZG34MBZ.js.map → chunk-XJYBCDY2.js.map} +1 -1
  143. package/dist/{chunk-4A4OD24G.js → chunk-Y4Z7LGSH.js} +9 -9
  144. package/dist/{chunk-4A4OD24G.js.map → chunk-Y4Z7LGSH.js.map} +1 -1
  145. package/dist/{chunk-DZMNFCWB.js → chunk-Y7WKXPWS.js} +816 -143
  146. package/dist/chunk-Y7WKXPWS.js.map +1 -0
  147. package/dist/{chunk-HCEVNYSH.js → chunk-YTZFSKWL.js} +3 -3
  148. package/dist/{chunk-HCEVNYSH.js.map → chunk-YTZFSKWL.js.map} +1 -1
  149. package/dist/{chunk-WSBKB4CJ.js → chunk-ZSMMX3JD.js} +167 -25
  150. package/dist/chunk-ZSMMX3JD.js.map +1 -0
  151. package/dist/{chunk-GCHPUTA3.js → chunk-ZU24LWBI.js} +3 -3
  152. package/dist/{chunk-GCHPUTA3.js.map → chunk-ZU24LWBI.js.map} +1 -1
  153. package/dist/cli/index.js +1427 -605
  154. package/dist/cli/index.js.map +1 -1
  155. package/dist/cli/src/agent-checks.d.ts +40 -0
  156. package/dist/cli/src/agent-checks.d.ts.map +1 -0
  157. package/dist/cli/src/asset-feeds.d.ts.map +1 -1
  158. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  159. package/dist/cli/src/commands/catalog-cmd.d.ts.map +1 -1
  160. package/dist/cli/src/commands/catalog.d.ts +26 -0
  161. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  162. package/dist/cli/src/commands/config.d.ts.map +1 -1
  163. package/dist/cli/src/commands/diff.d.ts +1 -1
  164. package/dist/cli/src/commands/diff.d.ts.map +1 -1
  165. package/dist/cli/src/commands/integration.d.ts.map +1 -1
  166. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  167. package/dist/cli/src/commands/library-index.d.ts +10 -0
  168. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  169. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  170. package/dist/cli/src/commands/mcp-server.d.ts +1 -1
  171. package/dist/cli/src/commands/migrate-assets.d.ts +2 -1
  172. package/dist/cli/src/commands/migrate-assets.d.ts.map +1 -1
  173. package/dist/cli/src/commands/migrate.d.ts.map +1 -1
  174. package/dist/cli/src/commands/plugin/claude-code.d.ts +1 -1
  175. package/dist/cli/src/commands/plugin/claude-code.d.ts.map +1 -1
  176. package/dist/cli/src/commands/plugin/types.d.ts +3 -1
  177. package/dist/cli/src/commands/plugin/types.d.ts.map +1 -1
  178. package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -1
  179. package/dist/cli/src/commands/preset-apply.d.ts.map +1 -1
  180. package/dist/cli/src/commands/project.d.ts +8 -0
  181. package/dist/cli/src/commands/project.d.ts.map +1 -1
  182. package/dist/cli/src/commands/publish-core.d.ts +5 -0
  183. package/dist/cli/src/commands/publish-core.d.ts.map +1 -1
  184. package/dist/cli/src/commands/run.d.ts +11 -1
  185. package/dist/cli/src/commands/run.d.ts.map +1 -1
  186. package/dist/cli/src/commands/serve-preflight.d.ts +23 -0
  187. package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -0
  188. package/dist/cli/src/commands/serve.d.ts.map +1 -1
  189. package/dist/cli/src/commands/source-manifest-publish.d.ts.map +1 -1
  190. package/dist/cli/src/commands/source-manifest.d.ts +1 -0
  191. package/dist/cli/src/commands/source-manifest.d.ts.map +1 -1
  192. package/dist/cli/src/commands/source.d.ts +9 -1
  193. package/dist/cli/src/commands/source.d.ts.map +1 -1
  194. package/dist/cli/src/commands/store.d.ts.map +1 -1
  195. package/dist/cli/src/commands/tree.d.ts.map +1 -1
  196. package/dist/cli/src/commands/update.d.ts.map +1 -1
  197. package/dist/cli/src/commands/validate-instances.d.ts.map +1 -1
  198. package/dist/cli/src/commands/validate.d.ts +3 -2
  199. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  200. package/dist/cli/src/commands/why.d.ts.map +1 -1
  201. package/dist/cli/src/curated-manifests.d.ts +21 -0
  202. package/dist/cli/src/curated-manifests.d.ts.map +1 -0
  203. package/dist/cli/src/driver-error.d.ts +7 -0
  204. package/dist/cli/src/driver-error.d.ts.map +1 -1
  205. package/dist/cli/src/helpers.d.ts +6 -0
  206. package/dist/cli/src/helpers.d.ts.map +1 -1
  207. package/dist/cli/src/index-busy.d.ts +8 -0
  208. package/dist/cli/src/index-busy.d.ts.map +1 -0
  209. package/dist/cli/src/plugin-store/index.d.ts +1 -1
  210. package/dist/cli/src/plugin-store/index.d.ts.map +1 -1
  211. package/dist/cli/src/plugin-store/paths.d.ts +7 -3
  212. package/dist/cli/src/plugin-store/paths.d.ts.map +1 -1
  213. package/dist/cli/src/plugin-store/reconcile.d.ts +24 -4
  214. package/dist/cli/src/plugin-store/reconcile.d.ts.map +1 -1
  215. package/dist/cli/src/skill-checks.d.ts +27 -3
  216. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  217. package/dist/cli/src/store-addable.d.ts +17 -0
  218. package/dist/cli/src/store-addable.d.ts.map +1 -0
  219. package/dist/connectors/config.js +6 -6
  220. package/dist/connectors/index.js +18 -18
  221. package/dist/connectors/src/config.d.ts.map +1 -1
  222. package/dist/{connectors-4QWAKPHB.js → connectors-GFKMKAXV.js} +21 -21
  223. package/dist/{connectors-4QWAKPHB.js.map → connectors-GFKMKAXV.js.map} +1 -1
  224. package/dist/core/driver-targets.js +1 -1
  225. package/dist/core/index.js +9 -9
  226. package/dist/core/logging.js +1 -1
  227. package/dist/core/manifest.js +2 -2
  228. package/dist/core/models.js +1 -1
  229. package/dist/core/publish-manifest.js +4 -2
  230. package/dist/core/ref.js +1 -1
  231. package/dist/core/runtime-assets.js +6 -6
  232. package/dist/core/src/agent-instances.d.ts +5 -0
  233. package/dist/core/src/agent-instances.d.ts.map +1 -1
  234. package/dist/core/src/driver-targets.d.ts.map +1 -1
  235. package/dist/core/src/index.d.ts +6 -5
  236. package/dist/core/src/index.d.ts.map +1 -1
  237. package/dist/core/src/lock.d.ts +15 -5
  238. package/dist/core/src/lock.d.ts.map +1 -1
  239. package/dist/core/src/logging/sinks/sqlite-sink.d.ts.map +1 -1
  240. package/dist/core/src/manifest.d.ts +14 -3
  241. package/dist/core/src/manifest.d.ts.map +1 -1
  242. package/dist/core/src/models.d.ts +11 -3
  243. package/dist/core/src/models.d.ts.map +1 -1
  244. package/dist/core/src/package-manager.d.ts +19 -0
  245. package/dist/core/src/package-manager.d.ts.map +1 -0
  246. package/dist/core/src/publish-manifest.d.ts +38 -1
  247. package/dist/core/src/publish-manifest.d.ts.map +1 -1
  248. package/dist/core/src/repo-manager.d.ts +19 -3
  249. package/dist/core/src/repo-manager.d.ts.map +1 -1
  250. package/dist/core/src/runtime-assets.d.ts.map +1 -1
  251. package/dist/core/src/settings.d.ts +26 -6
  252. package/dist/core/src/settings.d.ts.map +1 -1
  253. package/dist/core/src/store.d.ts +4 -0
  254. package/dist/core/src/store.d.ts.map +1 -1
  255. package/dist/core/src/walker.d.ts +8 -1
  256. package/dist/core/src/walker.d.ts.map +1 -1
  257. package/dist/core/src/workspace-config.d.ts +24 -2
  258. package/dist/core/src/workspace-config.d.ts.map +1 -1
  259. package/dist/core/store.js +2 -2
  260. package/dist/core/workspace-config.js +5 -5
  261. package/dist/deploy/index.js +9 -9
  262. package/dist/discovery/index.js +5 -5
  263. package/dist/discovery/src/parse-manifest.d.ts.map +1 -1
  264. package/dist/discovery/src/source-config.d.ts +5 -3
  265. package/dist/discovery/src/source-config.d.ts.map +1 -1
  266. package/dist/{ensure-sources-2RONZKCU.js → ensure-sources-VUKHL65L.js} +21 -21
  267. package/dist/{ensure-sources-2RONZKCU.js.map → ensure-sources-VUKHL65L.js.map} +1 -1
  268. package/dist/factory-assets/README.md +1 -1
  269. package/dist/factory-assets/connectors/box.js +18 -18
  270. package/dist/factory-assets/connectors/deploy.js +18 -18
  271. package/dist/factory-assets/connectors/devserver.js +18 -18
  272. package/dist/factory-assets/connectors/flow/adapter.js +18 -18
  273. package/dist/factory-assets/connectors/flow/contract/normalize.d.ts.map +1 -1
  274. package/dist/factory-assets/connectors/flow/contract.js +1 -1
  275. package/dist/factory-assets/connectors/flow/engine.js +11 -11
  276. package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
  277. package/dist/factory-assets/connectors/flow/run-flow.js +20 -20
  278. package/dist/factory-assets/connectors/flow.js +18 -18
  279. package/dist/factory-assets/connectors/git.js +18 -18
  280. package/dist/factory-assets/connectors/gmail.js +18 -18
  281. package/dist/factory-assets/connectors/googledrive.js +18 -18
  282. package/dist/factory-assets/connectors/local.js +18 -18
  283. package/dist/factory-assets/connectors/mattermost.js +18 -18
  284. package/dist/factory-assets/connectors/memory.js +18 -18
  285. package/dist/factory-assets/connectors/minio.js +18 -18
  286. package/dist/factory-assets/connectors/postgres.js +18 -18
  287. package/dist/factory-assets/connectors/s3.js +18 -18
  288. package/dist/factory-assets/connectors/sharepoint.js +18 -18
  289. package/dist/factory-assets/connectors/sqlite.js +18 -18
  290. package/dist/factory-assets/connectors/static-server.js +18 -18
  291. package/dist/factory-assets/connectors/tunnel.js +18 -18
  292. package/dist/factory-assets/connectors/webdav.js +18 -18
  293. package/dist/factory-assets/connectors/xstate-store.js +18 -18
  294. package/dist/factory-assets/connectors/xstate.js +18 -18
  295. package/dist/factory-assets/skills/authoring-skaile-assets/SKILL.md +10 -8
  296. package/dist/factory-assets/skills/authoring-skaile-manifests/SKILL.md +15 -11
  297. package/dist/factory-assets/skills/authoring-skaile-manifests/references/dependency-standard.md +12 -9
  298. package/dist/factory-assets/skills/skaile-author-asset/SKILL.md +2 -2
  299. package/dist/flows-A4YALSZY.js +26 -0
  300. package/dist/{flows-EQF2CH4U.js.map → flows-A4YALSZY.js.map} +1 -1
  301. package/dist/helpers-53XZW7KF.js +34 -0
  302. package/dist/{helpers-CFK6YP6R.js.map → helpers-53XZW7KF.js.map} +1 -1
  303. package/dist/library/index.js +14 -14
  304. package/dist/library/install.js +6 -4
  305. package/dist/library/src/index.d.ts +2 -2
  306. package/dist/library/src/index.d.ts.map +1 -1
  307. package/dist/library/src/install/source-fetch-github.d.ts.map +1 -1
  308. package/dist/library/src/local/db.d.ts +2 -0
  309. package/dist/library/src/local/db.d.ts.map +1 -1
  310. package/dist/library/src/local/library-manager.d.ts +5 -0
  311. package/dist/library/src/local/library-manager.d.ts.map +1 -1
  312. package/dist/library/src/local/library.d.ts +5 -3
  313. package/dist/library/src/local/library.d.ts.map +1 -1
  314. package/dist/library/src/local/local-catalog-source.d.ts +6 -0
  315. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  316. package/dist/library/src/local/store-paths.d.ts +9 -0
  317. package/dist/library/src/local/store-paths.d.ts.map +1 -1
  318. package/dist/library/src/manifest-writer.d.ts +1 -1
  319. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  320. package/dist/library/src/remote/index.d.ts +1 -1
  321. package/dist/library/src/remote/index.d.ts.map +1 -1
  322. package/dist/library/src/remote/remote-catalog-source.d.ts +17 -0
  323. package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
  324. package/dist/library/src/sync/git-driver.d.ts.map +1 -1
  325. package/dist/library/src/user-library.d.ts +2 -0
  326. package/dist/library/src/user-library.d.ts.map +1 -1
  327. package/dist/{library-publish-53UTB3MB.js → library-publish-FFIPWIRM.js} +50 -39
  328. package/dist/library-publish-FFIPWIRM.js.map +1 -0
  329. package/dist/open-library-PZAT3TJA.js +40 -0
  330. package/dist/{open-library-BOSPJVID.js.map → open-library-PZAT3TJA.js.map} +1 -1
  331. package/dist/open-registry-W46UXZ3I.js +32 -0
  332. package/dist/{open-registry-4FI7HKET.js.map → open-registry-W46UXZ3I.js.map} +1 -1
  333. package/dist/paths-KKY3NSBZ.js +22 -0
  334. package/dist/{paths-SUS4S4YT.js.map → paths-KKY3NSBZ.js.map} +1 -1
  335. package/dist/plugin-store-CK7YWRIC.js +227 -0
  336. package/dist/plugin-store-CK7YWRIC.js.map +1 -0
  337. package/dist/plugins/src/catalog-source.d.ts +6 -0
  338. package/dist/plugins/src/catalog-source.d.ts.map +1 -1
  339. package/dist/project-EZUH7PUJ.js +79 -0
  340. package/dist/{project-I55A4O2T.js.map → project-EZUH7PUJ.js.map} +1 -1
  341. package/dist/resolver/index.js +10 -10
  342. package/dist/runner/index.js +35 -35
  343. package/dist/runner/src/agent.d.ts.map +1 -1
  344. package/dist/runner/src/agents/in-process-host.d.ts.map +1 -1
  345. package/dist/runner/src/composition/index.d.ts +2 -1
  346. package/dist/runner/src/composition/index.d.ts.map +1 -1
  347. package/dist/runner/src/composition/prompt-sections.d.ts +20 -5
  348. package/dist/runner/src/composition/prompt-sections.d.ts.map +1 -1
  349. package/dist/runner/src/composition/resolve.d.ts +10 -1
  350. package/dist/runner/src/composition/resolve.d.ts.map +1 -1
  351. package/dist/runner/src/composition/verify.d.ts +29 -0
  352. package/dist/runner/src/composition/verify.d.ts.map +1 -0
  353. package/dist/runner/src/credential-notice.d.ts +14 -0
  354. package/dist/runner/src/credential-notice.d.ts.map +1 -0
  355. package/dist/runner/src/environment.d.ts.map +1 -1
  356. package/dist/runner/src/final-text.d.ts +17 -0
  357. package/dist/runner/src/final-text.d.ts.map +1 -0
  358. package/dist/runner/src/index.d.ts +2 -0
  359. package/dist/runner/src/index.d.ts.map +1 -1
  360. package/dist/runner/src/resource-handler.d.ts.map +1 -1
  361. package/dist/runner/src/serve.d.ts +13 -0
  362. package/dist/runner/src/serve.d.ts.map +1 -1
  363. package/dist/runner/src/session-builder.d.ts.map +1 -1
  364. package/dist/runner/src/session.d.ts +2 -0
  365. package/dist/runner/src/session.d.ts.map +1 -1
  366. package/dist/runner/src/ws-auth-warning.d.ts +17 -0
  367. package/dist/runner/src/ws-auth-warning.d.ts.map +1 -0
  368. package/dist/sdk/asset-manager.js +18 -18
  369. package/dist/sdk/bridge.js +14 -14
  370. package/dist/sdk/core.js +9 -9
  371. package/dist/sdk/flow.js +11 -11
  372. package/dist/sdk/index.js +38 -36
  373. package/dist/sdk/index.js.map +1 -1
  374. package/dist/sdk/resolver.js +10 -10
  375. package/dist/sdk/runner.js +35 -35
  376. package/dist/sdk/src/local-runtime.d.ts.map +1 -1
  377. package/dist/sdk/transport/ws/client.js +1 -1
  378. package/dist/sdk/transport/ws/server.js +1 -1
  379. package/dist/sdk/transport/ws.js +2 -2
  380. package/dist/sdk/transport.js +2 -2
  381. package/dist/serve-preflight-F7MYF747.js +64 -0
  382. package/dist/serve-preflight-F7MYF747.js.map +1 -0
  383. package/dist/{setup-7DQJKHUI.js → setup-L632QIHV.js} +26 -26
  384. package/dist/{setup-7DQJKHUI.js.map → setup-L632QIHV.js.map} +1 -1
  385. package/dist/skills-OY3Y5GKA.js +26 -0
  386. package/dist/{skills-NUEN5NDX.js.map → skills-OY3Y5GKA.js.map} +1 -1
  387. package/dist/source-36FHMN5V.js +42 -0
  388. package/dist/{source-G2LV5LVD.js.map → source-36FHMN5V.js.map} +1 -1
  389. package/dist/source-fetch-github-PIO6EMMF.js +4 -0
  390. package/dist/{source-fetch-github-QN4LLTL5.js.map → source-fetch-github-PIO6EMMF.js.map} +1 -1
  391. package/dist/{source-manifest-publish-6RM7SWLZ.js → source-manifest-publish-NIXJSJ22.js} +30 -28
  392. package/dist/source-manifest-publish-NIXJSJ22.js.map +1 -0
  393. package/dist/transport/index.js +2 -2
  394. package/dist/transport/src/ws/client.d.ts +6 -0
  395. package/dist/transport/src/ws/client.d.ts.map +1 -1
  396. package/dist/transport/src/ws/server.d.ts +4 -0
  397. package/dist/transport/src/ws/server.d.ts.map +1 -1
  398. package/dist/transport/ws/client.js +1 -1
  399. package/dist/transport/ws/server.js +1 -1
  400. package/dist/transport/ws.js +2 -2
  401. package/dist/tui/index.js +77 -50
  402. package/dist/tui/index.js.map +1 -1
  403. package/dist/tui/src/repl-session.d.ts +1 -1
  404. package/dist/tui/src/repl-session.d.ts.map +1 -1
  405. package/dist/tui/src/repl.d.ts +3 -0
  406. package/dist/tui/src/repl.d.ts.map +1 -1
  407. package/dist/types/manifests.js +1 -1
  408. package/dist/types/src/lifecycle.d.ts +2 -1
  409. package/dist/types/src/lifecycle.d.ts.map +1 -1
  410. package/dist/types/src/manifests/agent-composition.d.ts +20 -0
  411. package/dist/types/src/manifests/agent-composition.d.ts.map +1 -1
  412. package/dist/types/src/manifests/agent.d.ts.map +1 -1
  413. package/dist/types/src/manifests/cron.d.ts +15 -0
  414. package/dist/types/src/manifests/cron.d.ts.map +1 -0
  415. package/dist/types/src/manifests/index.d.ts +3 -2
  416. package/dist/types/src/manifests/index.d.ts.map +1 -1
  417. package/dist/types/src/manifests/preset.d.ts +6 -1
  418. package/dist/types/src/manifests/preset.d.ts.map +1 -1
  419. package/dist/workspace-plugin/adapters/mcp.js +25 -25
  420. package/dist/workspace-plugin/adapters/omp.js +106 -51
  421. package/dist/workspace-plugin/adapters/omp.js.map +1 -1
  422. package/dist/workspace-plugin/index.js +2 -2
  423. package/dist/workspace-plugin/src/adapters/claude-code.d.ts.map +1 -1
  424. package/dist/workspace-plugin/src/adapters/omp.d.ts +11 -2
  425. package/dist/workspace-plugin/src/adapters/omp.d.ts.map +1 -1
  426. package/package.json +1 -1
  427. package/dist/asset-feeds-CXGQIDFR.js.map +0 -1
  428. package/dist/chunk-2F5AWQX5.js.map +0 -1
  429. package/dist/chunk-3SM2DL2T.js.map +0 -1
  430. package/dist/chunk-47U4GZ4M.js.map +0 -1
  431. package/dist/chunk-5LKOAX7I.js.map +0 -1
  432. package/dist/chunk-6O2X3GPW.js.map +0 -1
  433. package/dist/chunk-ALEYHUC5.js.map +0 -1
  434. package/dist/chunk-CGYEHQOX.js.map +0 -1
  435. package/dist/chunk-CJERAGFY.js.map +0 -1
  436. package/dist/chunk-CPSIPIX7.js.map +0 -1
  437. package/dist/chunk-D3B36CYC.js.map +0 -1
  438. package/dist/chunk-DZMNFCWB.js.map +0 -1
  439. package/dist/chunk-EDYHEMJA.js.map +0 -1
  440. package/dist/chunk-FH7W6TJ4.js.map +0 -1
  441. package/dist/chunk-GV4DZ6MT.js.map +0 -1
  442. package/dist/chunk-HZXUXHIV.js.map +0 -1
  443. package/dist/chunk-J4RBUFGM.js.map +0 -1
  444. package/dist/chunk-NWDSLXOX.js.map +0 -1
  445. package/dist/chunk-OBYKJB4U.js.map +0 -1
  446. package/dist/chunk-PBBPZYVG.js.map +0 -1
  447. package/dist/chunk-PMECEZK3.js.map +0 -1
  448. package/dist/chunk-R7FOF242.js +0 -59
  449. package/dist/chunk-R7FOF242.js.map +0 -1
  450. package/dist/chunk-R7NHYEJF.js.map +0 -1
  451. package/dist/chunk-RYYLMBA2.js +0 -392
  452. package/dist/chunk-RYYLMBA2.js.map +0 -1
  453. package/dist/chunk-SBSA3IQA.js.map +0 -1
  454. package/dist/chunk-VLTQGE2E.js.map +0 -1
  455. package/dist/chunk-WSBKB4CJ.js.map +0 -1
  456. package/dist/chunk-YOH2L76X.js +0 -505
  457. package/dist/chunk-YOH2L76X.js.map +0 -1
  458. package/dist/chunk-ZCAJZ4B2.js.map +0 -1
  459. package/dist/chunk-ZPWTOUTK.js.map +0 -1
  460. package/dist/flows-EQF2CH4U.js +0 -26
  461. package/dist/helpers-CFK6YP6R.js +0 -34
  462. package/dist/library-publish-53UTB3MB.js.map +0 -1
  463. package/dist/open-library-BOSPJVID.js +0 -40
  464. package/dist/open-registry-4FI7HKET.js +0 -32
  465. package/dist/paths-SUS4S4YT.js +0 -22
  466. package/dist/plugin-store-AGQDMING.js +0 -149
  467. package/dist/plugin-store-AGQDMING.js.map +0 -1
  468. package/dist/project-I55A4O2T.js +0 -41
  469. package/dist/skills-NUEN5NDX.js +0 -26
  470. package/dist/source-G2LV5LVD.js +0 -41
  471. package/dist/source-fetch-github-QN4LLTL5.js +0 -4
  472. package/dist/source-manifest-publish-6RM7SWLZ.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../core/src/type-guards.ts","../core/src/agent-instances.ts","../core/src/walker.ts","../core/src/repo-manager.ts","../core/src/workspace-config.ts"],"names":["semver","existsSync","join","readFileSync","relative","resolve","mkdirSync","writeFileSync","readdirSync","parsePath","dirname","parse","stringify","readdirAsync","statAsync","cpAsync","fsConstants","rmAsync","openAsync","readFileAsync"],"mappings":"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","file":"chunk-L3ZGYSWY.js","sourcesContent":["/** Narrow to a plain-object-shaped value (not `null`, not an array); fields stay `unknown`. */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n","/**\n * Named agent instances — the root `agents:` map of `skaile.yaml`.\n *\n * An *instance* binds one agent asset into the workspace under a stable id\n * (`ref`), with overrides (lifecycle, model, permissions, memory scope,\n * triggers, connector slot bindings, budget). The legacy `agent:` block stays\n * the primary instance and is equivalent to `agents.default`.\n *\n * Pure: normalisation, merge and the effective-map helper do no I/O. Checks\n * that need the agent asset (`ref` resolves, `io` on roles, slot ids) live in\n * `skaile validate`.\n */\n\nimport { isRecord } from \"./type-guards.js\";\nimport type { AgentPermissions, Diagnostic, SkWorkspaceConfig } from \"./workspace-config.js\";\n\n/** Instance ids and trigger ids: lowercase, start with a letter. */\nexport const AGENT_INSTANCE_ID_PATTERN = /^[a-z][a-z0-9_-]*$/;\n\n/** Id of the primary instance — the one `agent:` declares. */\nexport const DEFAULT_AGENT_INSTANCE_ID = \"default\";\n\nexport const AGENT_INSTANCE_LIFECYCLES = [\"standing\", \"role\"] as const;\nexport type AgentInstanceLifecycle = (typeof AGENT_INSTANCE_LIFECYCLES)[number];\n\n/** Where an instance's memory blocks live; `none` disables host memory for it. */\nexport const AGENT_INSTANCE_MEMORY_SCOPES = [\"instance\", \"user\", \"workspace\", \"none\"] as const;\nexport type AgentInstanceMemoryScope = (typeof AGENT_INSTANCE_MEMORY_SCOPES)[number];\n\nexport const AGENT_INSTANCE_TRIGGER_KINDS = [\"schedule\", \"webhook\", \"channel\", \"event\"] as const;\n\n/**\n * A trigger entry on an instance. Merged by `id` into the asset's triggers: a\n * bare `{ id, enabled: false }` or `{ id, timezone }` is a partial override of\n * the asset's trigger of that id; an entry with `kind` declares a complete\n * trigger of its own (required when the asset has no trigger with that id).\n */\nexport interface AgentInstanceTrigger {\n id: string;\n kind?: (typeof AGENT_INSTANCE_TRIGGER_KINDS)[number];\n enabled?: boolean;\n timezone?: string;\n cron?: string;\n prompt?: string;\n /** `channel` triggers: which channel messages fire it (e.g. `mention`). */\n when?: string;\n /** `event` triggers: protocol / host event name. */\n event?: string;\n}\n\nexport interface AgentInstanceModel {\n preferred?: string;\n fallback?: string[];\n}\n\nexport interface AgentInstanceBudget {\n max_turns?: number;\n max_tokens?: number;\n}\n\nexport interface AgentInstanceConfig {\n /** Agent asset reference — same forms as `agent.definition`. */\n ref: string;\n /** Overrides the asset's `lifecycle`. */\n lifecycle?: AgentInstanceLifecycle;\n model?: AgentInstanceModel;\n /** Same shape and stacking rules as `agent.permissions`. */\n permissions?: AgentPermissions;\n memory?: { scope: AgentInstanceMemoryScope };\n /** Merged by `id` into the asset's triggers. */\n triggers?: AgentInstanceTrigger[];\n /** Compose slot id (`composes[].id`) → `skaile.yaml` `connectors[].id`. */\n connectors?: Record<string, string>;\n budget?: AgentInstanceBudget;\n}\n\nconst INSTANCE_KEYS: Record<string, true> = {\n ref: true,\n lifecycle: true,\n model: true,\n permissions: true,\n memory: true,\n triggers: true,\n connectors: true,\n budget: true,\n};\n\n// ── Normalisation ─────────────────────────────────────────────────────────────\n\n/**\n * Normalise the raw root `agents:` value. Total: a malformed instance is\n * dropped (or has the offending field dropped) with an `error` diagnostic\n * rather than throwing. Returns `undefined` when no instance survives.\n */\nexport function normalizeAgentInstances(\n raw: unknown,\n diagnostics: Diagnostic[],\n): Record<string, AgentInstanceConfig> | undefined {\n if (raw === undefined || raw === null) return undefined;\n if (!isRecord(raw)) {\n diagnostics.push({\n code: \"invalid_agents_section\",\n severity: \"error\",\n message: \"`agents:` must be a mapping of instance id → { ref, … }.\",\n path: \"agents\",\n });\n return undefined;\n }\n const out: Record<string, AgentInstanceConfig> = {};\n for (const [id, value] of Object.entries(raw)) {\n const path = `agents.${id}`;\n if (!AGENT_INSTANCE_ID_PATTERN.test(id)) {\n diagnostics.push({\n code: \"invalid_agent_instance_id\",\n severity: \"error\",\n message: `Agent instance id \"${id}\" must match [a-z][a-z0-9_-]* (lowercase, starts with a letter).`,\n path,\n });\n continue;\n }\n if (!isRecord(value) || typeof value.ref !== \"string\" || value.ref.trim() === \"\") {\n diagnostics.push({\n code: \"invalid_agent_instance\",\n severity: \"error\",\n message: `Agent instance \"${id}\" needs a non-empty string \\`ref\\` (e.g. \"agent:@publisher/name\" or a local path).`,\n path: `${path}.ref`,\n });\n continue;\n }\n out[id] = normalizeInstance(id, value, value.ref, diagnostics);\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction normalizeInstance(\n id: string,\n raw: Record<string, unknown>,\n ref: string,\n diagnostics: Diagnostic[],\n): AgentInstanceConfig {\n const path = `agents.${id}`;\n const instance: AgentInstanceConfig = { ref };\n\n for (const key of Object.keys(raw)) {\n if (INSTANCE_KEYS[key]) continue;\n diagnostics.push({\n code: \"unknown_agent_instance_key\",\n severity: \"warning\",\n message: `Unknown key \"${key}\" on agent instance \"${id}\" is ignored — expected one of: ${Object.keys(INSTANCE_KEYS).join(\", \")}.`,\n path: `${path}.${key}`,\n });\n }\n\n if (raw.lifecycle !== undefined) {\n if ((AGENT_INSTANCE_LIFECYCLES as readonly unknown[]).includes(raw.lifecycle)) {\n instance.lifecycle = raw.lifecycle as AgentInstanceLifecycle;\n } else {\n diagnostics.push({\n code: \"invalid_agent_instance_lifecycle\",\n severity: \"error\",\n message: `Agent instance \"${id}\": lifecycle \"${String(raw.lifecycle)}\" — expected one of: ${AGENT_INSTANCE_LIFECYCLES.join(\", \")}.`,\n path: `${path}.lifecycle`,\n });\n }\n }\n\n if (isRecord(raw.model)) {\n const model: AgentInstanceModel = {};\n if (typeof raw.model.preferred === \"string\") model.preferred = raw.model.preferred;\n if (Array.isArray(raw.model.fallback)) {\n model.fallback = raw.model.fallback.filter((m): m is string => typeof m === \"string\");\n }\n if (Object.keys(model).length > 0) instance.model = model;\n }\n\n if (isRecord(raw.permissions)) instance.permissions = raw.permissions as AgentPermissions;\n\n if (raw.memory !== undefined) {\n const scope = isRecord(raw.memory) ? raw.memory.scope : undefined;\n if ((AGENT_INSTANCE_MEMORY_SCOPES as readonly unknown[]).includes(scope)) {\n instance.memory = { scope: scope as AgentInstanceMemoryScope };\n } else {\n diagnostics.push({\n code: \"invalid_agent_instance_memory_scope\",\n severity: \"error\",\n message: `Agent instance \"${id}\": memory.scope ${scope === undefined ? \"is required\" : `\"${String(scope)}\" is unknown`} — expected one of: ${AGENT_INSTANCE_MEMORY_SCOPES.join(\", \")}.`,\n path: `${path}.memory.scope`,\n });\n }\n }\n\n if (Array.isArray(raw.triggers)) {\n const triggers = normalizeTriggers(id, raw.triggers, diagnostics);\n if (triggers.length > 0) instance.triggers = triggers;\n } else if (raw.triggers !== undefined) {\n diagnostics.push({\n code: \"invalid_agent_instance_triggers\",\n severity: \"error\",\n message: `Agent instance \"${id}\": triggers must be a list of { id, … } entries.`,\n path: `${path}.triggers`,\n });\n }\n\n if (isRecord(raw.connectors)) {\n const connectors: Record<string, string> = {};\n for (const [slot, connectorId] of Object.entries(raw.connectors)) {\n if (typeof connectorId === \"string\" && connectorId !== \"\") {\n connectors[slot] = connectorId;\n } else {\n diagnostics.push({\n code: \"invalid_agent_instance_connector\",\n severity: \"error\",\n message: `Agent instance \"${id}\": connectors.${slot} must name a skaile.yaml connectors[].id.`,\n path: `${path}.connectors.${slot}`,\n });\n }\n }\n if (Object.keys(connectors).length > 0) instance.connectors = connectors;\n } else if (raw.connectors !== undefined) {\n diagnostics.push({\n code: \"invalid_agent_instance_connector\",\n severity: \"error\",\n message: `Agent instance \"${id}\": connectors must map compose slot ids to connectors[].id.`,\n path: `${path}.connectors`,\n });\n }\n\n if (isRecord(raw.budget)) {\n const budget: AgentInstanceBudget = {};\n if (typeof raw.budget.max_turns === \"number\") budget.max_turns = raw.budget.max_turns;\n if (typeof raw.budget.max_tokens === \"number\") budget.max_tokens = raw.budget.max_tokens;\n if (Object.keys(budget).length > 0) instance.budget = budget;\n }\n\n return instance;\n}\n\nfunction normalizeTriggers(\n instanceId: string,\n raw: unknown[],\n diagnostics: Diagnostic[],\n): AgentInstanceTrigger[] {\n const out: AgentInstanceTrigger[] = [];\n raw.forEach((item, i) => {\n const path = `agents.${instanceId}.triggers[${i}]`;\n if (\n !isRecord(item) ||\n typeof item.id !== \"string\" ||\n !AGENT_INSTANCE_ID_PATTERN.test(item.id)\n ) {\n diagnostics.push({\n code: \"invalid_agent_instance_trigger\",\n severity: \"error\",\n message: `Agent instance \"${instanceId}\": trigger ${i} needs an \\`id\\` matching [a-z][a-z0-9_-]*.`,\n path: `${path}.id`,\n });\n return;\n }\n if (\n item.kind !== undefined &&\n !(AGENT_INSTANCE_TRIGGER_KINDS as readonly unknown[]).includes(item.kind)\n ) {\n diagnostics.push({\n code: \"invalid_agent_instance_trigger\",\n severity: \"error\",\n message: `Agent instance \"${instanceId}\": trigger \"${item.id}\" kind \"${String(item.kind)}\" — expected one of: ${AGENT_INSTANCE_TRIGGER_KINDS.join(\", \")}.`,\n path: `${path}.kind`,\n });\n return;\n }\n out.push({ ...item } as unknown as AgentInstanceTrigger);\n });\n return out;\n}\n\n// ── Merge ─────────────────────────────────────────────────────────────────────\n\nfunction definedEntries<T extends object>(obj: T | undefined): Partial<T> {\n const out: Partial<T> = {};\n for (const [key, value] of Object.entries(obj ?? {})) {\n if (value !== undefined) (out as Record<string, unknown>)[key] = value;\n }\n return out;\n}\n\n/**\n * Merge two `permissions` blocks: scalars overlay-win, `deny_write` /\n * `deny_read` are unioned. Shared by `agent.permissions` and instance permissions.\n */\nexport function mergeAgentPermissions(\n base: AgentPermissions | undefined,\n overlay: AgentPermissions | undefined,\n): AgentPermissions {\n return {\n ...base,\n ...definedEntries(overlay),\n deny_write: [...new Set([...(base?.deny_write ?? []), ...(overlay?.deny_write ?? [])])],\n deny_read: [...new Set([...(base?.deny_read ?? []), ...(overlay?.deny_read ?? [])])],\n };\n}\n\n/** Merge triggers by `id`: same id → fields overlay-win; new ids append. */\nfunction mergeTriggers(\n base: AgentInstanceTrigger[] | undefined,\n overlay: AgentInstanceTrigger[] | undefined,\n): AgentInstanceTrigger[] {\n const byId = new Map<string, AgentInstanceTrigger>();\n for (const t of [...(base ?? []), ...(overlay ?? [])]) {\n byId.set(t.id, { ...byId.get(t.id), ...definedEntries(t) } as AgentInstanceTrigger);\n }\n return [...byId.values()];\n}\n\nfunction mergeInstance(\n base: AgentInstanceConfig,\n overlay: AgentInstanceConfig,\n): AgentInstanceConfig {\n const merged: AgentInstanceConfig = { ref: overlay.ref };\n const lifecycle = overlay.lifecycle ?? base.lifecycle;\n if (lifecycle) merged.lifecycle = lifecycle;\n if (base.model || overlay.model)\n merged.model = { ...base.model, ...definedEntries(overlay.model) };\n if (base.permissions || overlay.permissions) {\n merged.permissions = mergeAgentPermissions(base.permissions, overlay.permissions);\n }\n const memory = overlay.memory ?? base.memory;\n if (memory) merged.memory = memory;\n if (base.triggers || overlay.triggers)\n merged.triggers = mergeTriggers(base.triggers, overlay.triggers);\n if (base.connectors || overlay.connectors) {\n merged.connectors = { ...base.connectors, ...overlay.connectors };\n }\n if (base.budget || overlay.budget)\n merged.budget = { ...base.budget, ...definedEntries(overlay.budget) };\n return merged;\n}\n\n/**\n * Merge instance maps across config layers: keyed by id; an id present in both\n * layers merges field-wise (scalars overlay-win, `triggers` by id, deny lists\n * unioned, `connectors` per slot). Returns `undefined` when neither layer has instances.\n */\nexport function mergeAgentInstances(\n base: Record<string, AgentInstanceConfig> | undefined,\n overlay: Record<string, AgentInstanceConfig> | undefined,\n): Record<string, AgentInstanceConfig> | undefined {\n if (!base && !overlay) return undefined;\n const out: Record<string, AgentInstanceConfig> = { ...base };\n for (const [id, instance] of Object.entries(overlay ?? {})) {\n const existing = out[id];\n out[id] = existing ? mergeInstance(existing, instance) : instance;\n }\n return out;\n}\n\n// ── Effective map + diagnostics ───────────────────────────────────────────────\n\n/**\n * Every instance of a workspace config: the declared `agents:` map plus the\n * `default` instance derived from `agent.definition`. When both declare\n * `default` the config is invalid (see {@link agentInstanceDiagnostics}); the\n * primary `agent:` wins here because that is what the runner builds.\n */\nexport function effectiveAgentInstances(\n config: Pick<SkWorkspaceConfig, \"agent\">,\n): Record<string, AgentInstanceConfig> {\n const out: Record<string, AgentInstanceConfig> = { ...config.agent?.instances };\n const definition = config.agent?.definition;\n if (definition) out[DEFAULT_AGENT_INSTANCE_ID] = { ref: definition };\n return out;\n}\n\n/** `agent_default_conflict` error when `agent.definition` and `agents.default` are both declared. */\nexport function agentInstanceDiagnostics(config: Pick<SkWorkspaceConfig, \"agent\">): Diagnostic[] {\n if (config.agent?.definition && config.agent.instances?.[DEFAULT_AGENT_INSTANCE_ID]) {\n return [\n {\n code: \"agent_default_conflict\",\n severity: \"error\",\n message:\n \"`agent:` and `agents.default` both declare the primary agent — `agent:` is the \" +\n \"default instance. Remove one of them.\",\n path: `agents.${DEFAULT_AGENT_INSTANCE_ID}`,\n },\n ];\n }\n return [];\n}\n\n/** The keys of the primary `agent:` block (see `AgentConfig`); `instances` is rejected apart. */\nconst AGENT_BLOCK_KEYS: ReadonlySet<string> = new Set([\n \"definition\",\n \"context\",\n \"permissions\",\n \"hooks\",\n \"fragments\",\n \"prompt-extensions\",\n \"home\",\n \"prompt\",\n \"instances\",\n \"subagents\",\n]);\n\n/**\n * `unknown_agent_key` warning per key of the primary `agent:` block that nothing reads, like\n * `unknown_agent_instance_key` for `agents.<id>`. Per-instance overrides belong under `agents`.\n */\nexport function agentBlockKeyDiagnostics(agent: unknown): Diagnostic[] {\n if (!isRecord(agent)) return [];\n return Object.keys(agent)\n .filter((key) => !AGENT_BLOCK_KEYS.has(key))\n .map((key) => ({\n code: \"unknown_agent_key\",\n severity: \"warning\" as const,\n message: `Unknown key \"${key}\" under \\`agent:\\` is ignored — expected one of: ${[...AGENT_BLOCK_KEYS].filter((k) => k !== \"subagents\").join(\", \")}. Per-instance overrides (lifecycle, model, memory, triggers, connectors, budget) belong under \\`agents.<id>\\`.`,\n path: `agent.${key}`,\n }));\n}\n","/**\n * Provenance-index walker.\n *\n * Given a list of cloned source paths plus their resolved commits, walk each\n * clone, read its `skaile.manifest.yaml` (or fall back to the agentskills.io\n * filename layout), compute per-file and composite sha256s, and build a\n * {@link ProvenanceIndex} keyed by `<publisher>/<kind>:<name>`.\n *\n * Manifest discovery is recursive: a `skaile.manifest.yaml` at the repo root\n * *and* under any subdirectory contributes assets (a curator repo carries one\n * manifest per upstream). A manifest (or asset entry) with a `source:` pointer\n * is **curated** — its bytes live in the referenced upstream, so the candidate's\n * `sourceUrl`/`commit` stamp the upstream and the hashes come from the author-\n * pinned `sha256` / granular `files[].sha256` rather than from local bytes.\n *\n * This is the source-side half of the canonical-identity resolution model: the\n * resolver compares these candidates against store-side candidates and detects\n * divergent content hashes for the same `(publisher, kind, name, version)`.\n */\n\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { join, posix, relative } from \"node:path\";\nimport fg from \"fast-glob\";\nimport semver from \"semver\";\nimport {\n agentYamlRequires,\n assetDepRefs,\n parseFrontmatter,\n parseRequires,\n scanDirectory,\n} from \"./manifest.js\";\nimport { type Dependency, depToStr, isValidAssetName, slugifyAssetName } from \"./models.js\";\nimport { dedupeRequirementRefs } from \"./requirements.js\";\nimport {\n type AssetEntry,\n compositeSha256,\n decodeSkaileManifest,\n listAssetFiles,\n type ManifestFileEntry,\n type ManifestSource,\n SKAILE_MANIFEST_FILENAME,\n sha256Hex,\n} from \"./publish-manifest.js\";\n\n/** One cloned source repo, pinned at a resolved commit. */\nexport interface SourceClone {\n localPath: string;\n sourceUrl: string;\n /** 40-char SHA. */\n commit: string;\n /** Publisher declared with `source add --publisher`: used when the manifest declares none, before the GitHub-org fallback. */\n publisher?: string;\n /** Optional tag context for the version waterfall (step 3). */\n tag?: string;\n /**\n * Optional curated overlay manifest FILE (the local store's flat\n * `~/.skaile/store/manifests/<slug>.yaml`, authored by `source manifest init`).\n * When set and the file exists, it is the AUTHORITATIVE inventory for this\n * clone — the walker reads it INSTEAD of scanning the clone's own manifests /\n * agentskills.io layout, so the curated publisher + asset set resolve. Byte\n * paths (`root`/`files`) still resolve against `localPath`. Mirrors the\n * discovery-side overlay so `add`/resolve agree with what `source add` indexed.\n */\n overlayManifestPath?: string;\n}\n\n/** One resolved candidate in the provenance index. */\nexport interface ProvenanceCandidate {\n publisher: string;\n kind: string;\n name: string;\n /** Canonical semver string (or `0.0.0-sha.<7char>`). */\n version: string;\n sourceUrl: string;\n commit: string;\n files: Array<{ path: string; sha256: string }>;\n /** Composite sha256 over sorted `<path>:<sha256>\\n` rows. */\n sha256: string;\n /** Parsed content frontmatter (mcp-server defaults etc.). */\n metadata?: Record<string, unknown>;\n /** Canonical transitive dependency refs (`kind:name@<publisher>[#pin]`).\n * Populated from the manifest's `assets[].dependencies` when present, else\n * for presets from the preset's asset items. `resolveAll` recurses into these so a\n * preset pulls its members (and nested presets). */\n deps?: string[];\n /** Preset only: items an expansion skips (`library://` instances, placeholder and\n * connector/mcp instance items). Reported by `skaile install`. */\n skippedItems?: number;\n\n // ── Store-listing metadata (manifest-wins-else-frontmatter; all optional) ──\n description?: string;\n keywords?: string[];\n category?: string;\n license?: string;\n homepage?: string;\n}\n\nexport type ProvenanceIndex = Map<string, ProvenanceCandidate[]>;\n\n/**\n * The composite digest of a candidate (`compositeSha256`, `publish-manifest.ts`)\n * is byte-for-byte the store's `computeCompositeSha256` (publish-shared.ts), the\n * `InstallManifest.sha256` rollup AND the hash discovery indexes a library or\n * source asset with, so source-side, library-side and store-side digests are\n * directly comparable (the resolver's cross-source divergence probe, and the\n * lock's `sha256` for every origin).\n */\nfunction fileSha256(p: string): string {\n return sha256Hex(readFileSync(p));\n}\n\n/**\n * Canonical GitHub-org → publisher slug. The single lowercasing rule shared by\n * the resolve side (`buildProvenanceIndex` here) and the index side\n * (`resolveSourcePublisher` in repo-manager). GitHub orgs are case-insensitive,\n * so a cased remote (`Acme`) and a lowercase index ref must not split.\n */\nexport function normalizeGithubOrg(org: string): string {\n return org.toLowerCase();\n}\n\nfunction publisherFromGithubUrl(url: string): string | undefined {\n const m = url.match(/github\\.com[/:]([^/]+)\\/[^/]+/);\n return m ? normalizeGithubOrg(m[1]) : undefined;\n}\n\nfunction syntheticVersion(commit: string): string {\n return `0.0.0-sha.${commit.slice(0, 7)}`;\n}\n\n/** Agentskills.io filename layout: `<repo-root>/<kind-plural>/<name>/<KIND>.md`. */\nconst KIND_DIRS: Array<{ dir: string; kind: string; mdName: string }> = [\n { dir: \"skills\", kind: \"skill\", mdName: \"SKILL.md\" },\n { dir: \"agents\", kind: \"agent\", mdName: \"AGENT.md\" },\n { dir: \"mcp-servers\", kind: \"mcp-server\", mdName: \"MCP.md\" },\n { dir: \"connectors\", kind: \"connector\", mdName: \"CONNECTOR.md\" },\n { dir: \"prompts\", kind: \"prompt\", mdName: \"PROMPT.md\" },\n { dir: \"contracts\", kind: \"contract\", mdName: \"CONTRACT.md\" },\n];\n\nconst MD_FILE_BY_KIND: Record<string, string> = Object.fromEntries(\n KIND_DIRS.map((k) => [k.kind, k.mdName]),\n);\n\n/**\n * Walk a list of source clones into a provenance index.\n *\n * @param clones - Cloned source repos pinned at resolved commits.\n * @param opts.onSourceError - Receives a clone whose walk failed (a non-GitHub source with no\n * `publisher:` anywhere in its manifest, a SKILL.md name mismatch). The clone is then left\n * out of the index, so one bad source never stops a ref that comes from another one.\n * Without it the error propagates (the old all-or-nothing behaviour).\n * @returns Map of `<publisher>/<kind>:<name>` → candidates.\n * @throws On a SKILL.md name mismatch or a missing publisher for a non-GitHub source (when no `onSourceError`).\n * @docLink packages/core/workspace-config#build-provenance-index\n */\nexport async function buildProvenanceIndex(\n clones: SourceClone[],\n opts: {\n projectDir?: string;\n knownKinds: ReadonlySet<string>;\n onSourceError?: (clone: SourceClone, err: unknown) => void;\n },\n): Promise<ProvenanceIndex> {\n const index: ProvenanceIndex = new Map();\n for (const clone of clones) {\n if (!opts.onSourceError) {\n await walkOne(clone, index, opts.knownKinds);\n continue;\n }\n // Walk into a scratch index: a source that fails half-way contributes nothing.\n const scratch: ProvenanceIndex = new Map();\n try {\n await walkOne(clone, scratch, opts.knownKinds);\n } catch (err) {\n opts.onSourceError(clone, err);\n continue;\n }\n for (const [key, candidates] of scratch) for (const c of candidates) push(index, key, c);\n }\n return index;\n}\n\nasync function walkOne(\n clone: SourceClone,\n index: ProvenanceIndex,\n knownKinds: ReadonlySet<string>,\n): Promise<void> {\n // Curated store overlay wins: when present, it is the authoritative inventory\n // (the same replace-on-presence rule discovery applies), so resolution agrees\n // with the curated publisher/assets `source add` indexed.\n if (clone.overlayManifestPath && existsSync(clone.overlayManifestPath)) {\n if (await walkWithManifest(clone, clone.overlayManifestPath, index)) return;\n // Overlay present but declared no assets[] — fall through to the clone scan.\n }\n const manifestPaths = findManifestFiles(clone.localPath);\n // Glob mode (no manifest, or one without `assets:`): every asset the scan finds gets the\n // manifest's repo-level `publisher` (and `version`), the same chain `search` reads.\n const repoLevel = repoLevelManifest(\n [clone.overlayManifestPath, ...manifestPaths].filter((p): p is string => !!p),\n );\n if (manifestPaths.length === 0) {\n await walkFilenameConvention(clone, index, knownKinds, repoLevel);\n return;\n }\n let produced = false;\n for (const p of manifestPaths) {\n if (await walkWithManifest(clone, p, index)) produced = true;\n }\n // Manifest(s) present but none declared assets[]: fall back to the\n // agentskills.io filename convention (matches the single-manifest behaviour).\n if (!produced) await walkFilenameConvention(clone, index, knownKinds, repoLevel);\n}\n\n/** The repo-level `publisher` / `version` of the first of `paths` that declares them. */\nfunction repoLevelManifest(paths: string[]): { publisher?: string; version?: string } {\n for (const p of paths) {\n if (!existsSync(p)) continue;\n const { manifest } = decodeSkaileManifest(readFileSync(p, \"utf8\"));\n if (manifest.publisher) {\n return {\n publisher: manifest.publisher.replace(/^@/, \"\"),\n version: manifest.version,\n };\n }\n }\n return {};\n}\n\n/**\n * Recursively find every `skaile.manifest.yaml` under `root`, skipping\n * `.git`/`node_modules` (same skip list as the rest of the walker).\n *\n * **Deliberately synchronous and unbounded**, unlike `manifest.ts walkDir`.\n * `root` is always `clone.localPath` — a clone under `getGlobalCacheDir()`,\n * which is container-local storage this package created itself. It is never the\n * rclone FUSE workspace mount, so the #454 hazard (a sync call parking the\n * event loop on an unresponsive mount) does not apply. Do **not** copy this\n * shape to a path that can reach the mount, and if a caller ever passes one\n * here, convert this to the bounded async `walkDir` instead of widening it.\n */\nfunction findManifestFiles(root: string): string[] {\n const found: string[] = [];\n const walk = (dir: string): void => {\n if (!existsSync(dir)) return;\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.name === \".git\" || entry.name === \"node_modules\") continue;\n const abs = join(dir, entry.name);\n if (entry.isDirectory()) walk(abs);\n else if (entry.isFile() && entry.name === SKAILE_MANIFEST_FILENAME) found.push(abs);\n }\n };\n walk(root);\n return found;\n}\n\n/**\n * Walk one `skaile.manifest.yaml` into the index. Returns `true` when it\n * produced at least one candidate.\n *\n * First-party assets (no `source:`) read bytes from the local clone. Curated\n * assets (manifest- or asset-level `source:`) are pointers: the candidate's\n * `sourceUrl`/`commit` stamp the upstream and the hashes come from the author-\n * pinned `sha256` / granular `files[].sha256`.\n */\nasync function walkWithManifest(\n clone: SourceClone,\n manifestPath: string,\n index: ProvenanceIndex,\n): Promise<boolean> {\n const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, \"utf8\"));\n const repoRoot = clone.localPath;\n const manifestPublisher =\n manifest.publisher ?? clone.publisher ?? publisherFromGithubUrl(clone.sourceUrl);\n const manifestVersion =\n manifest.version ??\n (clone.tag ? clone.tag.replace(/^v/, \"\") : undefined) ??\n syntheticVersion(clone.commit);\n\n const assets = manifest.assets ?? [];\n if (assets.length === 0) return false;\n\n for (const a of assets) {\n const assetPublisher = a.publisher ?? manifestPublisher;\n if (!assetPublisher) {\n throw new Error(\n `${clone.sourceUrl}: publisher must be declared in skaile.manifest.yaml ` +\n \"(non-GitHub source URL — auto-derivation not available) or recorded with `skaile source add --publisher`.\",\n );\n }\n const curatedSource = a.source ?? manifest.source;\n const entryVersion = a.version ?? manifestVersion;\n // A third-party manifest may declare a human-styled name; slugify it to a\n // canonical identity so the ref it produces parses (no-op when canonical).\n const name = canonicalAssetName(a.name);\n\n const resolved = resolveAssetBytes(clone, repoRoot, a, curatedSource);\n const { files } = resolved;\n // The asset file is the source of truth for its version (`info`/`search` read it from\n // there), so a manifest entry or the manifest top level only supplies one when the file\n // declares none; a curated pointer has no readable file and keeps the manifest's.\n const version = declaredFileVersion(resolved.frontmatter) ?? entryVersion;\n\n const candidate: ProvenanceCandidate = {\n publisher: assetPublisher,\n kind: a.kind,\n name,\n version,\n sourceUrl: resolved.sourceUrl,\n commit: resolved.commit,\n files,\n sha256: a.sha256 ?? compositeSha256(files),\n metadata: resolved.metadata,\n ...(await candidateDeps(repoRoot, files, a.kind, assetPublisher, a.dependencies)),\n };\n\n applyStoreListingMetadata(candidate, a, manifest, resolved.frontmatter);\n\n push(index, `${assetPublisher}/${a.kind}:${name}`, candidate);\n }\n return true;\n}\n\n/** The semver an asset file declares in its frontmatter: top-level `version`, else\n * `metadata.version` (the same reading `info`/`search` use), or `undefined`. A value that is\n * not semver is ignored: it cannot be the pin of a lock key. */\nfunction declaredFileVersion(frontmatter: Record<string, unknown> | undefined): string | undefined {\n if (!frontmatter) return undefined;\n const scalar = (v: unknown): string | undefined =>\n typeof v === \"string\" ? v : typeof v === \"number\" ? String(v) : undefined;\n const meta = frontmatter.metadata;\n const nested =\n meta !== null && typeof meta === \"object\"\n ? scalar((meta as Record<string, unknown>).version)\n : undefined;\n const version = scalar(frontmatter.version) ?? nested;\n return version !== undefined && semver.valid(version) ? version : undefined;\n}\n\n/** Canonical asset name: returned as-is when already valid, slugified when a\n * third-party source declared a human-styled name, or left untouched when it\n * can't be slugified (downstream `parseAssetRef` then reports the full error). */\nfunction canonicalAssetName(raw: string): string {\n if (isValidAssetName(raw)) return raw;\n try {\n return slugifyAssetName(raw);\n } catch {\n return raw;\n }\n}\n\n/** Resolved bytes + provenance for one asset entry. */\ninterface ResolvedAssetBytes {\n files: Array<{ path: string; sha256: string }>;\n sourceUrl: string;\n commit: string;\n metadata?: Record<string, unknown>;\n frontmatter?: Record<string, unknown>;\n}\n\n/**\n * Resolve an asset's files + provenance stamp. Curated assets (a `source:`\n * pointer) read author-pinned granular `files[]`/sha256 and stamp the upstream;\n * first-party assets read bytes from the local clone and additionally surface\n * metadata + content frontmatter.\n */\nfunction resolveAssetBytes(\n clone: SourceClone,\n repoRoot: string,\n a: AssetEntry,\n curatedSource: ManifestSource | undefined,\n): ResolvedAssetBytes {\n if (curatedSource) {\n // Pointer — bytes live upstream (never vendored). Use the author-pinned\n // granular files[]/sha256; stamp provenance to the upstream.\n return {\n files: granularFiles(a) ?? [],\n sourceUrl: curatedSource.url,\n commit: curatedSource.commit ?? clone.commit,\n };\n }\n // First-party — bytes from the local clone.\n const files = expandAssetFiles(repoRoot, a);\n verifyNameMatch(repoRoot, files, a.name, a.kind);\n return {\n files,\n sourceUrl: clone.sourceUrl,\n commit: clone.commit,\n metadata: readMetadata(repoRoot, files, a.kind),\n frontmatter: readContentFrontmatter(repoRoot, files, a.kind),\n };\n}\n\n/**\n * Fold store-listing metadata onto a candidate in place: manifest field wins,\n * else content frontmatter, with repo-level license/homepage as the per-asset\n * default.\n */\nfunction applyStoreListingMetadata(\n candidate: ProvenanceCandidate,\n a: AssetEntry,\n manifest: { license?: string; homepage?: string },\n frontmatter: Record<string, unknown> | undefined,\n): void {\n const fmStr = (k: string): string | undefined =>\n typeof frontmatter?.[k] === \"string\" ? (frontmatter[k] as string) : undefined;\n const fmArr = (k: string): string[] | undefined =>\n Array.isArray(frontmatter?.[k])\n ? (frontmatter[k] as unknown[]).filter((x): x is string => typeof x === \"string\")\n : undefined;\n const description = a.description ?? fmStr(\"description\");\n const keywords = a.keywords ?? fmArr(\"keywords\");\n const category = a.category ?? fmStr(\"category\");\n const license = a.license ?? manifest.license;\n const homepage = a.homepage ?? manifest.homepage;\n if (description) candidate.description = description;\n if (keywords && keywords.length > 0) candidate.keywords = keywords;\n if (category) candidate.category = category;\n if (license) candidate.license = license;\n if (homepage) candidate.homepage = homepage;\n}\n\n/** The glob strings of an asset's `files:` (first-party form). */\nfunction globFiles(a: AssetEntry): string[] | undefined {\n if (!Array.isArray(a.files)) return undefined;\n const strings = a.files.filter((f): f is string => typeof f === \"string\");\n return strings.length > 0 ? strings : undefined;\n}\n\n/** The granular `{path, sha256}` entries of an asset's `files:` (curated form). */\nfunction granularFiles(a: AssetEntry): ManifestFileEntry[] | undefined {\n if (!Array.isArray(a.files)) return undefined;\n const granular = a.files.filter(\n (f): f is ManifestFileEntry => !!f && typeof f === \"object\" && \"path\" in f && \"sha256\" in f,\n );\n return granular.length > 0 ? granular : undefined;\n}\n\nfunction expandAssetFiles(\n repoRoot: string,\n a: AssetEntry,\n): Array<{ path: string; sha256: string }> {\n const out: Array<{ path: string; sha256: string }> = [];\n if (a.root) {\n out.push(...hashedFilesUnder(repoRoot, a.root));\n }\n const globs = globFiles(a);\n if (globs) {\n const matches = fg.sync(globs, { cwd: repoRoot, onlyFiles: true, dot: false });\n for (const rel of matches) {\n out.push({ path: rel, sha256: fileSha256(join(repoRoot, rel)) });\n }\n }\n // dedupe by path\n const seen = new Set<string>();\n return out.filter((f) => (seen.has(f.path) ? false : (seen.add(f.path), true)));\n}\n\n/**\n * Every file under `<repoRoot>/<dir>` as a `{path, sha256}` row, `path` POSIX and\n * relative to `repoRoot`. The file list comes from `listAssetFiles`, the same\n * enumeration discovery uses for a `root:` entry.\n */\nfunction hashedFilesUnder(repoRoot: string, dir: string): Array<{ path: string; sha256: string }> {\n const base = posix.normalize(dir.replace(/\\\\/g, \"/\"));\n return listAssetFiles(join(repoRoot, dir)).map((rel) => {\n const path = posix.join(base, rel);\n return { path, sha256: fileSha256(join(repoRoot, path)) };\n });\n}\n\n/** Kinds whose asset spans the manifest file's whole containing directory\n * (SKILL.md + scripts, etc.). The rest are single-file assets (a `.preset.yaml`,\n * `.flow.yaml`, or `.prompt.md` standing alone). */\nconst DIR_SCOPED_KINDS = new Set([\n \"skill\",\n \"agent\",\n \"contract\",\n \"mcp-server\",\n \"connector\",\n \"knowledge\",\n]);\n\nasync function walkFilenameConvention(\n clone: SourceClone,\n index: ProvenanceIndex,\n knownKinds: ReadonlySet<string>,\n repoLevel: { publisher?: string; version?: string } = {},\n): Promise<void> {\n // Same chain as `walkWithManifest`: the manifest's repo-level `publisher` first, then the one\n // `source add --publisher` recorded, then the GitHub org of the source URL. Only a source with\n // none of them has no publisher to give.\n const publisher =\n repoLevel.publisher ?? clone.publisher ?? publisherFromGithubUrl(clone.sourceUrl);\n if (!publisher) {\n throw new Error(\n `${clone.sourceUrl}: publisher must be declared in skaile.manifest.yaml ` +\n \"(non-GitHub source URL) or recorded with `skaile source add --publisher`.\",\n );\n }\n const version =\n repoLevel.version ??\n (clone.tag ? clone.tag.replace(/^v/, \"\") : undefined) ??\n syntheticVersion(clone.commit);\n\n // Reuse the catalog scanner so the provenance fallback discovers exactly the\n // assets `manage` lists — recursively, by manifest filename, anywhere in the\n // tree. The old top-level `<kind-plural>/<name>/` scan missed nested assets\n // (e.g. `flows/x/x.flow.yaml`): the TUI listed them but `add` couldn't\n // resolve them. See _devlog/notes/2026-06-02-provenance-fallback-recursion.md.\n for (const e of await scanDirectory(clone.localPath, publisher, { knownKinds })) {\n const manifestAbs = e.source;\n const manifestRel = relative(clone.localPath, manifestAbs).replace(/\\\\/g, \"/\");\n const files: Array<{ path: string; sha256: string }> = DIR_SCOPED_KINDS.has(e.kind)\n ? hashedFilesUnder(clone.localPath, posix.dirname(manifestRel))\n : [{ path: manifestRel, sha256: fileSha256(manifestAbs) }];\n const candidate: ProvenanceCandidate = {\n publisher,\n kind: e.kind,\n name: e.name,\n version,\n sourceUrl: clone.sourceUrl,\n commit: clone.commit,\n files,\n sha256: compositeSha256(files),\n metadata: readMetadata(clone.localPath, files, e.kind),\n ...(await candidateDeps(clone.localPath, files, e.kind, publisher)),\n };\n push(index, `${publisher}/${e.kind}:${e.name}`, candidate);\n }\n}\n\nfunction verifyNameMatch(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n expectedName: string,\n kind: string,\n): void {\n const mdName = MD_FILE_BY_KIND[kind];\n if (!mdName) return;\n const md = files.find((f) => f.path.endsWith(mdName));\n if (!md) return;\n const { data } = parseFrontmatter(readFileSync(join(repoRoot, md.path), \"utf8\"));\n const declared = typeof data.name === \"string\" ? data.name : undefined;\n // Compare on the canonical (slugified) form so a manifest and its SKILL.md that\n // agree on a human-styled name (\"Complex App\" vs \"complex-app\") don't false-trip.\n if (declared && canonicalAssetName(declared) !== canonicalAssetName(expectedName)) {\n throw new Error(\n `name mismatch: ${mdName} says \"${declared}\", skaile.manifest.yaml says ` +\n `\"${expectedName}\" — index-time hard error.`,\n );\n }\n}\n\nfunction readMetadata(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n kind: string,\n): Record<string, unknown> | undefined {\n // For MCP servers, return parsed frontmatter so loadMcpServerDeclarations\n // gets command/args/env defaults.\n if (kind !== \"mcp-server\") return undefined;\n const mcpMd = files.find((f) => f.path.endsWith(\"MCP.md\"));\n if (!mcpMd) return undefined;\n const { data } = parseFrontmatter(readFileSync(join(repoRoot, mcpMd.path), \"utf8\"));\n return data;\n}\n\n/** Read the asset's manifest-file frontmatter (SKILL.md, AGENT.md, …) so the\n * walker can fall back to content `description`/`keywords` when the manifest\n * omits the store-listing fields. Returns undefined when the kind has no\n * manifest file or it is absent among `files`. */\nfunction readContentFrontmatter(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n kind: string,\n): Record<string, unknown> | undefined {\n const mdName = MD_FILE_BY_KIND[kind];\n if (!mdName) return undefined;\n const md = files.find((f) => f.path.endsWith(mdName));\n if (!md) return undefined;\n try {\n return parseFrontmatter(readFileSync(join(repoRoot, md.path), \"utf8\")).data;\n } catch {\n return undefined;\n }\n}\n\n/** For a preset or flow, locate its manifest among `files` and read its\n * transitive dep refs (a flow's `requires:`, a preset's asset `items[].ref`s) plus,\n * for a preset, how many instance items an expansion skips. Without this,\n * installing a flow deploys only the `.flow.yaml` and never the contracts/skills/\n * sub-flows it declares. Returns `{}` for other kinds or when no manifest is\n * present. */\nasync function manifestDeps(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n kind: string,\n): Promise<{ deps?: string[]; skippedItems?: number }> {\n const ext =\n kind === \"preset\" ? [\".preset.yaml\"] : kind === \"flow\" ? [\".flow.yaml\", \".flow.json\"] : null;\n if (!ext) return {};\n const mf = files.find((f) => ext.some((e) => f.path.endsWith(e)));\n if (!mf) return {};\n const { refs, skipped } = await assetDepRefs(join(repoRoot, mf.path));\n return kind === \"preset\" ? { deps: refs, skippedItems: skipped } : { deps: refs };\n}\n\n/** The `composes:` refs of an agent's `agent.yaml` among `files` (an agent's composed\n * skills, connectors and sub-agents are requirements, as in a library scan of it). */\nfunction readAgentYamlRequires(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n kind: string,\n): Dependency[] {\n if (kind !== \"agent\") return [];\n const yaml = files.find((f) => posix.basename(f.path) === \"agent.yaml\");\n if (!yaml) return [];\n try {\n return agentYamlRequires(readFileSync(join(repoRoot, yaml.path), \"utf8\"));\n } catch {\n return [];\n }\n}\n\n/**\n * Every transitive dependency of a candidate, as requirement refs: the manifest entry's\n * own `dependencies` (`explicit`) or, for a preset / flow, the refs its file declares,\n * plus the `requires` its manifest file (SKILL.md, AGENT.md, …) lists in its frontmatter.\n * Each requirement is listed once ({@link dedupeRequirementRefs}; a bare ref means the\n * candidate's own publisher), so `resolveAll` pulls what a library scan of the same asset\n * would: a source asset deploys its `requires` like a library asset does.\n */\nasync function candidateDeps(\n repoRoot: string,\n files: Array<{ path: string; sha256: string }>,\n kind: string,\n publisher: string,\n explicit?: string[],\n): Promise<{ deps?: string[]; skippedItems?: number }> {\n const base = explicit ? { deps: explicit } : await manifestDeps(repoRoot, files, kind);\n if (kind === \"preset\" || kind === \"flow\") return base;\n const frontmatter = readContentFrontmatter(repoRoot, files, kind);\n const declared = [\n ...(frontmatter ? parseRequires(frontmatter) : []),\n ...readAgentYamlRequires(repoRoot, files, kind),\n ].map(depToStr);\n if (declared.length === 0) return base;\n return { ...base, deps: dedupeRequirementRefs([...(base.deps ?? []), ...declared], publisher) };\n}\n\nfunction push(index: ProvenanceIndex, key: string, candidate: ProvenanceCandidate): void {\n const arr = index.get(key) ?? [];\n arr.push(candidate);\n index.set(key, arr);\n}\n","/**\n * Repository operations — clone, pull, scan, resolve, link.\n *\n * Remote repos are cloned to a shared global cache (~/.skaile/cache/sources/<name>/).\n * Projects reference the cache via symlinks at .skaile/cache/sources/<name>/.\n * Local repos (path:) are used directly. Linked repos override remote URLs.\n *\n * Supports partial clone + sparse checkout for large repos.\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport {\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n rmSync,\n symlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport semver from \"semver\";\nimport { parse, stringify } from \"yaml\";\nimport {\n globalCacheRoot,\n globalSkaileDir,\n mergeLegacyEntriesInto,\n mergeLegacyEntriesKeyed,\n} from \"./cache-paths.js\";\nimport { type ScanOptions, scanDirectory } from \"./manifest.js\";\nimport type { AssetRef, CatalogEntry } from \"./models.js\";\nimport { assetRefToStr, parseAssetRef } from \"./models.js\";\nimport { readPluginGroupings } from \"./plugin-groupings.js\";\nimport { SKAILE_MANIFEST_FILENAME } from \"./publish-manifest.js\";\nimport { normalizeGithubOrg, type ProvenanceCandidate, type ProvenanceIndex } from \"./walker.js\";\nimport type { OverrideEntry, SourceDeclaration, StoreEntry } from \"./workspace-config.js\";\n\n// ── Global clone cache ───────────────────────────────────────────────────────\n\n/** True if `dir` is itself a git repo (has its own `.git`). */\nfunction hasOwnGit(dir: string): boolean {\n return existsSync(join(dir, \".git\"));\n}\n\n/**\n * The global source-clone cache: `<cacheRoot>/sources` (override the root with\n * `SKAILE_CACHE_DIR`). On first call it migrates both legacy clone roots into it:\n * the whole of `~/.skaile/repos/*`, and the own-`.git` (clone) entries of\n * `~/.skaile/sources/*`. The non-clone remainder of `~/.skaile/sources` is the\n * sidecar repo and is migrated separately by `getSidecarRoot()`.\n * @docLink packages/core/api-reference#get-global-cache-dir\n */\nexport function getGlobalCacheDir(): string {\n const dir = join(globalCacheRoot(), \"sources\");\n // Legacy roots are anchored at SKAILE_HOME, not the cache root — do not derive\n // them from globalCacheRoot() (SKAILE_CACHE_DIR may point elsewhere).\n const home = globalSkaileDir();\n mergeLegacyEntriesInto(dir, join(home, \"repos\"), () => true);\n // Legacy `~/.skaile/sources/<bare-name>` clones were keyed by the bare repo\n // name, so a URL-keyed lookup (`<host>/<owner>/<repo>`) missed them and they\n // lingered mis-placed. Re-derive each clone's true key from its `origin`\n // remote and land it at the URL-keyed path; a clone with no readable origin\n // (or a non-GitHub URL) falls back to its bare name.\n mergeLegacyEntriesKeyed(dir, join(home, \"sources\"), hasOwnGit, (from) => {\n const origin = getRepoRemoteUrl(from);\n return origin ? sourceCacheKey(origin) : null;\n });\n return dir;\n}\n\n// ── Clone-cache key ──────────────────────────────────────────────────────────\n\n/**\n * Canonical clone-cache key for a source git URL: `<host>/<owner>/<repo>`\n * (lowercased host; `.git` suffix, trailing slash, and protocol/scp prefix\n * stripped). This is the SSOT for the clone-cache path under\n * `getGlobalCacheDir()` — every writer and reader of that cache MUST derive its\n * key here.\n *\n * It exists because the old \"last path segment\" slug collided: both\n * `github.com/orgA/ai-assets` and `github.com/orgB/ai-assets` mapped to\n * `ai-assets`, so the wrong repo was served from cache silently. Keying by the\n * full `<host>/<owner>/<repo>` triple makes that collision impossible.\n *\n * Any URL that is not `<host>/<owner>/<repo>` shaped (local paths, `file://`,\n * a GitLab subgroup, exotic hosts) is keyed `<last segment>-<8 hex chars of the\n * sha256 of the normalized url>`. The bare last segment collided too:\n * `file:///a/other/local-skills.git` reused the clone of\n * `file:///b/remotes/local-skills.git`. `<host>/<owner>/<repo>` keys are\n * unchanged, so existing clones keep working.\n *\n * Userinfo is dropped, so `https://x-access-token:<token>@host/o/r` keys the\n * same clone as the plain url — and the token never becomes a directory name\n * or leaks through a message that names the key (`install` reports failures as\n * `source:<key> (…)`).\n *\n * @docLink packages/core/api-reference#source-cache-key\n */\nexport function sourceCacheKey(url: string): string {\n const normalized = normalizeSourceKeyUrl(url);\n const m = /^([^/]+)\\/([^/]+)\\/([^/]+)$/.exec(normalized);\n if (m) {\n const [, host, owner, repo] = m;\n return `${host.toLowerCase()}/${owner}/${repo}`;\n }\n // Hash the NORMALIZED url (userinfo already stripped), never the raw one —\n // else a token would shape the key.\n const hash = createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 8);\n return `${lastSegment(normalized)}-${hash}`;\n}\n\n/**\n * The clone-cache key an older release used for `url` — just the last path\n * segment — or `undefined` when it is the key {@link sourceCacheKey} still\n * produces (`<host>/<owner>/<repo>` urls never changed). Lets `source sync`\n * recognise the library row that points at a clone made under the old key.\n */\nexport function legacySourceCacheKey(url: string): string | undefined {\n const legacy = lastSegment(normalizeSourceKeyUrl(url));\n return legacy === sourceCacheKey(url) ? undefined : legacy;\n}\n\n/** Scheme, scp prefix, userinfo, `.git` suffix and trailing slashes stripped. */\nfunction normalizeSourceKeyUrl(url: string): string {\n return url\n .trim()\n .replace(/^git@([^:]+):/, \"$1/\") // git@host:owner/repo → host/owner/repo\n .replace(/^[a-z][a-z0-9+.-]*:\\/\\//i, \"\") // drop scheme (https://, ssh://, file://, …)\n .replace(/^[^/]*@/, \"\") // drop userinfo (user:token@) — never key on a secret\n .replace(/\\.git$/i, \"\")\n .replace(/\\/+$/, \"\");\n}\n\nfunction lastSegment(url: string): string {\n return (\n url\n .replace(/\\.git$/i, \"\")\n .replace(/\\/+$/, \"\")\n .split(/[/:]/)\n .pop() || \"source\"\n );\n}\n\n/**\n * Short repo name (`<repo>`) of a raw source URL (or a `<host>/<owner>/<repo>`\n * key). Used where a single human-facing label or library name is wanted. It\n * is the bare last segment, NOT the hash-suffixed key {@link sourceCacheKey}\n * gives a non-`<host>/<owner>/<repo>` URL.\n */\nexport function sourceShortName(urlOrCacheKey: string): string {\n return lastSegment(normalizeSourceKeyUrl(urlOrCacheKey));\n}\n\n/**\n * Collision-free, filesystem-safe flat slug for a source URL — the basename of\n * its curated store manifest (`~/.skaile/store/manifests/<slug>.yaml`). Derived\n * from the full {@link sourceCacheKey} (`<host>/<owner>/<repo>`) with path\n * separators encoded, so `orgA/cli` and `orgB/cli` never collide on the trailing\n * repo name (which {@link sourceShortName} would). Keyed identically by the\n * `init` writer, the `source add`/`sync` overlay reader, and the resolver.\n */\nexport function storeManifestSlug(url: string): string {\n return sourceCacheKey(url).replace(/[/\\\\:]+/g, \"__\");\n}\n\n// ── Git operations ───────────────────────────────────────────────────────────\n\n/**\n * Shared env for all git subprocess spawns.\n * GIT_TERMINAL_PROMPT=0 prevents git from opening /dev/tty to ask for\n * credentials when running inside a CLI spinner (which holds the terminal in\n * raw mode). Without this, git bypasses stdio: \"pipe\" and the process hangs\n * indefinitely waiting for input that can never arrive.\n */\nconst GIT_ENV = { ...process.env, GIT_TERMINAL_PROMPT: \"0\" };\n\n/**\n * Clone a remote git repository using partial clone (treeless) with sparse checkout.\n * Falls back to a regular shallow clone if the server does not support partial clones.\n *\n * @param url - Remote git URL\n * @param branch - Branch to clone\n * @param dest - Local destination directory\n * @returns `true` on success, `false` on failure\n * @docLink packages/core/api-reference#clone-repo\n */\nexport function cloneRepo(url: string, branch: string, dest: string): boolean {\n mkdirSync(dest, { recursive: true });\n // Try partial clone first (requires git 2.25+ and server support)\n const r = spawnSync(\n \"git\",\n [\"clone\", \"--depth=1\", \"--filter=blob:none\", \"--sparse\", \"--branch\", branch, url, dest],\n { stdio: \"pipe\", env: GIT_ENV },\n );\n if (r.status === 0) {\n // Enable cone mode for sparse checkout\n spawnSync(\"git\", [\"-C\", dest, \"sparse-checkout\", \"init\", \"--cone\"], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n // Check out everything initially (for discovery)\n spawnSync(\"git\", [\"-C\", dest, \"sparse-checkout\", \"disable\"], { stdio: \"pipe\", env: GIT_ENV });\n return true;\n }\n // Fallback: regular shallow clone\n const fallback = spawnSync(\"git\", [\"clone\", \"--depth=1\", \"--branch\", branch, url, dest], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n return fallback.status === 0;\n}\n\n/**\n * Blank out every `userinfo@host` in a message (`https://user:token@host/…` and\n * the scheme-less `user:token@host/…` that {@link sourceCacheKey} bakes into a\n * cache path). Git echoes the configured remote verbatim in transport errors,\n * and a credentialed source url also keys its clone directory, so the git\n * message and the path both carry the token. Redacting a secret-free `git@host`\n * too costs readability; missing one token costs a credential.\n */\nfunction redactCredentials(text: string): string {\n return text.replace(/[^/\\s@]+@/g, \"***@\");\n}\n\n/** Readable one-line reason for a failed git spawn (stderr, else exit status). */\nfunction gitFailure(r: ReturnType<typeof spawnSync>): string {\n const stderr = r.stderr ? String(r.stderr).trim() : \"\";\n if (stderr) return redactCredentials(stderr.split(\"\\n\").slice(-2).join(\" \").trim());\n if (r.error) return redactCredentials(r.error.message);\n return `git exited with status ${r.status}`;\n}\n\n/** Result of {@link pullRepoResult}: success flag plus git's reason on failure. */\nexport interface PullResult {\n ok: boolean;\n error?: string;\n}\n\n/**\n * Pull the latest commits for a cloned repository, reporting git's own failure\n * reason. Same strategy as {@link pullRepo} — of which this is the detailed\n * form — so callers can surface *why* a refresh failed instead of swallowing it.\n *\n * @param dest - Local repo directory\n * @param branch - Branch to pull\n * @returns `{ ok: true }`, or `{ ok: false, error }` carrying the git message\n * @docLink packages/core/api-reference#pull-repo-result\n */\nexport function pullRepoResult(dest: string, branch: string): PullResult {\n // A detached HEAD (left by a pin checkout) cannot pull — re-attach first.\n attachToBranch(dest, branch);\n // Local commits the remote lacks are the user's work: the force-sync below would drop\n // them. Refuse, with the message `git pull --ff-only` gives for a diverged clone.\n // Measured against the last fetched `origin/<branch>`, so a shallow clone that is only\n // behind (or whose upstream history was rewritten) still counts as having none.\n const ahead = spawnSync(\"git\", [\"-C\", dest, \"rev-list\", \"--count\", `origin/${branch}..HEAD`], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (ahead.status === 0 && Number(ahead.stdout.trim()) > 0) {\n return { ok: false, error: \"Not possible to fast-forward, aborting.\" };\n }\n const pull = spawnSync(\"git\", [\"-C\", dest, \"pull\", \"--depth=1\", \"--ff-only\"], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (pull.status === 0) return { ok: true };\n // Shallow clones can diverge upstream — force-sync via fetch + reset\n const fetch = spawnSync(\"git\", [\"-C\", dest, \"fetch\", \"--depth=1\", \"origin\", branch], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (fetch.status !== 0) return { ok: false, error: gitFailure(fetch) };\n const reset = spawnSync(\"git\", [\"-C\", dest, \"reset\", \"--hard\", `origin/${branch}`], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n return reset.status === 0 ? { ok: true } : { ok: false, error: gitFailure(reset) };\n}\n\n/**\n * Pull the latest commits for a cloned repository.\n * On shallow clone divergence, falls back to `git fetch --depth=1` + `git reset --hard`.\n *\n * @param dest - Local repo directory\n * @param branch - Branch to pull\n * @returns `true` on success, `false` on failure\n * @docLink packages/core/api-reference#pull-repo\n */\nexport function pullRepo(dest: string, branch: string): boolean {\n return pullRepoResult(dest, branch).ok;\n}\n\n/**\n * Return the current HEAD commit SHA for a local repository.\n *\n * @param repoDir - Absolute path to the cloned repository\n * @returns Full commit SHA string, or `null` on failure\n * @docLink packages/core/api-reference#get-repo-commit\n */\nexport function getRepoCommit(repoDir: string): string | null {\n const r = spawnSync(\"git\", [\"-C\", repoDir, \"rev-parse\", \"HEAD\"], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n return r.status === 0 ? r.stdout.trim() : null;\n}\n\n/**\n * Whether `commit` is a boundary of a shallow clone: a commit `git fetch --depth` brought from\n * the remote (a pin, or the tip at clone time), never one made in the clone. Its history is cut\n * there, so `branch -r --contains` cannot see it on a remote branch once the remote moved on.\n */\nfunction isShallowBoundary(repoDir: string, commit: string): boolean {\n const full = spawnSync(\"git\", [\"-C\", repoDir, \"rev-parse\", \"--verify\", `${commit}^{commit}`], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n const sha = full.stdout.trim();\n if (full.status !== 0 || !sha) return false;\n const file = spawnSync(\"git\", [\"-C\", repoDir, \"rev-parse\", \"--git-path\", \"shallow\"], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (file.status !== 0) return false;\n const shallowPath = resolve(repoDir, file.stdout.trim());\n try {\n return readFileSync(shallowPath, \"utf8\").split(\"\\n\").includes(sha);\n } catch {\n return false;\n }\n}\n\n/**\n * Whether `commit` is reachable from a remote-tracking branch of the clone at `repoDir` — i.e.\n * whether another machine that clones the remote can check it out. `false` for a commit made in\n * the clone and never pushed. `true` when the answer is unknowable (not a git checkout of its\n * own, no `origin`, an unknown object): a lock must not be refused on a guess.\n *\n * @param repoDir - Absolute path to the clone\n * @param commit - Full or abbreviated commit SHA\n */\nexport function isCommitOnRemote(repoDir: string, commit: string): boolean {\n if (!/^[0-9a-f]{7,64}$/i.test(commit) || !hasOwnGit(repoDir)) return true;\n if (!getRepoRemoteUrl(repoDir)) return true;\n const known = spawnSync(\"git\", [\"-C\", repoDir, \"cat-file\", \"-e\", `${commit}^{commit}`], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (known.status !== 0) return true;\n if (isShallowBoundary(repoDir, commit)) return true;\n const r = spawnSync(\"git\", [\"-C\", repoDir, \"branch\", \"-r\", \"--contains\", commit], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n return r.status !== 0 || r.stdout.trim().length > 0;\n}\n\n/**\n * Check out a specific tag, branch, or commit SHA in a local repository.\n * Fetches the ref from `origin` first, then attempts `FETCH_HEAD` checkout.\n *\n * @param repoDir - Absolute path to the cloned repository\n * @param pin - Tag, branch name, or commit SHA\n * @returns `true` on success, `false` on failure\n * @docLink packages/core/api-reference#checkout-pin\n */\nexport function checkoutPin(repoDir: string, pin: string): boolean {\n // Fetch the ref first (works for tags, branches, and commits). A failed fetch leaves\n // `FETCH_HEAD` at whatever an earlier fetch wrote: checking that out would \"pin\" another commit.\n const fetched = spawnSync(\"git\", [\"-C\", repoDir, \"fetch\", \"--depth=1\", \"origin\", pin], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n const r =\n fetched.status === 0\n ? spawnSync(\"git\", [\"-C\", repoDir, \"checkout\", \"FETCH_HEAD\"], { stdio: \"pipe\", env: GIT_ENV })\n : undefined;\n // Fallback: try direct checkout (for branches already fetched)\n const ok =\n r?.status === 0 ||\n spawnSync(\"git\", [\"-C\", repoDir, \"checkout\", pin], { stdio: \"pipe\", env: GIT_ENV }).status ===\n 0;\n if (!ok) return false;\n // A commit pin names exactly one commit: anything else checked out is not the pin.\n if (/^[0-9a-f]{7,40}$/i.test(pin)) {\n return getRepoCommit(repoDir)?.toLowerCase().startsWith(pin.toLowerCase()) === true;\n }\n return true;\n}\n\n/** The branch HEAD is on, or `null` when HEAD is detached. */\nfunction currentBranch(repoDir: string): string | null {\n const r = spawnSync(\"git\", [\"-C\", repoDir, \"symbolic-ref\", \"--short\", \"-q\", \"HEAD\"], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n return r.status === 0 ? r.stdout.trim() || null : null;\n}\n\n/**\n * Put a clone whose HEAD is detached back on a branch. {@link checkoutPin}\n * (`install --locked`, `add`) leaves the shared clone detached at the locked\n * commit, and `git pull` refuses to run there. With `preferred`, only that\n * branch is tried (a tag or SHA pin stays detached); without it, the branch\n * `origin/HEAD` names, then `main` and `master`. A no-op on a clone that is\n * already on a branch.\n *\n * @returns `true` when the clone is on a branch afterwards\n * @docLink packages/core/api-reference#attach-to-branch\n */\nexport function attachToBranch(repoDir: string, preferred?: string): boolean {\n if (currentBranch(repoDir)) return true;\n let candidates = [preferred];\n if (!preferred) {\n const originHead = spawnSync(\n \"git\",\n [\"-C\", repoDir, \"symbolic-ref\", \"--short\", \"-q\", \"refs/remotes/origin/HEAD\"],\n { encoding: \"utf8\", stdio: \"pipe\" },\n );\n const tracked =\n originHead.status === 0 ? originHead.stdout.trim().replace(/^origin\\//, \"\") : \"\";\n candidates = [tracked, \"main\", \"master\"];\n }\n for (const candidate of candidates) {\n if (!candidate) continue;\n spawnSync(\"git\", [\"-C\", repoDir, \"checkout\", \"-q\", candidate], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (currentBranch(repoDir)) return true;\n }\n return false;\n}\n\n/**\n * Read a clone's configured `origin` URL, or `null` when it is absent / not a\n * repo. Reads `remote.origin.url` as written, NOT `git remote get-url`, which\n * applies `url.<base>.insteadOf` rewrites: with `insteadOf` set for the\n * declared url, the rewritten path would map to another cache key and the\n * clone would read as a stale collision.\n */\nfunction getRepoRemoteUrl(repoDir: string): string | null {\n const r = spawnSync(\"git\", [\"-C\", repoDir, \"config\", \"--get\", \"remote.origin.url\"], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n return r.status === 0 ? r.stdout.trim() : null;\n}\n\n/** True when the clone's origin maps to the same cache key as the declared URL. */\nfunction remoteUrlMatches(repoDir: string, expectedUrl: string): boolean {\n // Only a dir that is its OWN git root can be verified. A local source path that\n // is NOT a standalone clone (e.g. the in-repo factory-assets tree) would make\n // `git -C` report the ENCLOSING repo's remote, falsely \"mismatch\", and get\n // wiped. Treat \"not its own clone\" as a match so it is never destroyed.\n if (!hasOwnGit(repoDir)) return true;\n const actual = getRepoRemoteUrl(repoDir);\n if (!actual) return true; // no remote info → don't destroy; assume ok\n return sourceCacheKey(actual) === sourceCacheKey(expectedUrl);\n}\n\n// ── Link management ──────────────────────────────────────────────────────────\n\n/**\n * Map of repo name → local filesystem path for development overrides.\n * Stored in `.skaile/links.yaml`; used to redirect a named repo to a local clone.\n * @docLink packages/core/api-reference#link-config\n */\nexport interface LinkConfig {\n [repoName: string]: string; // repo name → local path\n}\n\n/** Path to the project-local links file. */\nfunction linksFile(projectDir: string): string {\n return join(projectDir, \".skaile\", \"links.yaml\");\n}\n\n/**\n * Read the dev-link map from `.skaile/links.yaml` in the project directory.\n * Returns an empty object when no links file exists.\n *\n * @param projectDir - Absolute path to the project root\n * @returns `LinkConfig` map (may be empty)\n * @docLink packages/core/api-reference#read-links\n */\nexport function readLinks(projectDir: string): LinkConfig {\n const file = linksFile(projectDir);\n if (!existsSync(file)) return {};\n try {\n return (parse(readFileSync(file, \"utf8\")) as LinkConfig) ?? {};\n } catch {\n return {};\n }\n}\n\n/**\n * Persist the dev-link map to `.skaile/links.yaml` in the project directory.\n *\n * @param projectDir - Absolute path to the project root\n * @param links - Updated `LinkConfig` to write\n * @docLink packages/core/api-reference#write-links\n */\nexport function writeLinks(projectDir: string, links: LinkConfig): void {\n const dir = join(projectDir, \".skaile\");\n mkdirSync(dir, { recursive: true });\n writeFileSync(linksFile(projectDir), stringify(links));\n}\n\n/**\n * Register a local filesystem path as a dev override for a named repository.\n * The path is stored in `.skaile/links.yaml` and takes priority over the remote URL at runtime.\n *\n * @param projectDir - Absolute path to the project root\n * @param repoName - Name of the repository to override\n * @param localPath - Local path (absolute or relative to `projectDir`) to use instead\n * @throws When the resolved path does not exist\n * @docLink packages/core/api-reference#link-repo\n */\nexport function linkRepo(projectDir: string, repoName: string, localPath: string): void {\n const resolved = resolve(projectDir, localPath);\n if (!existsSync(resolved)) {\n throw new Error(`Path not found: ${localPath} (resolved: ${resolved})`);\n }\n const links = readLinks(projectDir);\n links[repoName] = resolved;\n writeLinks(projectDir, links);\n}\n\n/**\n * Remove the dev-link override for a named repository, reverting it to the remote URL.\n *\n * @param projectDir - Absolute path to the project root\n * @param repoName - Name of the repository to unlink\n * @returns `true` if the link existed and was removed, `false` if no link was found\n * @docLink packages/core/api-reference#unlink-repo\n */\nexport function unlinkRepo(projectDir: string, repoName: string): boolean {\n const links = readLinks(projectDir);\n if (!links[repoName]) return false;\n delete links[repoName];\n writeLinks(projectDir, links);\n return true;\n}\n\n// ── Repo lifecycle ───────────────────────────────────────────────────────────\n\n/**\n * Ensure a repository is available locally, cloning or symlinking as needed.\n *\n * Resolution order:\n * 1. Linked override (`.skaile/links.yaml`) — highest priority\n * 2. Local path (`decl.path`) — direct filesystem reference; a bare path must\n * already exist, but a url-backed managed cache dir is cloned in-place on miss\n * 3. Remote URL (`decl.url`) — cloned to the shared global cache, symlinked into `.skaile/cache/sources/`\n *\n * Freshness: a **managed cache clone** (a url-backed dir under\n * {@link getGlobalCacheDir}) is refreshed on every call when no pin is given —\n * both for a bare `url:` declaration and for the `path:`-into-the-cache form\n * that `AssetManager` builds from `sources:`, so `install` never serves a stale\n * source. A failed refresh warns and keeps the cached commit. A user-owned\n * checkout (bare `path:`, dev link, factory tree) is never touched.\n *\n * Pin support: when `opts.pin` is provided, the tag/commit is checked out and\n * the clone is never pulled.\n *\n * @param decl - Repository declaration from `skaile.yaml`\n * @param name - Logical repository name (cache key)\n * @param reposDir - Project-local source-clone directory (`.skaile/cache/sources/`)\n * @param opts - Optional: `pin` for a specific commit/tag, `projectDir` for link lookup\n * @returns Absolute path to the local repository directory\n * @throws When the repository cannot be resolved or cloned\n * @docLink packages/core/api-reference#ensure-repo\n */\nexport function ensureRepo(\n decl: SourceDeclaration,\n name: string,\n reposDir: string,\n opts?: { pin?: string; projectDir?: string; strictPin?: boolean },\n): string {\n // 1. Check for linked override\n const linked = resolveLinkedOverride(name, opts?.projectDir);\n if (linked) return linked;\n\n // 2. Local path (or managed cache dir for a remote source)\n if (decl.path) {\n return ensureLocalPathRepo(decl, reposDir, opts);\n }\n\n // 3. Remote URL — clone to shared global cache\n if (decl.url) {\n return ensureRemoteRepo(decl, name, reposDir, opts);\n }\n\n throw new Error(`Repository \"${name}\" has neither url nor path`);\n}\n\n/**\n * Step 1 of {@link ensureRepo}: resolve a dev-link override for `name`, if one\n * exists. Returns the linked path (validated to exist) or `null` when no link\n * is configured.\n */\nfunction resolveLinkedOverride(name: string, projectDir?: string): string | null {\n if (!projectDir) return null;\n const links = readLinks(projectDir);\n const linked = links[name];\n if (!linked) return null;\n if (!existsSync(linked)) {\n throw new Error(\n `Linked path not found: ${linked}. Remove the .skaile/links.yaml entry to clear it.`,\n );\n }\n return linked;\n}\n\n/**\n * True when `dir` lives inside the global clone cache — i.e. it is a clone\n * skaile itself created and may therefore refresh. A user's own checkout\n * (a bare `path:` source, a dev link, the in-package factory tree) never is,\n * and must never be pulled or reset under them.\n */\nfunction isManagedCacheDir(dir: string): boolean {\n const root = resolve(getGlobalCacheDir());\n const target = resolve(dir);\n return target === root || target.startsWith(root + sep);\n}\n\n/** Warnings already printed in this process, so a source clone is reported once per cause. */\nconst warnedSourceClones = new Set<string>();\n\n/**\n * One user-facing line for a source clone that could not be brought to where its declaration\n * says: `! source clone <name> <what>`. No logger tag and no absolute path (the clone dir is a\n * cache path keyed off the url, so it can carry a token: the line is redacted too).\n */\nfunction warnSourceClone(url: string, dest: string, what: string): void {\n const line = redactCredentials(`! source clone ${sourceShortName(url)} ${what}`);\n if (warnedSourceClones.has(`${dest}\\n${line}`)) return;\n warnedSourceClones.add(`${dest}\\n${line}`);\n console.warn(line);\n}\n\n/**\n * THE one place that brings a managed cache clone to the commit it should be on.\n * Clone on miss (or on a stale flat-slug collision), pull on an unpinned hit,\n * check out the pin when one is given. Both `ensureRepo` routes — a `path:`\n * declaration pointing into the cache and a bare `url:` one — go through here,\n * so \"refresh a managed clone\" has a single definition.\n *\n * A failed refresh is warned, not thrown: an unreachable network must not fail\n * an install that the existing clone can still serve.\n */\nfunction syncManagedClone(\n dest: string,\n url: string,\n branch: string,\n pin?: string,\n strictPin = false,\n): void {\n const cached = existsSync(join(dest, \".git\"));\n if (cached && remoteUrlMatches(dest, url)) {\n // The declaration is authoritative for credentials: the key ignores\n // userinfo, so a clone made with a since-rotated token still matches and\n // would keep fetching with the revoked one.\n spawnSync(\"git\", [\"-C\", dest, \"remote\", \"set-url\", \"origin\", url], {\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n // An unpinned source tracks its branch — refresh on every call, else the\n // clone is served forever at whatever commit it was first cloned at.\n if (!pin) {\n const { ok, error } = pullRepoResult(dest, branch);\n if (!ok) {\n // `dest` is a cache path keyed off the url, so it carries the token too when the\n // source url does; `warnSourceClone` redacts the assembled line.\n warnSourceClone(\n url,\n dest,\n `not refreshed: ${(error ?? \"\").replace(/\\.+$/, \"\")}; using the cached commit`,\n );\n }\n }\n } else {\n if (cached) rmSync(dest, { recursive: true, force: true });\n mkdirSync(dirname(dest), { recursive: true });\n if (!cloneRepo(url, branch, dest)) {\n // The url is reported back to the user (install lists it under `missing`),\n // so strip any token it carries before it reaches a build log.\n throw new Error(redactCredentials(`Failed to clone ${url} (branch: ${branch}) into ${dest}`));\n }\n }\n // A SHA pin already checked out needs no git at all — that keeps a fully\n // pinned project offline after its first clone, which is much of the point.\n if (pin && getRepoCommit(dest) === pin) return;\n if (pin && !checkoutPin(dest, pin)) {\n // A lock restore must not deploy another commit's bytes under the pinned one's name.\n if (strictPin) {\n throw new Error(\n redactCredentials(\n `could not check out pin ${pin} in source clone ${dest}: the commit is not on the remote (an unpublished commit, or a rewritten branch)`,\n ),\n );\n }\n warnSourceClone(url, dest, `not on its pin ${pin}; using the cached commit`);\n }\n}\n\n/**\n * Step 2 of {@link ensureRepo}: resolve a `decl.path` source. A bare local path\n * must already exist; a url-backed managed cache dir is ours to populate, so it\n * is cloned in-place on first miss and kept in sync on every later call.\n */\nfunction ensureLocalPathRepo(\n decl: SourceDeclaration,\n reposDir: string,\n opts?: { pin?: string; projectDir?: string; strictPin?: boolean },\n): string {\n const projectDir = opts?.projectDir ?? resolve(reposDir, \"..\");\n const resolved = resolve(projectDir, decl.path as string);\n // A managed cache dir whose origin maps to a different key than `decl.url` is a\n // stale flat-slug collision — wipe and re-clone so the wrong repo is never used.\n const exists = existsSync(resolved);\n if (exists && (!decl.url || remoteUrlMatches(resolved, decl.url))) {\n // Only a clone we own may be moved; a user's checkout is read as-is.\n if (decl.url && !decl.factory && hasOwnGit(resolved) && isManagedCacheDir(resolved)) {\n syncManagedClone(resolved, decl.url, decl.branch ?? \"main\", opts?.pin, opts?.strictPin);\n }\n return resolved;\n }\n if (!decl.url) {\n throw new Error(`Local repository path not found: ${decl.path} (resolved: ${resolved})`);\n }\n // Miss, or a stale flat-slug collision (origin maps to a different key) — the\n // shared helper wipes and re-clones so the wrong repo is never used.\n syncManagedClone(resolved, decl.url, decl.branch ?? \"main\", opts?.pin, opts?.strictPin);\n return resolved;\n}\n\n/**\n * Step 3 of {@link ensureRepo}: clone/pull a remote `decl.url` source into the\n * shared global cache, checkout any pin, then symlink it into the project-local\n * `.skaile/cache/sources/`. Returns the global cache path.\n */\nfunction ensureRemoteRepo(\n decl: SourceDeclaration,\n name: string,\n reposDir: string,\n opts?: { pin?: string; projectDir?: string; strictPin?: boolean },\n): string {\n const cacheDest = join(getGlobalCacheDir(), name);\n syncManagedClone(\n cacheDest,\n decl.url as string,\n decl.branch ?? \"main\",\n opts?.pin,\n opts?.strictPin,\n );\n linkCacheIntoProject(cacheDest, reposDir, name);\n return cacheDest;\n}\n\n/**\n * Create (or repair) the project-local `.skaile/cache/sources/<name>` symlink pointing\n * at the global cache. A stale real directory (legacy clone) is replaced. All\n * symlink failures are swallowed — callers fall back to the cache dir directly.\n */\nfunction linkCacheIntoProject(cacheDest: string, reposDir: string, name: string): void {\n const projectDest = join(reposDir, name);\n const projectExists = existsSync(projectDest);\n const isSymlink = projectExists && lstatSync(projectDest).isSymbolicLink();\n\n if (!projectExists) {\n mkdirSync(reposDir, { recursive: true });\n try {\n symlinkSync(cacheDest, projectDest);\n } catch {\n // Symlink failed (Windows?), just use cache dir directly\n }\n } else if (!isSymlink) {\n // Stale real directory (legacy clone) — replace with symlink to global cache\n rmSync(projectDest, { recursive: true });\n try {\n symlinkSync(cacheDest, projectDest);\n } catch {\n // Symlink failed, fall through to return cacheDest\n }\n }\n}\n\n// ── Scanning ─────────────────────────────────────────────────────────────────\n\n/**\n * Derive the `\"<org>/<repo>\"` slug from a directory's git `origin` remote.\n * Returns `undefined` when `rootDir` is not a git repo, has no `origin` remote,\n * or the URL is not a parseable GitHub repo. Mirrors the store's\n * `repoSlugFromSourceUrl` so local and remote feeds key the grouping tree\n * identically.\n *\n * @param rootDir - Absolute path to the scanned repository root\n * @returns `\"<org>/<repo>\"` or `undefined`\n * @docLink packages/core/api-reference#repo-slug-from-git-remote\n */\nfunction repoSlugFromGitRemote(rootDir: string): string | undefined {\n const r = spawnSync(\"git\", [\"-C\", rootDir, \"config\", \"--get\", \"remote.origin.url\"], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (r.status !== 0) return undefined;\n const m = /github\\.com[/:]([^/]+)\\/([^/]+?)(?:\\.git)?\\/?$/.exec(r.stdout.trim());\n return m ? `${m[1]}/${m[2]}` : undefined;\n}\n\n/**\n * Resolve a scanned source's canonical publisher: the declared `publisher` in\n * the root `skaile.manifest.yaml`, else the GitHub org from the `origin` remote.\n * Returns `undefined` when neither is available, so callers can fall back to the\n * repo config key.\n *\n * Single source of truth shared by the source/library scanner (`scanRepo`) and\n * the index/discovery side (`LocalCatalogSource.sync`) so both key an asset\n * identically. The org fallback is lowercased to its GitHub-shaped slug\n * (GitHub orgs are case-insensitive — a cased remote like `Acme` must not split\n * from the lowercase index ref). A declared manifest publisher has its single\n * leading `@` (the scope sigil, added automatically by the ref formatter)\n * stripped so the scan/display refs match the decode path — `@acme` would\n * otherwise render as `@@acme` and be un-addable.\n *\n * @param repoDir - Absolute path to the scanned repository root\n * @param declared - Publisher recorded with `skaile source add --publisher`: used when the\n * manifest declares none, before the GitHub-org fallback\n * @returns The publisher slug (no `@` sigil) or `undefined`\n * @docLink packages/core/api-reference#resolve-source-publisher\n */\nexport function resolveSourcePublisher(repoDir: string, declared?: string): string | undefined {\n const manifestPath = join(repoDir, SKAILE_MANIFEST_FILENAME);\n if (existsSync(manifestPath)) {\n try {\n const raw = parse(readFileSync(manifestPath, \"utf8\")) as Record<string, unknown> | null;\n if (raw && typeof raw.publisher === \"string\" && raw.publisher.length > 0)\n return raw.publisher.startsWith(\"@\") ? raw.publisher.slice(1) : raw.publisher;\n } catch {}\n }\n if (declared) return declared.startsWith(\"@\") ? declared.slice(1) : declared;\n const org = repoSlugFromGitRemote(repoDir)?.split(\"/\")[0];\n return org ? normalizeGithubOrg(org) : undefined;\n}\n\n/**\n * Scan a repository directory and return all discovered asset catalog entries.\n * Delegates to `scanDirectory` from `manifest.ts`, then stamps the `repo` slug\n * derived once from the root's git remote onto every entry (the GitHub\n * coordinate is a property of the scanned root, not of individual assets).\n *\n * The `publisher` field is overridden with the source's declared canonical\n * publisher (`skaile.yaml` `publisher` / GitHub org) so refs emitted from\n * filename-convention scans match the provenance index `resolveAll` builds.\n * Without this, a source whose declared publisher differs from its config slug\n * yields refs (`name@<slug>`) that resolution can't find (`name@<publisher>`).\n *\n * @param repoDir - Absolute path to the repository root\n * @param repoName - Repository config key; fallback publisher and `repository` field\n * @param options - Walk bounds plus the registered `knownKinds` typed frontmatter is checked against;\n * `declaredPublisher` is the source's `skaile source add --publisher` value\n * @returns Array of `CatalogEntry` objects found in the repository\n * @docLink packages/core/api-reference#scan-repo\n */\nexport async function scanRepo(\n repoDir: string,\n repoName: string,\n options: ScanOptions & { declaredPublisher?: string },\n): Promise<CatalogEntry[]> {\n const repo = repoSlugFromGitRemote(repoDir);\n const publisher = resolveSourcePublisher(repoDir, options.declaredPublisher) ?? repoName;\n const groupings = readPluginGroupings(repoDir);\n return (await scanDirectory(repoDir, repoName, options)).map((e) => {\n const plugin = groupings.get(relative(repoDir, dirname(e.source)).split(sep).join(\"/\"));\n return {\n ...e,\n publisher,\n ...(repo ? { repo } : {}),\n ...(plugin ? { plugin } : {}),\n };\n });\n}\n\n// ── Resolution ───────────────────────────────────────────────────────────────\n\n/**\n * Resolve a single asset reference to its `CatalogEntry` by scanning declared repositories.\n *\n * Search order:\n * 1. Explicit `@repository` qualifier on the ref — only that repo is searched.\n * 2. `opts.preferRepo` — searched first when set (repo affinity for transitive deps).\n * 3. All declared repos in declaration order.\n *\n * @param ref - Parsed asset reference to resolve\n * @param repositories - Repository declarations from `skaile.yaml`\n * @param reposDir - Project-local source-clone directory (`.skaile/cache/sources/`)\n * @param opts - Optional: `projectDir` for link lookup, `preferRepo` for affinity\n * @returns Matching `CatalogEntry`, or `null` if not found in any repository\n * @docLink packages/core/api-reference#resolve-asset\n */\nexport async function resolveAsset(\n ref: AssetRef,\n repositories: Record<string, SourceDeclaration>,\n reposDir: string,\n opts: { knownKinds: ReadonlySet<string>; projectDir?: string; preferRepo?: string },\n): Promise<CatalogEntry | null> {\n let repoNames: string[];\n if (ref.publisher) {\n // Explicit @repo qualifier — only search that repo\n repoNames = [ref.publisher];\n } else if (opts.preferRepo && opts.preferRepo in repositories) {\n // Repo affinity from parent — search preferred repo first, then others\n const rest = Object.keys(repositories).filter((n) => n !== opts.preferRepo);\n repoNames = [opts.preferRepo, ...rest];\n } else {\n repoNames = Object.keys(repositories);\n }\n\n for (const repoName of repoNames) {\n const decl = repositories[repoName];\n if (!decl) continue;\n\n const repoDir = resolveRepoDir(decl, repoName, reposDir, opts.projectDir);\n if (!repoDir || !existsSync(repoDir)) continue;\n\n const entries = await scanRepo(repoDir, repoName, {\n knownKinds: opts.knownKinds,\n declaredPublisher: decl.publisher,\n });\n const match = entries.find((e) => e.kind === ref.kind && e.name === ref.name);\n if (match) return match;\n }\n\n return null;\n}\n\n/** Resolve repo dir without cloning (for lookups). Checks links first. */\nfunction resolveRepoDir(\n decl: SourceDeclaration,\n name: string,\n reposDir: string,\n projectDir?: string,\n): string | null {\n // Check links\n if (projectDir) {\n const links = readLinks(projectDir);\n if (links[name]) {\n return existsSync(links[name]) ? links[name] : null;\n }\n }\n\n if (decl.path) {\n const base = projectDir ?? resolve(reposDir, \"..\");\n const resolved = resolve(base, decl.path);\n return existsSync(resolved) ? resolved : null;\n }\n\n // Check project-local symlink or global cache. A global cache dir whose origin\n // maps to a different key than `decl.url` is a stale collision — skip it rather\n // than scan the wrong repo (re-clone happens on the next ensureRepo).\n const projectDest = join(reposDir, name);\n if (existsSync(projectDest)) return projectDest;\n\n const globalDest = join(getGlobalCacheDir(), name);\n if (existsSync(join(globalDest, \".git\"))) {\n if (decl.url && !remoteUrlMatches(globalDest, decl.url)) return null;\n return globalDest;\n }\n\n return null;\n}\n\n/**\n * Hard error raised when two or more candidates for the same canonical ref\n * `<publisher>/<kind>:<name>@<version>` disagree on their content sha256 and no\n * `overrides[]` entry resolves the conflict. The message walks the dep chain\n * back to the user-declared root.\n * @docLink packages/core/api-reference#canonical-ref-conflict-error\n */\nexport class CanonicalRefConflictError extends Error {\n constructor(\n public ref: string,\n public candidates: ProvenanceCandidate[],\n public depChain: string[],\n ) {\n super(\n [\n `error: divergent sha256 for ${ref}`,\n \"\",\n \" pulled in via:\",\n ...depChain.map((s, i) => ` ${\" \".repeat(i * 2)}${s}`),\n \"\",\n \" candidates:\",\n ...candidates.map(\n (c) => ` ${c.sourceUrl} @ ${c.commit.slice(0, 8)}\\n sha256: ${c.sha256}`,\n ),\n \"\",\n \"resolve by:\",\n \" 1. removing one source from skaile.yaml,\",\n \" 2. configuring a store and using its canonical digest, or\",\n \" 3. adding to overrides: (with a non-empty reason:)\",\n ].join(\"\\n\"),\n );\n this.name = \"CanonicalRefConflictError\";\n }\n}\n\n/** Deepest preset nesting a dependency expansion follows (the preset schema allows 3). */\nexport const MAX_PRESET_DEPTH = 3;\n\n/**\n * Raised (`code: \"preset_depth_exceeded\"`) when a `preset:` dependency nests deeper\n * than {@link MAX_PRESET_DEPTH} or lists itself, directly or through other presets.\n */\nexport class PresetDepthError extends Error {\n readonly code = \"preset_depth_exceeded\";\n constructor(\n readonly reason: \"depth\" | \"cycle\",\n readonly ref: string,\n readonly depChain: string[],\n ) {\n super(\n `preset_depth_exceeded: ${\n reason === \"cycle\"\n ? `preset ${ref} lists itself (cycle)`\n : `preset ${ref} nests deeper than ${MAX_PRESET_DEPTH} presets`\n } — via ${depChain.join(\" → \")}`,\n );\n this.name = \"PresetDepthError\";\n }\n}\n\n/** Kinds that no longer exist, mapped to the kind that replaced them. */\nconst REMOVED_KIND_REPLACEMENTS: Record<string, string> = { bundle: \"preset\", mount: \"connector\" };\n\n/**\n * Raised (`code: \"unknown_asset_kind\"`) when a dependency ref names a kind that is\n * not registered or was removed; names the replacement when there is one.\n */\nexport class UnknownAssetKindError extends Error {\n readonly code = \"unknown_asset_kind\";\n constructor(\n readonly kind: string,\n readonly ref: string,\n readonly replacement?: string,\n ) {\n super(\n replacement\n ? `unknown_asset_kind: asset kind \"${kind}\" (in \"${ref}\") no longer exists — use \\`${ref.replace(`${kind}:`, `${replacement}:`)}\\` (\\`${replacement}:\\`) instead`\n : `unknown_asset_kind: asset kind \"${kind}\" (in \"${ref}\") is not registered`,\n );\n this.name = \"UnknownAssetKindError\";\n }\n}\n\nfunction assertKnownKind(\n ref: AssetRef,\n refStr: string,\n knownKinds: ReadonlySet<string> | undefined,\n): void {\n const replacement = Object.hasOwn(REMOVED_KIND_REPLACEMENTS, ref.kind)\n ? REMOVED_KIND_REPLACEMENTS[ref.kind]\n : undefined;\n if (replacement !== undefined) throw new UnknownAssetKindError(ref.kind, refStr, replacement);\n if (knownKinds && !knownKinds.has(ref.kind)) throw new UnknownAssetKindError(ref.kind, refStr);\n}\n\n/**\n * Result of a full transitive dependency resolution via `resolveAll`.\n * @docLink packages/core/api-reference#resolve-result\n */\nexport interface ResolveResult {\n /** Resolved candidates in leaf-first order. Presets are expanded, never listed. */\n resolved: ProvenanceCandidate[];\n /** Refs that no source / store could provide. */\n missing: string[];\n /** \"<publisher>/<kind>:<name>\" → parent ref (\"direct\" if user-declared). */\n resolvedBy: Map<string, string>;\n /** Overrides that were applied (lock-side bookkeeping); canonical refs. */\n overridesApplied: Set<string>;\n /** One entry per preset expanded into the install set (nested presets included). */\n presets: PresetExpansion[];\n}\n\n/**\n * What expanding one `preset:` dependency contributed: `assets` direct asset items\n * (nested presets are listed as their own entry), `skipped` instance items\n * (`library://`, placeholder and connector/mcp items) left to `skaile preset apply`.\n */\nexport interface PresetExpansion {\n /** Canonical ref (`preset:@publisher/name#version`). */\n ref: string;\n assets: number;\n skipped: number;\n /** Library the preset was read from (a library-held preset); absent for source/store presets. */\n library?: string;\n}\n\n/** Minimal store fetcher contract used by the resolver for the catalog branch. */\nexport interface StoreFetcher {\n getInstallManifest(\n storeUrl: string,\n ref: string,\n ): Promise<{\n sourceUrl: string;\n commit: string;\n sha256: string;\n files: Array<{ path: string; sha256: string }>;\n /**\n * Hard dependency refs the store declares for the asset (kind-less\n * `@publisher/name[#pin]` or `kind:@publisher/name[#pin]`). The install manifest\n * itself carries none, so an adapter fills this from the catalog asset row.\n * Absent ⇒ no known deps.\n */\n deps?: string[];\n } | null>;\n getCanonicalDigest(storeUrl: string, ref: string): Promise<{ sha256: string } | null>;\n /**\n * Enumerate the versions a store can serve for a version-less ref\n * (`kind:@<publisher>/name`). Optional — when present, the resolver uses it to\n * discover candidate versions for a store-only asset whose dep ref is bare or\n * ranged (no source clone to derive a version hint from). Absent ⇒ the\n * resolver falls back to the source-derived hint only (legacy behaviour).\n */\n listVersions?(storeUrl: string, ref: string): Promise<string[]>;\n}\n\n/** Options for {@link resolveAll}. */\nexport interface ResolveOpts {\n /** Source-side candidate index built by the walker. */\n provenanceIndex: ProvenanceIndex;\n /** Conflict-resolution overrides (with required reason). */\n overrides: OverrideEntry[];\n /** Trusted store catalogs. */\n stores: StoreEntry[];\n /** Lazy store fetcher; only used when `stores[]` is non-empty. */\n storeFetcher?: StoreFetcher;\n projectDir?: string;\n /**\n * Registered asset kinds (`registry.getAllKinds()`). When set, a dependency of\n * any other kind fails with {@link UnknownAssetKindError}. Kinds that were\n * removed (`bundle`) always fail, with a pointer to their replacement.\n */\n knownKinds?: ReadonlySet<string>;\n /**\n * Refs the project already declares. A transitive dependency whose\n * `<publisher>/<kind>:<name>` identity matches one is resolved with the declared\n * ref (and so its pin) instead of the dependency's own, so walking a new asset\n * never moves a pinned dependency.\n */\n declaredRefs?: readonly string[];\n}\n\nconst SHA_PIN_RE = /^[0-9a-f]{40}$/i;\n\n/**\n * Ensure a transitive dep ref carries a publisher, inheriting `fallback` (the\n * parent candidate's publisher) when absent. Keeps any `#pin` suffix in place.\n * A ref that already names a publisher is returned unchanged; a bare\n * `kind:name[#pin]` ref is re-emitted in the scope form `kind:@publisher/name[#pin]`.\n */\nfunction qualifyPublisher(ref: string, fallback: string): string {\n const hashIdx = ref.indexOf(\"#\");\n const head = hashIdx === -1 ? ref : ref.slice(0, hashIdx);\n // A scoped ref carries `@publisher/`; bare refs (`kind:name`) don't. `parseAssetRef`\n // throws on a bare ref, so detect the scope sigil by string before building one.\n if (head.includes(\"@\")) return ref;\n const pin = hashIdx === -1 ? undefined : ref.slice(hashIdx + 1) || undefined;\n const colonIdx = head.indexOf(\":\");\n const kind = colonIdx === -1 ? \"skill\" : head.slice(0, colonIdx);\n const name = colonIdx === -1 ? head : head.slice(colonIdx + 1);\n return assetRefToStr({ kind, name, publisher: fallback, pin });\n}\n\n/**\n * Resolve all dependencies against a content-hash-verified candidate set drawn\n * from every source clone and (optionally) every store.\n *\n * Per dep ref: gather source candidates, optionally extend with store\n * candidates, filter by the SemVer/SHA pin, pick the highest matching version,\n * then detect conflicts — divergent sha256 for the same\n * `(publisher, kind, name, version)` is a hard {@link CanonicalRefConflictError}\n * unless an `overrides[]` entry pins a source. A cheap `getCanonicalDigest`\n * cross-check runs when both a source and a store produced a candidate at the\n * chosen version.\n *\n * @param deps - Top-level canonical asset ref strings (`kind:@<publisher>/name[#pin]`).\n * @param opts - Provenance index, overrides, stores, and an optional store fetcher.\n * @returns `ResolveResult` with resolved candidates, missing refs, provenance map, applied overrides.\n * @docLink packages/core/api-reference#resolve-all\n */\nexport async function resolveAll(deps: string[], opts: ResolveOpts): Promise<ResolveResult> {\n const resolved: ProvenanceCandidate[] = [];\n const seen = new Set<string>(); // <publisher>/<kind>:<name>\n const missing: string[] = [];\n const resolvedBy = new Map<string, string>();\n const overridesApplied = new Set<string>();\n const overridesByRef = new Map(opts.overrides.map((o) => [o.ref, o]));\n const presets: PresetExpansion[] = [];\n /** `<publisher>/<kind>:<name>` → the ref the project declares for it. */\n const declaredByKey = new Map<string, string>();\n for (const declared of opts.declaredRefs ?? []) {\n try {\n const p = parseAssetRef(declared);\n if (p.publisher) declaredByKey.set(`${p.publisher}/${p.kind}:${p.name}`, declared);\n } catch {\n // A malformed declared ref pins nothing; `visit` reports it when it is resolved.\n }\n }\n\n async function visit(\n refStr: string,\n parent: string,\n depChain: string[],\n presetChain: string[],\n ): Promise<void> {\n const ref = parseAssetRef(refStr); // throws on floating refs etc.\n if (!ref.publisher) throw new Error(`dep \"${refStr}\" missing publisher`);\n assertKnownKind(ref, refStr, opts.knownKinds);\n const key = `${ref.publisher}/${ref.kind}:${ref.name}`;\n if (ref.kind === \"preset\") {\n if (presetChain.includes(key))\n throw new PresetDepthError(\"cycle\", refStr, [...depChain, refStr]);\n if (presetChain.length >= MAX_PRESET_DEPTH) {\n throw new PresetDepthError(\"depth\", refStr, [...depChain, refStr]);\n }\n }\n if (seen.has(key)) return;\n seen.add(key);\n\n // 1. Source-side candidates.\n const sourceCandidates = opts.provenanceIndex.get(key) ?? [];\n\n // 2. Optional store-side candidates.\n const storeCandidates = await gatherStoreCandidates(ref, ref.publisher, sourceCandidates, opts);\n\n const all = [...sourceCandidates, ...storeCandidates];\n if (all.length === 0) {\n missing.push(refStr);\n return;\n }\n\n // 3. Filter by pin.\n const filtered = all.filter((c) => matchPin(ref.pin, c.version));\n if (filtered.length === 0) {\n missing.push(refStr);\n return;\n }\n\n // 4. Highest-version finalists.\n const versions = Array.from(new Set(filtered.map((c) => c.version)));\n const best = versions.sort((a, b) => semver.rcompare(coerceVersion(a), coerceVersion(b)))[0]!;\n const finalists = filtered.filter((c) => c.version === best);\n // Canonical ref == lock key == store wire ref: `kind:@publisher/name#version`.\n const canonicalRef = assetRefToStr({ ...ref, pin: best });\n\n // 5. Conflict detection.\n const chosen = selectChosenCandidate(\n finalists,\n canonicalRef,\n overridesByRef,\n overridesApplied,\n [...depChain, refStr],\n );\n\n // 6. Cheap cross-check when both source and store produced a candidate.\n await crossCheckStoreDigest(\n chosen,\n finalists,\n canonicalRef,\n best,\n sourceCandidates,\n storeCandidates,\n opts,\n [...depChain, refStr],\n );\n\n // A preset is a grouping, not an installable: its asset items join the install\n // set and the lock records only those, never the preset itself.\n const isPreset = chosen.kind === \"preset\";\n if (isPreset) {\n const members = chosen.deps ?? [];\n presets.push({\n ref: canonicalRef,\n assets: members.filter((m) => !m.startsWith(\"preset:\")).length,\n skipped: chosen.skippedItems ?? 0,\n });\n } else {\n resolved.push(chosen);\n }\n resolvedBy.set(key, parent);\n\n // Transitive expansion. Preset and flow candidates carry canonical dep refs;\n // recurse so a preset pulls its members (nested presets up to MAX_PRESET_DEPTH).\n // The `seen` set above dedupes shared deps. A bare ref inherits the parent's\n // publisher (same-source assumption).\n const childPresets = isPreset ? [...presetChain, key] : presetChain;\n for (const depRef of chosen.deps ?? []) {\n const qualified = qualifyPublisher(depRef, chosen.publisher);\n // Same parse `visit` starts with, so a malformed ref fails identically.\n const dep = parseAssetRef(qualified);\n const declared = declaredByKey.get(`${dep.publisher}/${dep.kind}:${dep.name}`);\n await visit(declared ?? qualified, key, [...depChain, refStr], childPresets);\n }\n }\n\n for (const dep of deps) {\n await visit(dep, \"direct\", [], []);\n }\n return { resolved, missing, resolvedBy, overridesApplied, presets };\n}\n\n/**\n * Step 2 of `resolveAll`'s `visit`: gather store-side candidates for `ref`.\n * For each store, derive a version hint (source-derived, or — for a bare/ranged\n * pin with no source hint and a `listVersions` capable fetcher — store-enumerated)\n * and fetch an install manifest per candidate version. Pure: reads `opts`, no\n * closure state. Returns `[]` when no store / fetcher is configured.\n */\nasync function gatherStoreCandidates(\n ref: AssetRef,\n publisher: string,\n sourceCandidates: ProvenanceCandidate[],\n opts: ResolveOpts,\n): Promise<ProvenanceCandidate[]> {\n const storeCandidates: ProvenanceCandidate[] = [];\n if (opts.stores.length === 0 || !opts.storeFetcher) return storeCandidates;\n\n const sourceVersions = sourceCandidates.map((c) => c.version);\n const fetcher = opts.storeFetcher;\n for (const store of opts.stores) {\n // Store-only fallback: with no source-derived version hint and a bare or\n // ranged pin, ask the store which versions it has so the dep can resolve\n // instead of landing in `missing` (exact pins/SHAs need no discovery).\n let versionsHint = sourceVersions;\n if (versionsHint.length === 0 && needsStoreVersionDiscovery(ref.pin) && fetcher.listVersions) {\n versionsHint = await fetcher.listVersions(\n store.url,\n assetRefToStr({ ...ref, pin: undefined }),\n );\n }\n const candidateVersions = enumerateVersionsForPin(ref.pin, versionsHint);\n for (const v of candidateVersions) {\n if (!v) continue;\n const m = await fetcher.getInstallManifest(store.url, assetRefToStr({ ...ref, pin: v }));\n if (m) {\n storeCandidates.push({\n publisher,\n kind: ref.kind,\n name: ref.name,\n version: v,\n sourceUrl: m.sourceUrl,\n commit: m.commit,\n files: m.files,\n sha256: m.sha256,\n deps: m.deps,\n });\n }\n }\n }\n return storeCandidates;\n}\n\n/**\n * Step 5 of `resolveAll`'s `visit`: pick the chosen candidate among the\n * highest-version finalists. Divergent sha256 is a hard conflict unless an\n * `overrides[]` entry pins a source (recorded in `overridesApplied`); otherwise\n * the pick is deterministic by `sourceUrl` ascending.\n */\nfunction selectChosenCandidate(\n finalists: ProvenanceCandidate[],\n canonicalRef: string,\n overridesByRef: Map<string, OverrideEntry>,\n overridesApplied: Set<string>,\n conflictChain: string[],\n): ProvenanceCandidate {\n const uniqueShas = Array.from(new Set(finalists.map((c) => c.sha256)));\n if (uniqueShas.length > 1) {\n const override = overridesByRef.get(canonicalRef);\n if (!override) {\n throw new CanonicalRefConflictError(canonicalRef, finalists, conflictChain);\n }\n const pick = finalists.find((c) => c.sourceUrl === override.source);\n if (!pick) {\n throw new Error(\n `override for ${canonicalRef} points at ${override.source}, ` +\n \"which is not among the resolved candidates\",\n );\n }\n overridesApplied.add(canonicalRef);\n return pick;\n }\n // No conflict — deterministic pick by sourceUrl asc.\n return [...finalists].sort((a, b) => a.sourceUrl.localeCompare(b.sourceUrl))[0]!;\n}\n\n/**\n * Step 6 of `resolveAll`'s `visit`: cheap cross-check that runs only when both a\n * source and a store produced a candidate at the chosen `best` version. A store\n * canonical digest that disagrees with `chosen.sha256` is a hard conflict.\n */\nasync function crossCheckStoreDigest(\n chosen: ProvenanceCandidate,\n finalists: ProvenanceCandidate[],\n canonicalRef: string,\n best: string,\n sourceCandidates: ProvenanceCandidate[],\n storeCandidates: ProvenanceCandidate[],\n opts: ResolveOpts,\n conflictChain: string[],\n): Promise<void> {\n if (\n !opts.storeFetcher ||\n opts.stores.length === 0 ||\n !sourceCandidates.some((c) => c.version === best) ||\n !storeCandidates.some((c) => c.version === best)\n ) {\n return;\n }\n for (const store of opts.stores) {\n const d = await opts.storeFetcher.getCanonicalDigest(store.url, canonicalRef);\n if (d && d.sha256 !== chosen.sha256) {\n throw new CanonicalRefConflictError(\n canonicalRef,\n [...finalists, { ...chosen, sourceUrl: store.url, sha256: d.sha256 }],\n conflictChain,\n );\n }\n }\n}\n\n/** Coerce a version string to a semver-comparable form (synthetic 0.0.0-sha.X is valid semver). */\nexport function coerceVersion(v: string): string {\n return semver.valid(v) ? v : (semver.coerce(v)?.version ?? \"0.0.0\");\n}\n\n/** Match a candidate version against a pin (SemVer range, exact, 40-char SHA, or absent). */\nexport function matchPin(pin: string | undefined, version: string): boolean {\n if (!pin) return true;\n if (SHA_PIN_RE.test(pin)) {\n // SHA pin matches only the synthetic version it produced.\n return version === `0.0.0-sha.${pin.slice(0, 7)}`;\n }\n if (version.startsWith(\"0.0.0-sha.\")) {\n // Synthetic versions satisfy ONLY their exact literal pin.\n return version === pin;\n }\n if (!semver.valid(version)) return version === pin;\n return semver.satisfies(version, pin, { includePrerelease: false });\n}\n\n/**\n * Whether the resolver should ask the store to enumerate versions. True for a\n * bare ref (no pin) or a SemVer range; false for an exact-version pin or a SHA\n * pin (those name a single version, so `getInstallManifest` can be queried\n * directly without discovery).\n */\nfunction needsStoreVersionDiscovery(pin: string | undefined): boolean {\n if (!pin) return true;\n if (SHA_PIN_RE.test(pin)) return false;\n return !semver.valid(pin);\n}\n\nfunction enumerateVersionsForPin(pin: string | undefined, sourceVersionsHint: string[]): string[] {\n if (!pin) return sourceVersionsHint.length > 0 ? sourceVersionsHint : [];\n if (semver.valid(pin)) return [pin];\n // For ranges / SHA pins the resolver re-filters against the source hint.\n return sourceVersionsHint;\n}\n\n// ── Status ───────────────────────────────────────────────────────────────────\n\n/**\n * Status summary for a repository — local HEAD, remote HEAD, and how far behind.\n * @docLink packages/core/api-reference#repo-status\n */\nexport interface RepoStatus {\n /** Logical name of the repository. */\n name: string;\n /** Whether the repo is local, remote (cloned), or linked (dev override). */\n kind: \"local\" | \"remote\" | \"linked\";\n /** Current local HEAD commit SHA. */\n localHead: string;\n /** Remote HEAD commit SHA (fetched during status check). */\n remoteHead: string;\n /** Number of commits the local clone is behind the remote. */\n behind: number;\n /** `true` when `behind === 0`. */\n upToDate: boolean;\n /** Absolute path the link points to (linked repos only). */\n linkedTo?: string;\n /** Human-readable error string when the status check failed. */\n error?: string;\n}\n\n/**\n * Check whether a repository clone is up to date with its remote.\n * Fetches the last 50 commits to compare local HEAD with `origin/<branch>`.\n *\n * @param decl - Repository declaration from `skaile.yaml`\n * @param name - Logical repository name\n * @param reposDir - Project-local source-clone directory (`.skaile/cache/sources/`)\n * @param projectDir - Optional project root for link lookup\n * @returns `RepoStatus` describing the current state\n * @docLink packages/core/api-reference#check-repo-status\n */\nexport function checkRepoStatus(\n decl: SourceDeclaration,\n name: string,\n reposDir: string,\n projectDir?: string,\n): RepoStatus {\n // Check for linked override\n if (projectDir) {\n const links = readLinks(projectDir);\n if (links[name]) {\n return {\n name,\n kind: \"linked\",\n localHead: \"\",\n remoteHead: \"\",\n behind: 0,\n upToDate: true,\n linkedTo: links[name],\n };\n }\n }\n\n // `AssetManager` declares every `sources:` entry as `path:` into the global\n // clone cache plus its `url:` (see {@link ensureRepo}). That clone is ours and\n // tracks the url, so it is status-checked like a bare `url:` source. Only a\n // user-owned `path:` (own checkout, factory tree) is local and never fetched.\n const managedPath =\n decl.path !== undefined &&\n decl.url !== undefined &&\n !decl.factory &&\n isManagedCacheDir(decl.path)\n ? resolve(decl.path)\n : undefined;\n const local = decl.path !== undefined && managedPath === undefined;\n\n const base: RepoStatus = {\n name,\n kind: local ? \"local\" : \"remote\",\n localHead: \"\",\n remoteHead: \"\",\n behind: 0,\n upToDate: true,\n };\n\n if (local) return base;\n\n // Check the managed clone (or the global cache) first, then project-local. A\n // cache dir whose origin maps to a different key than `decl.url` is a stale\n // collision — fall through to the project-local clone rather than reporting\n // status for the wrong repo.\n let dest = managedPath ?? join(getGlobalCacheDir(), name);\n const globalOk =\n existsSync(join(dest, \".git\")) && (!decl.url || remoteUrlMatches(dest, decl.url));\n if (!globalOk) {\n dest = join(reposDir, name);\n }\n if (!existsSync(join(dest, \".git\"))) {\n return { ...base, error: \"Not cloned yet\" };\n }\n\n const branch = decl.branch ?? \"main\";\n\n const localHead = getRepoCommit(dest);\n if (!localHead) return { ...base, error: \"Failed to read local HEAD\" };\n base.localHead = localHead;\n\n const fetchR = spawnSync(\"git\", [\"-C\", dest, \"fetch\", \"--depth=50\", \"origin\", branch], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n env: GIT_ENV,\n });\n if (fetchR.status !== 0) return { ...base, error: \"Fetch failed\" };\n\n const remoteR = spawnSync(\"git\", [\"-C\", dest, \"rev-parse\", `origin/${branch}`], {\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n if (remoteR.status !== 0) return { ...base, error: \"Failed to read remote HEAD\" };\n base.remoteHead = remoteR.stdout.trim();\n\n const countR = spawnSync(\n \"git\",\n [\"-C\", dest, \"rev-list\", \"--left-right\", \"--count\", `HEAD...origin/${branch}`],\n { encoding: \"utf8\", stdio: \"pipe\" },\n );\n if (countR.status === 0) {\n const parts = countR.stdout.trim().split(/\\s+/);\n base.behind = parseInt(parts[1] ?? \"0\", 10);\n }\n\n base.upToDate = base.behind === 0;\n return base;\n}\n","/**\n * Unified workspace configuration — `skaile.yaml` / `<name>.skaile.yaml`\n *\n * Single file combining AI resources, data connectors, agent behavior,\n * runtime defaults, and workspace layout.\n *\n * ── File naming ──────────────────────────────────────────────────────────\n *\n * skaile.yaml → canonical default workspace config\n * staging.skaile.yaml → alternative workspace config\n * *.skaile.yaml → glob pattern for named configs\n *\n * ── Stacking ─────────────────────────────────────────────────────────────\n *\n * Files stack across scope levels (same name must match):\n * ~/.skaile/skaile.yaml priority 10 (user)\n * /app/skaile.yaml priority 20 (app)\n * /project/skaile.yaml priority 30 (project)\n *\n * ── Relationship to other files ──────────────────────────────────────────\n *\n * .skaile/settings.json User-specific overrides (API keys, personal\n * model preferences). Gitignored. Overrides\n * workspace config defaults at runtime.\n *\n * workspace.yaml Scaffold template. Generates skaile.yaml\n * at `skaile init` time. Never read at runtime.\n *\n * agent.yaml Agent definition (identity). Referenced from\n * skaile.yaml via `agent.definition`.\n */\n\nimport {\n type Dirent,\n constants as fsConstants,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport {\n cp as cpAsync,\n open as openAsync,\n readdir as readdirAsync,\n readFile as readFileAsync,\n rm as rmAsync,\n stat as statAsync,\n} from \"node:fs/promises\";\nimport { basename, dirname, join, parse as parsePath, resolve } from \"node:path\";\nimport type { LogLevel, LogStoreMode, LogStoreRetention } from \"@skaile/workspaces/types\";\nimport { parse, stringify } from \"yaml\";\nimport {\n type AgentInstanceConfig,\n agentBlockKeyDiagnostics,\n agentInstanceDiagnostics,\n mergeAgentInstances,\n mergeAgentPermissions,\n normalizeAgentInstances,\n} from \"./agent-instances.js\";\nimport { globalSkaileDir } from \"./cache-paths.js\";\nimport { fsDeadlineMs, tryWithFsDeadline, withFsDeadline } from \"./fs-deadline.js\";\nimport {\n type DriverTarget,\n globalHarnessRoot,\n SUPPORTED_DRIVER_TARGETS,\n} from \"./driver-targets.js\";\nimport { isRetentionValue } from \"./logging/retention-value.js\";\nimport { fromMcpServerMdContent, parseFrontmatter } from \"./manifest.js\";\nimport { type CatalogEntry, parseAssetRef } from \"./models.js\";\nimport { getGlobalCacheDir, getRepoCommit, sourceCacheKey } from \"./repo-manager.js\";\nimport { isRecord } from \"./type-guards.js\";\nimport {\n buildProvenanceIndex,\n type ProvenanceCandidate,\n type ProvenanceIndex,\n type SourceClone,\n} from \"./walker.js\";\n\n// ── Agent config ──────────────────────────────────────────────────────────────\n\n/**\n * Named agent configuration profile. The \"default\" profile is the active one.\n * Personal overrides (preferred model/driver) live in .skaile/settings.json.\n *\n * A profile carries **selection only** (§1.6): which driver runs and which\n * model it talks to. Endpoints and credentials are defined once in\n * `~/.skaile/providers.yml` (or `<workspace>/.skaile/providers.yml`) — a\n * committed `skaile.yaml` that redirects a base URL while the credential comes\n * from elsewhere is an exfiltration primitive, so those keys are parse errors\n * here.\n * @docLink packages/core/workspace-config#agent-config-profile\n */\nexport interface AgentConfigProfile {\n /** Bridge driver to use: \"claude-sdk\", \"codex\", or \"omp\". */\n driver?: string;\n /**\n * Model selector, in one of three forms (§1.6, §9.8):\n * - `\"<providerId>/<modelId>\"` — an entry in the provider registry, e.g.\n * `anthropic/opus`\n * - `\"<modelId>\"` — bare; the first registry entry that maps the id wins,\n * else the first entry in registry order\n * - `\"@role\"` — resolved through the top-level `roles:` table\n *\n * Resolved by `parseModelRef` (`core/provider-registry.ts`); a dangling\n * provider or role falls back to registry order with a warning.\n */\n model?: string;\n /** Thinking mode for Claude models. */\n thinking?: \"adaptive\" | \"enabled\" | \"disabled\";\n /** Reasoning effort level. */\n effort?: \"low\" | \"medium\" | \"high\" | string;\n /** Override framework install paths (rarely needed). */\n skills_dir?: string;\n agents_dir?: string;\n prompts_dir?: string;\n}\n\n// ── Startup ───────────────────────────────────────────────────────────────────\n\n/**\n * A startup directive — run on workspace launch.\n *\n * String form: \"agent:research-assistant\" — start the named agent\n * Object form: { \"system-prompt-override\": \"...\" } — replace system prompt\n * { \"system-prompt-append\": \"...\" } — append to system prompt\n * @docLink packages/core/workspace-config#startup-directive\n */\nexport type StartupDirective = string | Record<string, string>;\n\n// ── AI Resources ──────────────────────────────────────────────────────────────\n\n/**\n * An AI resource source with its own dependency list.\n * All declared dependencies are installed from this source's catalog.\n * @docLink packages/core/workspace-config#ai-resource-entry\n */\nexport interface AiResourceEntry {\n /** Source name (used as cache key and in CLI output). */\n name: string;\n /** Path to local directory or GitHub repo URL. */\n path: string;\n /** Git branch (default: main). */\n branch?: string;\n /** Skill/agent/package/flow refs to install from this source. Syntax: \"kind:name\". */\n dependencies?: string[];\n /** Auto-deploy to framework dirs on install. */\n auto_deploy?: boolean;\n}\n\n// ── Repository Declaration ────────────────────────────────────────────────────\n\n/**\n * Internal-only data shape used by the asset install pipeline (`repo-manager`,\n * `lock`, `runtime-assets`). Carries the resolved URL or path for a `sources[]`\n * entry. Not surfaced directly via the workspace config schema.\n *\n * NOTE: this type was named `RepositoryDeclaration` before 2026-05-31 (the\n * canonical-identity rename). The shape is unchanged — only the name moved\n * from a project-local \"repository\" concept to the source carrier.\n *\n * @docLink packages/core/workspace-config#source-declaration\n */\nexport interface SourceDeclaration {\n /** GitHub or git URL (for remote repos). */\n url?: string;\n /** Local filesystem path (for local repos). */\n path?: string;\n /** Git branch (default: main). */\n branch?: string;\n /** Upstream URL for fork workflows. */\n upstream?: string;\n /**\n * Built-in source shipped inside the package (`dist/factory-assets/`). Deploys\n * are **copied**, not symlinked, even though `path` is set: the bundled dir\n * lives under `node_modules` and is replaced on every upgrade, so a symlink\n * into it would dangle. Injected at runtime by `AssetManager`, never persisted\n * to `skaile.yaml`.\n */\n factory?: boolean;\n /**\n * Publisher declared with `skaile source add --publisher <name>`: the fallback for a\n * source whose manifest declares none and whose URL is not a GitHub one.\n */\n publisher?: string;\n}\n\n// ── Source Entry ──────────────────────────────────────────────────────────────\n\n/**\n * One entry in a project's `sources:` list. Names the upstream git URL plus\n * an optional pin (tag, branch HEAD, or 40-char SHA). The publisher identity\n * is intrinsic to the asset bytes, declared in the source's own\n * `skaile.manifest.yaml`; `publisher` here only fills in when it declares none.\n *\n * Persisted under the `sources:` key in `skaile.yaml`. Bytes live under\n * `<cache>/sources/<slug>/` (unified machine-global clone cache, via\n * `getGlobalCacheDir()`) where the slug is derived from the URL.\n *\n * @docLink packages/core/workspace-config#source-entry\n */\nexport interface SourceEntry {\n /** Git URL (ssh or https). Cache key derives from this. */\n url: string;\n /** Optional pin: branch | tag | 40-char sha. Defaults to HEAD of default branch. */\n pin?: string;\n /**\n * Publisher for assets whose manifest declares none, set by\n * `skaile source add --publisher <name>`. A GitHub URL derives it from the org; any other\n * URL needs it here or in the source's `skaile.manifest.yaml`.\n */\n publisher?: string;\n}\n\n/**\n * Thrown when a `sources:` item in `skaile.yaml` is not an object with a `url:` string.\n * The message is one line that names the entry; the CLI prints it as is.\n *\n * @docLink packages/core/workspace-config#source-entry-error\n */\nexport class SourceEntryError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SourceEntryError\";\n }\n}\n\n/**\n * Validate the raw `sources:` list of a `skaile.yaml` and return it as entries\n * (`pin` kept only when a non-empty string). The one place that decides what a\n * source entry is: the config normalizer and the comment-preserving editor both use it.\n *\n * @throws {SourceEntryError} For the first item that is not an object with a non-empty `url:` string.\n * @docLink packages/core/workspace-config#parse-source-entries\n */\nexport function parseSourceEntries(raw: unknown[]): SourceEntry[] {\n return raw.map((item, i) => {\n const s = item && typeof item === \"object\" && !Array.isArray(item) ? item : undefined;\n const url = (s as Record<string, unknown> | undefined)?.url;\n if (typeof url !== \"string\" || url.trim() === \"\") {\n throw new SourceEntryError(\n `sources[${i}] has no url: ${JSON.stringify(item)} (write it as \"- url: <git url>\")`,\n );\n }\n const entry: SourceEntry = { url };\n const pin = (s as Record<string, unknown>).pin;\n if (typeof pin === \"string\" && pin.length > 0) entry.pin = pin;\n const publisher = (s as Record<string, unknown>).publisher;\n if (typeof publisher === \"string\" && publisher.length > 0) entry.publisher = publisher;\n return entry;\n });\n}\n\n/**\n * One entry in a project's `stores:` list. Catalog endpoint URL only.\n * The store backend authenticates publisher identity; no project-side\n * trust declaration applies.\n *\n * @docLink packages/core/workspace-config#store-entry\n */\nexport interface StoreEntry {\n /** Catalog base URL (e.g. `https://skaile.store`). */\n url: string;\n}\n\n/**\n * One entry in `overrides:`. Pins a specific canonical ref to one source\n * URL when two or more candidates diverge on sha256. The `reason:` field\n * is REQUIRED and non-empty; empty or missing is a parse-time error.\n *\n * @docLink packages/core/workspace-config#override-entry\n */\nexport interface OverrideEntry {\n /** Canonical ref form: `<publisher>/<kind>:<name>@<version>`. */\n ref: string;\n /** One of the candidate source URLs. */\n source: string;\n /** Non-empty justification. */\n reason: string;\n}\n\n// ── Mounts ──────────────────────────────────────────────────────────────────\n\n/**\n * A filesystem mount — projected storage backend.\n * @docLink packages/core/workspace-config#mount-declaration\n */\ninterface MountDeclaration {\n /** Unique identifier. Used as mount dir name. */\n id: string;\n /** Mount driver: \"local\", \"git\", \"s3\", \"webdav\", \"sharepoint\". */\n driver: string;\n /** What to mount: URL, bucket path, host filesystem path. */\n source: string;\n /** Workspace-relative mount point (default: .mounts/<id>). */\n target?: string;\n /** Access level enforced by the mount driver. */\n access?: \"read-only\" | \"read-write\";\n /** Credential reference: \"env:VAR_NAME\" or inline value. */\n auth?: string;\n /**\n * Whether to watch this mount for filesystem changes.\n * true = always watch, false = never watch, undefined = auto (watch if read-write).\n */\n watch?: boolean;\n /**\n * **Expert-only.** When `true`, the mount manager wires the resolved\n * credential into the workspace so the agent's interactive `git`/`curl`\n * tools can authenticate directly against the mount's host. Defaults to\n * `false` — agents have no credential exposure and rely on driver-managed\n * pulls/pushes. See `_devlog/specs/2026-05-05-git-credential-tiers.md`.\n */\n exposeAccessToken?: boolean;\n /**\n * Optional override for the access token TTL (seconds). When omitted, the\n * provider's natural TTL is used. Values above the provider's documented\n * maximum are silently capped.\n */\n accessTokenTTL?: number;\n /** Driver-specific configuration (branch, region, etc.). */\n options?: Record<string, unknown>;\n}\n\n// ── Connectors ────────────────────────────────────────────────────────────────\n\n/**\n * A data connector — tool-accessed backend the agent interacts with.\n * @docLink packages/core/workspace-config#connector-declaration\n */\nexport interface ConnectorDeclaration {\n /** Unique identifier. Used as tool namespace. */\n id: string;\n /** Connector adapter: \"postgres\", \"redis\", \"sqlite\", \"memory\", \"xstate\", \"xstate-store\", \"yjs\". */\n driver: string;\n /**\n * Access level enforced by ConnectorManager.\n * Optional in config — ConnectorManager defaults to \"read-only\" when absent.\n */\n access?: \"read-only\" | \"read-write\";\n /** Credential reference: \"env:VAR_NAME\" or inline value. */\n auth?: string;\n /**\n * Backend-mediated credential routing key. For backend-auth mounts the\n * platform serializes this top-level so the runner can mint/refresh the\n * connector token via `host.refresh_credential`. Must survive the\n * skaile.yaml → declaration mapping or live token refresh fails.\n */\n providerLinkId?: string;\n /**\n * Operating mode for connectors that manage a working copy. Orthogonal to\n * faces. `agent` = the agent drives the source natively (e.g. native git) and\n * the connector only provisions short-lived credentials. `sync` = the\n * connector owns the working copy (clone + watch + auto-commit/pull). Absent =\n * the driver's legacy `options.{session,sync,lifecycle}` blocks decide.\n */\n mode?: \"agent\" | \"sync\";\n /** Adapter-specific configuration (dsn, host, etc.). */\n options?: Record<string, unknown>;\n\n // ── Extended fields (Plan A: first-level asset support) ──────────────────\n /** Semver range for future catalog versioning, e.g. \"^1.0.0\". */\n version?: string;\n /**\n * Run a health check (ping) when the connector is first connected.\n * Default: false. Set to true to surface connection errors early.\n */\n health_check?: boolean;\n /**\n * Inject this connector's skill description into the agent's system prompt.\n * Default: false.\n */\n expose_as_skill?: boolean;\n /** Tags for catalog browsing and skill routing. */\n tags?: string[];\n\n /**\n * Optional filesystem face — makes the connector \"mountable\".\n * When present, ConnectorManager allocates a mount directory and passes it\n * to the connector via `ConnectContext.mountTarget`.\n *\n * YAML key: `mount` (sub-block under a `connectors:` entry).\n * Replaces the legacy top-level `mounts:` key (hard cut — see Task 11).\n */\n mount?: {\n /** Source URL or path (repo URL, bucket name, host path). */\n source: string;\n /** Override mount target directory (default: `.mounts/<id>/`). */\n target?: string;\n /** Watch flag: omitted → watch read-write, skip read-only. */\n watch?: boolean;\n /** Expert-only: expose the resolved credential to the agent CLI. */\n exposeAccessToken?: boolean;\n /** Optional access-token TTL override (seconds). */\n accessTokenTTL?: number;\n };\n\n /**\n * `local` driver only: the host directory the connector exposes. Same as\n * `params.mountPath`. `${project}` is the project directory; a relative path\n * is relative to it. Ignored when `mount:` is set.\n */\n mountPath?: string;\n /** `local` driver only: `{ mountPath }`, the nested form of {@link ConnectorDeclaration.mountPath}. */\n params?: { mountPath?: string; [key: string]: unknown };\n\n /**\n * Written by a host (the platform) for a connector it declares but has\n * already decided cannot be attached. The runner never attempts a connect\n * for it and lists it as failed with this reason, so the connector stays\n * visible from inside the session instead of vanishing from the config.\n * `reason` is a short host-chosen token, `detail` its prose. Older runners\n * ignore the key.\n */\n unavailable?: { reason: string; detail?: string } | string;\n}\n\n// ── MCP Servers ──────────────────────────────────────────────────────────────\n\n/**\n * Reference to a Nix-built asset recipe.\n *\n * Two source forms:\n * - **Platform-flake attr (legacy):** `{ attr }` selects an attribute path in\n * the platform flake (`/etc/skaile/flake/`), e.g. `mcps.excel`, `mcps.ppt`,\n * `stacks.baseline`. The leaf of `attr` doubles as the recipe-map lookup key.\n * - **Self-contained flake (BYO-flake):** `{ flake, attr? }` names a flake that\n * travels with the asset (`flake: \".\"`) or a remote URL for allowlisted\n * third-party publishers. The host-side builder resolves it to a store path.\n * Here `attr` is the in-flake BUILD target only (defaults to `\"default\"`);\n * the recipe **id** (the MCP declaration id) is the recipe-map / `${recipe:<id>}`\n * marker key, never `attr`.\n *\n * Resolution happens at session start (cold) and on `reconfigure_mcps` (hot-add)\n * via the prebuilt recipe map → `nix path-info --offline` fallback.\n *\n * @docLink packages/core/concepts#asset-recipe\n */\nexport interface AssetRecipe {\n /**\n * Flake attribute to resolve/build.\n * - Legacy `{ attr }` form: required, e.g. `mcps.excel`.\n * - BYO-flake `{ flake, attr? }` form: optional, defaults to `\"default\"`.\n */\n attr?: string;\n /**\n * Optional flake source. `\".\"` = the asset's own `flake.nix` (resolved\n * relative to the asset directory by the host-side builder). A flake URL\n * (`github:…`, `git+https://…`, `git+ssh://…`, `path:/…`) is permitted only\n * for publishers on the curated allowlist (enforced host-side). Absent = the\n * platform flake (legacy behaviour).\n */\n flake?: string;\n /**\n * Publisher id that authored this recipe's flake. Required (host-side) when\n * `flake` is a remote URL; the builder checks it against the allowlist.\n * Defaults to the owning asset's publisher when `flake` is `\".\"`.\n */\n publisher?: string;\n}\n\n/** Default in-flake build target for the BYO-flake form when `attr` is omitted. */\nexport const DEFAULT_RECIPE_ATTR = \"default\";\n\n/**\n * Validates an `AssetRecipe.flake` source string.\n *\n * Accepted forms:\n * - `\".\"` — the asset's own flake directory (always allowed).\n * - a flake URL with a recognised scheme: `github:`, `git+https://`,\n * `git+ssh://`, `path:/` (absolute-only).\n *\n * Rejected: empty strings, local relative/absolute paths other than `\".\"`\n * (including `..` traversal and bare `/abs/path` — those must go through an\n * explicit `path:` URL), and unknown schemes. This guards the value before the\n * host-side builder interpolates it into `nix build \"<flake>#<attr>\"`; the\n * allowlist gate is a *separate* trust check, not a substitute for this.\n *\n * NOTE: this validates *shape*, not allowlist membership — the publisher\n * allowlist is enforced host-side by the builder, which has the allowlist file.\n *\n * @throws Error when `flake` is malformed\n */\nexport function validateAssetRecipeFlake(flake: string): void {\n if (typeof flake !== \"string\" || flake.length === 0) {\n throw new Error(\"AssetRecipe.flake must be a non-empty string\");\n }\n if (flake.length > 500) {\n throw new Error(`AssetRecipe.flake too long (${flake.length} chars, max 500)`);\n }\n if (flake === \".\") return;\n // Recognised flake-URL schemes only. Everything else (relative paths, bare\n // absolute paths, `..`, `file:`, arbitrary schemes) is rejected — a local\n // path must be expressed as an explicit `path:` URL.\n // `path:` is absolute-only (`path:/…`): a remote catalog entry must not be\n // able to name a relative path or `..` escape via `path:relative/x`.\n const ALLOWED_SCHEME = /^(github:|git\\+https:\\/\\/|git\\+ssh:\\/\\/|path:\\/)/;\n if (!ALLOWED_SCHEME.test(flake)) {\n throw new Error(\n `AssetRecipe.flake \"${flake}\" has an unsupported source. ` +\n `Allowed: \".\" or a flake URL (github:, git+https://, git+ssh://, path:/).`,\n );\n }\n // Defense-in-depth: reject shell/nix metacharacters that have no place in a\n // flake ref even within an accepted scheme (the ref is also passed quoted by\n // the builder, but belt-and-braces). `#` is the nix attr separator — the\n // builder appends `#<attr>`, so a `#` in the flake ref would yield a\n // malformed `flake#x#attr` invocation.\n if (/[\\s`$;|&<>(){}#\\n\\r]/.test(flake)) {\n throw new Error(`AssetRecipe.flake \"${flake}\" contains forbidden characters.`);\n }\n}\n\n/**\n * Validates an `AssetRecipe.attr` value against nix attribute path syntax.\n *\n * Nix attribute paths are dot-separated segments. Each segment must start with\n * a letter and contain only letters, digits, underscores, hyphens, and dots.\n * Characters like `#`, spaces, and nix expression fragments are explicitly\n * rejected — even though `spawnSync` array args prevent shell injection, nix\n * parses the combined `flakeRef#attr` string and invalid chars trigger\n * unintended evaluation paths.\n *\n * Deliberate restriction: leading digits per segment are not allowed even\n * though some nix attrs permit them, because they are rare in practice and\n * the restriction makes the validation straightforward to audit.\n *\n * @throws Error when `attr` is invalid\n */\nexport function validateAssetRecipeAttr(attr: string): void {\n if (typeof attr !== \"string\" || attr.length === 0) {\n throw new Error(\"AssetRecipe.attr must be a non-empty string\");\n }\n if (attr.length > 200) {\n throw new Error(`AssetRecipe.attr too long (${attr.length} chars, max 200)`);\n }\n const VALID_ATTR = /^[a-z][a-z0-9._-]*(?:\\.[a-z][a-z0-9._-]*)*$/i;\n if (!VALID_ATTR.test(attr)) {\n throw new Error(\n `AssetRecipe.attr \"${attr}\" contains invalid characters. ` +\n `Allowed: letters, digits, underscore, hyphen, dot. ` +\n `Each dot-segment must start with a letter.`,\n );\n }\n}\n\n/**\n * A declarative external MCP server — spawned or connected at session startup\n * and injected into the Claude SDK driver as a named `mcpServers` entry.\n *\n * Maps directly to the Claude Agent SDK's `McpServerConfig` union:\n * - `transport: \"stdio\"` (default) → `McpStdioServerConfig` — subprocess spawn\n * - `transport: \"sse\"` → `McpSSEServerConfig` — HTTP Server-Sent Events\n * - `transport: \"http\"` → `McpHttpServerConfig` — HTTP streaming\n *\n * The `id` becomes the key in the SDK's `mcpServers` record and also the MCP\n * tool prefix (e.g., `mcp__my-server__<tool-name>`).\n * @docLink packages/core/workspace-config#mcp-server-declaration\n */\nexport interface McpServerDeclaration {\n /** Unique identifier — used as the `mcpServers` record key and tool prefix. */\n id: string;\n /**\n * Transport type.\n * Default: `\"stdio\"` (subprocess).\n */\n transport?: \"stdio\" | \"sse\" | \"http\";\n /** For `\"stdio\"`: the command to execute (e.g. `\"npx\"`, `\"node\"`, `\"python\"`). */\n command?: string;\n /** For `\"stdio\"`: arguments passed to the command. */\n args?: string[];\n /** For `\"stdio\"`: environment variables injected into the subprocess. */\n env?: Record<string, string>;\n /** For `\"sse\"` and `\"http\"`: the server URL. */\n url?: string;\n /** For `\"sse\"` and `\"http\"`: HTTP headers (e.g. `Authorization`). */\n headers?: Record<string, string>;\n /**\n * For `\"sse\"` and `\"http\"`: a PEM CA certificate (or a secret ref to one,\n * e.g. `env:MCP__<id>__CA`) that this server's TLS certificate must chain to.\n * Pinned per connection, never process-wide; the URL must be `https:`.\n * Absent: the default trust store applies.\n */\n ca?: string;\n /**\n * Credential resolution mode for a remote (sse/http) server. `\"backend\"` means\n * the platform mints + provisions the bearer (header `Authorization:\n * env:MCP__<id>__AUTH`) and the runner re-mints it on a 401. Written by the\n * platform; absent for local / static-token servers.\n */\n auth?: string;\n /**\n * For a remote `auth: \"backend\"` server: the org `ProviderLink` whose OAuth\n * credential backs this server's bearer. The runner passes it as the re-mint\n * `id` on a 401. Written by the platform alongside `auth`.\n */\n providerLinkId?: string;\n /** Short description of what this server provides (used in catalog). */\n description?: string;\n /** Tags for catalog browsing and discovery. */\n tags?: string[];\n /**\n * Named launcher strategy for a local (stdio) server. Selectable + explicit;\n * default is inferred (recipe present → \"recipe\"; else a pass-through\n * \"path\"/\"package-runner\" command-shape). Only \"recipe\" carries resolution\n * logic; \"package-runner\" (npx/uvx/pip) and \"path\" are documented command\n * shapes the stdio transport already spawns as-is. Ignored for remote (sse/http).\n */\n launcher?: \"recipe\" | \"package-runner\" | \"path\";\n /**\n * Optional Nix recipe binding. When present, the runner resolves the\n * recipe's `/nix/store` out-path before subprocess spawn and substitutes\n * `${recipe:<id>}` / `${recipe:<id>:<sub>}` / `${recipe:<id>:bin}` /\n * `${recipe:<id>:lib}` markers in `command`, `args`, and `env` values.\n * `<id>` matches this declaration's `id` field.\n */\n recipe?: AssetRecipe;\n /** Owner-authored instruction text from the materialized MCP.md body (preset custom instructions). */\n instructions?: string;\n /**\n * Internal provenance, never authored in `skaile.yaml`: set when a sibling\n * `.instance.json` contributed **resolved secret values** to `env` (see\n * `foldInstanceEnv`). Those values are live plaintext credentials that must\n * stay in memory — the same reason `.instance.json` is never copied into\n * `.claude/skills/`. Any consumer that would persist a declaration to disk\n * (e.g. rendering it into a coding agent's MCP config) must skip a\n * declaration carrying this flag.\n */\n instanceSecretsFolded?: boolean;\n}\n\n// ── Agent Configuration ──────────────────────────────────────────────────────\n\n/**\n * Platform-level context describing the environment the agent operates in.\n * Rendered by the runner into a \"## Platform\" section of the system prompt.\n */\nexport interface AgentContextConfig {\n /** Platform identifier (e.g. \"skaile\"). Controls the rendered header sentence. */\n platform?: string;\n /** Whether multiple users may interact in the same session. */\n multi_user?: boolean;\n /** Session persistence model. */\n session_model?: \"persistent\" | \"ephemeral\";\n}\n\nexport interface AgentConfig {\n /**\n * Agent definition reference. Resolved in order:\n * - Local path: \".skaile/agent\" or \"./my-agent\"\n * - Catalog reference: \"agent:@<publisher>/<name>\" or \"agent:<name>\" (the\n * agent dir whose agent.yaml declares that `name:`; see `resolveAgentDir`)\n * - Resource path: \"ai-assets://<path>/agents/<name>\"\n */\n definition?: string;\n\n /**\n * Platform-level context (platform identifier, multi-user flag, session model).\n * Consumed by the runner to build the \"## Platform\" section of the system prompt.\n */\n context?: AgentContextConfig;\n\n /** Agent runtime constraints. */\n permissions?: AgentPermissions;\n\n /** Lifecycle hooks — shell commands run at specific points. */\n hooks?: AgentHooks;\n\n /**\n * Named agent instances bound into this workspace, keyed by instance id.\n * `definition` above is the primary instance (== `instances.default`);\n * declaring both is an error (`agent_default_conflict`).\n *\n * YAML key: root `agents:` (not nested under `agent:`).\n */\n instances?: Record<string, AgentInstanceConfig>;\n\n /**\n * Control which framework fragments are included in the rendered system prompt.\n * true (default) — include built-in fragment\n * false — omit this fragment\n * string — path to a custom markdown file (relative to project root)\n *\n * Fragment IDs: \"agent-mode\" | \"skill-discovery\" | \"connector-usage\" | \"handoff\"\n */\n fragments?: Record<string, boolean | string>;\n\n /**\n * Additional markdown files appended at the end of every rendered agent system\n * prompt in this workspace. Paths relative to the project root (skaile.yaml).\n *\n * YAML key: `prompt-extensions`\n */\n \"prompt-extensions\"?: string[];\n\n /**\n * Assistant home block: files the runner reads at every session build and\n * renders as one framed block directly after `prompt`. Unlike\n * `prompt-extensions` it is capped per file and allowed under managed Codex,\n * because its reader refuses symlinks and paths outside the project root.\n *\n * @since 4.10\n */\n home?: AgentHomeConfig;\n\n /**\n * Free-form user-authored agent prompt. Plain text or markdown — no length\n * cap, no template substitution. Prepended immediately after the platform\n * context section and before the environment section in the assembled\n * system prompt (see runner's {@link assembleSystemPrompt}).\n *\n * Written by the platform's wake-time yaml serializer from the combined\n * project-level + session-level prompts stored on `SkaileConfigData.agent.prompt`.\n * Standalone CLI / forge sessions may set this directly in `skaile.yaml`.\n *\n * Spec: `docs/superpowers/specs/2026-05-13-platform-agent-prompt-design.md`\n * @since 2026-05\n */\n prompt?: string;\n}\n\n/**\n * `agent.home` in skaile.yaml. Rendered as:\n *\n * ```text\n * <TAG>\n * <intro>\n *\n * ## <label>\n * <content>\n *\n * ## <label>\n * <content>\n * </TAG>\n * ```\n *\n * A file that is absent, empty or whitespace-only is left out; the whole block is\n * left out when no file contributes. A file that cannot be read is left out and\n * logged — it never fails the session.\n */\nexport interface AgentHomeConfig {\n /** Frame tag name, `[A-Z][A-Z0-9_]*`. Default `SKAILE_HOME`. */\n tag?: string;\n /** One line printed under the opening tag, followed by a blank line. Omitted when absent. */\n intro?: string;\n /** Files in render order. At most 16; the first entry per `path` wins. */\n files: AgentHomeFile[];\n}\n\n/** One `agent.home.files` entry. */\nexport interface AgentHomeFile {\n /**\n * Relative to the project root (the `skaile.yaml` directory), `/`-separated.\n * No absolute path, no `.`/`..` segment and no segment starting with `.`.\n */\n path: string;\n /** Section heading. Default: the file name without its `.md` extension. */\n label?: string;\n /** Character cap (UTF-16 code units), 1–100000. */\n \"max-chars\": number;\n /** Which end survives the cap. `tail` keeps the newest lines of an append-only file. Default `head`. */\n from?: \"head\" | \"tail\";\n}\n\nexport interface AgentPermissions {\n /** Maximum agentic turns per query (default: 15). */\n max_turns?: number;\n /**\n * Permission mode for Claude SDK driver.\n * 'auto' = bypassPermissions (default for automated flows).\n * 'interactive' = prompt for each tool use.\n */\n permission_mode?: \"auto\" | \"interactive\";\n /** Glob patterns the agent may NOT write to. Stacking: union across scopes. */\n deny_write?: string[];\n /** Glob patterns the agent may NOT read. Stacking: union across scopes. */\n deny_read?: string[];\n /**\n * Network egress policy. Codec is permissive — the platform decides\n * enforcement.\n */\n network?: NetworkPolicy;\n}\n\n/**\n * Per-session egress policy: `open` allows everything, `off` allows only\n * platform-resolved LLM-provider endpoints, `allowlist` adds user-supplied\n * domains. `allowlist` field is ignored when `mode !== 'allowlist'`.\n */\nexport interface NetworkPolicy {\n mode: \"open\" | \"off\" | \"allowlist\";\n allowlist?: string[];\n}\n\nconst KNOWN_NETWORK_MODES = [\"open\", \"off\", \"allowlist\"] as const;\n\nexport interface AgentHooks {\n /** Run before a flow starts (after resources are connected). */\n pre_flow?: HookEntry[];\n /** Run after a flow completes (before resources disconnect). */\n post_flow?: HookEntry[];\n /** Run before each flow node executes. */\n pre_node?: HookEntry[];\n /** Run after each flow node completes successfully. */\n post_node?: HookEntry[];\n}\n\nexport interface HookEntry {\n /** Human-readable hook name. */\n name: string;\n /** Shell command to execute. */\n run: string;\n /** Working directory relative to workspace root (default: workspace root). */\n cwd?: string;\n /** Timeout in seconds (default: 60). */\n timeout?: number;\n /** Continue flow if hook fails (default: false). */\n continue_on_error?: boolean;\n}\n\n// ── Workspace Layout ─────────────────────────────────────────────────────────\n\nexport interface WorkspaceLayoutConfig {\n /** Directories to ensure exist (created at scaffold time, verified at run time). */\n directories?: string[];\n\n /** Git configuration. */\n git?: GitConfig;\n\n /** Post-scaffold setup commands (run once after `skaile init`). */\n setup?: SetupEntry[];\n\n /** Container configuration (Docker). */\n container?: ContainerConfig;\n}\n\nexport interface GitConfig {\n /** Initialize a git repo at scaffold time (default: true). */\n init?: boolean;\n /** .gitignore entries. Stacking: concatenate + deduplicate. */\n ignore?: string[];\n}\n\nexport interface SetupEntry {\n /** Human-readable name. */\n name: string;\n /** Shell command to execute. */\n run: string;\n /** Working directory relative to workspace root. */\n cwd?: string;\n /** Continue if command fails (default: false). */\n continue_on_error?: boolean;\n}\n\nexport interface NixContainerConfig {\n /**\n * Nixpkgs package attribute names to include in the environment.\n * Example: [\"nodejs_22\", \"bun\", \"git\", \"python3\"]\n */\n packages?: string[];\n /**\n * Nixpkgs registry name used as a package prefix for `nix shell`.\n * MUST be a bare registry name like \"nixpkgs\" — not a channel path like\n * \"nixpkgs/nixos-24.11\" (which is not valid as a flake ref prefix).\n * Defaults to \"nixpkgs\".\n */\n channel?: string;\n /**\n * Path to a Nix file (shell.nix / flake.nix) relative to the project root.\n * When set, `packages` and `channel` are ignored — the file is the source of truth.\n */\n flake?: string;\n /**\n * Predefined named stack to resolve from the system stack registry (SKAILE_NIX_STACK_REGISTRY).\n * Overridden by `packages` if present.\n * Takes precedence over the parent `ContainerConfig.stack` field when nix mode is active.\n */\n stack?: string;\n}\n\nexport interface ContainerConfig {\n /** Enable Docker container generation. */\n enabled?: boolean;\n /** Base Docker image. */\n image?: string;\n /** System packages to install. */\n packages?: string[];\n /** Agent CLIs to install globally in the container. */\n agent_clis?: string[];\n /** Ports to expose. */\n ports?: string[];\n /** Environment variables to pass through. */\n env?: string[];\n /** Docker volume/bind mounts. */\n mounts?: Array<{ type: \"bind\" | \"volume\"; source: string; target: string }>;\n /** WebSocket port for IPC. */\n ws_port?: number;\n /**\n * Named system stack.\n * - Docker mode: resolved to an image tag via `dockerImageMap` (SKAILE_DOCKER_IMAGE_MAP).\n * - Nix mode: resolved to a package list via `nixStackRegistry` (SKAILE_NIX_STACK_REGISTRY).\n * Overridden by `nix.stack` if both are present.\n */\n stack?: string;\n /** Nix-specific environment configuration (nix session mode only). */\n nix?: NixContainerConfig;\n}\n\n// ── Top-level config ──────────────────────────────────────────────────────────\n\nexport interface SkWorkspaceConfig {\n /** Project name (defaults to directory basename). */\n name?: string;\n /** Project description. */\n description?: string;\n\n /**\n * Agent configuration profiles. The \"default\" profile provides runtime\n * defaults (driver, model selector). Personal overrides live in\n * .skaile/settings.json and always take priority.\n *\n * YAML key: `agent-config` or `agent_config`\n */\n agent_config?: Record<string, AgentConfigProfile>;\n\n /**\n * Model role aliases (§9.8) — `default`, `smol`, `slow`, or any name an\n * agent manifest references as `@role`. Each value is a model selector:\n * `\"<providerId>/<modelId>\"` or a bare `<modelId>`.\n *\n * Roles live here rather than in `providers.yml` because a role is a\n * *selection* (\"what this project calls its cheap model\"), and selection is\n * the half of the configuration a team commits. Resolution is lenient: a\n * role naming an entry this machine does not have falls back to registry\n * order with a warning instead of failing the session.\n *\n * YAML key: `roles`\n */\n roles?: Record<string, string>;\n\n /**\n * Startup directives — executed when the workspace is launched.\n * Each item is either a string (\"agent:name\") or a map\n * ({ \"system-prompt-override\": \"...\" }).\n */\n startup?: StartupDirective[];\n\n /**\n * Asset dependencies using `kind:name@<publisher>[#pin]` syntax.\n * Top-level flat list — sources and deps are separate concerns.\n *\n * YAML key: `dependencies`\n */\n dependencies?: string[];\n\n /**\n * Global cross-harness install set — the coding-agent harnesses a `skaile\n * install --global` fans `dependencies:` out to. Only meaningful in the\n * user-scope SSOT (`~/.skaile/skaile.yaml`). When absent, the harness set is\n * auto-detected from existing `~/.<harness>` dirs (see `resolveGlobalHarnesses`).\n * Each entry must be a `DriverTarget` (`claude-code` | `omp` | `codex`).\n *\n * YAML key: `global_harnesses` (the pre-4.34 `global_backends` is still read).\n */\n global_harnesses?: DriverTarget[];\n\n /**\n * Github sources this project depends on. Each entry is `{url, pin?}`; the\n * cache slug is derived from the URL. `skaile install` clones any missing\n * entries; `skaile source add/remove/sync` are the CRUD surface.\n *\n * YAML key: `sources`\n */\n sources?: SourceEntry[];\n\n /**\n * Consumption-half: trusted store catalogs queried per dep.\n *\n * YAML key: `stores`\n */\n stores?: StoreEntry[];\n\n /**\n * Consumption-half: conflict-resolution overrides with required reason.\n *\n * YAML key: `overrides`\n */\n overrides?: OverrideEntry[];\n\n /**\n * Local patches applied during install (new format).\n * Maps \"kind:name\" → patch file path relative to project root.\n *\n * YAML key: `patches`\n */\n patches?: Record<string, string>;\n\n /**\n * @deprecated The top-level `mounts:` key is no longer supported as of Task 11.\n *\n * Move filesystem-projected storage backends under `connectors:` with a\n * `mount:` sub-block. See `docs/migration-mounts-to-connectors.md`.\n *\n * This field is kept on the type **only** so `config.ts` can detect a\n * present `mounts:` block and throw a migration error. It is never merged,\n * applied, or forwarded to any manager. `normalizeConfig` still populates it\n * when `mounts:` is present in the YAML so the detection check works.\n *\n * YAML key: `mounts` (rejected at runtime — do not use)\n */\n mounts?: MountDeclaration[];\n\n /**\n * Data connectors — tool-accessed backends.\n *\n * Each declaration's `driver` field is an *implicit* catalog ref\n * (`connector:<driver>`). The runtime resolves it through\n * `resolveRuntimeAssets()`, which scans every declared `repositories` entry\n * plus the implicit built-in `factory-assets` repo for matching `CONNECTOR.md`\n * manifests. Drivers that do not match any catalog entry produce a\n * `missing_driver` warning at session startup.\n *\n * YAML key: `connectors`\n */\n connectors?: ConnectorDeclaration[];\n\n /**\n * External MCP servers — injected into the Claude SDK driver at session startup.\n * Supports stdio subprocess, SSE, and HTTP transports.\n *\n * YAML key: `mcp_servers`\n */\n mcp_servers?: McpServerDeclaration[];\n\n /** Agent behavior — definition reference, instances, permissions, hooks. */\n agent?: AgentConfig;\n\n /** Workspace layout — directories, git, setup scripts, container. */\n workspace?: WorkspaceLayoutConfig;\n\n /**\n * Secret provisioning configuration.\n * Controls how connector credentials are resolved at runtime.\n *\n * YAML key: `secrets`\n */\n secrets?: SecretsConfig;\n\n /**\n * Telemetry configuration — passed through raw to the telemetry package.\n * Parsed by `resolveTelemetryConfig` in `@skaile/workspaces/telemetry`.\n *\n * YAML key: `telemetry`\n */\n telemetry?: Record<string, unknown>;\n\n /**\n * Session compaction settings -- controls when and how conversation\n * snapshots are created.\n *\n * YAML key: `compaction`\n */\n compaction?: CompactionConfig;\n\n /**\n * Structured-log settings for the session's `LogStore`: storage mode, minimum\n * level, and the `logs.db` retention trim. The platform writes this block for\n * cloud sessions; the runner reads it once at start.\n *\n * YAML key: `logging`\n */\n logging?: LoggingConfig;\n\n /**\n * Plugin specs to load into pluginRegistry — npm specifiers like\n * \"@skaile/provider-fly@^0.1.0\". Opt-in; no auto-discovery. YAML key: `plugins`.\n */\n plugins?: string[];\n /** Deploy target selection. YAML key: `deploy`. */\n deploy?: DeployBlock;\n}\n\n/** Deploy target selection for `skaile deploy`. YAML key: `deploy`. Resolved through pluginRegistry at deploy time. */\nexport interface DeployBlock {\n /** Deploy target id (e.g. \"local\", \"docker\", \"fly\") — resolved against pluginRegistry at deploy time, not validated here. */\n target: string;\n /** Target-specific config; validated by the target's configSchema at resolve time. */\n config?: unknown;\n}\n\nexport interface SecretsConfig {\n /**\n * How secrets are provided to the container.\n * \"env\" — read from process.env (default, for CLI/standalone)\n * \"provisioned\" — wait for secrets over transport bridge (platform containers)\n */\n provider?: \"env\" | \"provisioned\";\n /** Timeout in ms for waiting for provisioned secrets (default: 30000). */\n timeoutMs?: number;\n}\n\n// ── Logging config ───────────────────────────────────────────────────────────\n\n/**\n * The `logging:` block. Every key is optional; the runner falls back to\n * `persistent` / `info` and the cloud retention defaults. `SKAILE_LOG_MODE` and\n * `SKAILE_LOG_LEVEL` override `mode` and `level`.\n */\nexport interface LoggingConfig {\n mode?: LogStoreMode;\n level?: LogLevel;\n retention?: LogStoreRetention;\n}\n\n// Keyed so a new `LogStoreMode` / `LogLevel` member fails to compile here until\n// it is accepted, keeping this set equal to the one `resolveLogStoreConfig` allows.\nconst KNOWN_LOG_MODES = { persistent: true, ephemeral: true, off: true } satisfies Record<\n LogStoreMode,\n true\n>;\nconst KNOWN_LOG_LEVELS = { debug: true, info: true, warn: true, error: true } satisfies Record<\n LogLevel,\n true\n>;\n\n// ── Compaction config ────────────────────────────────────────────────────────\n\nexport interface CompactionConfig {\n /** Enable managed compaction (default: true). */\n enabled?: boolean;\n /**\n * Flat override: when set, it wins over both tiers. Unset by default, so the\n * tiered values below decide; see {@link resolveCompactionThresholdPercent}.\n */\n thresholdPercent?: number;\n /** Context fill percentage that triggers compaction on a large window (default: 40). */\n largeWindowThresholdPercent?: number;\n /** Context fill percentage that triggers compaction on a small window (default: 80). */\n smallWindowThresholdPercent?: number;\n /** Context window, in tokens, at or above which the large-window percentage applies (default: 1000000). */\n largeWindowMinTokens?: number;\n /** Minimum ms between compactions to prevent thrashing (default: 120000). */\n minCooldownMs?: number;\n /** Enable manual compact command in expert mode (default: false). */\n manualCompactEnabled?: boolean;\n}\n\n/** A {@link CompactionConfig} with every key resolved except the flat `thresholdPercent` override. */\nexport type ResolvedCompactionConfig = Required<Omit<CompactionConfig, \"thresholdPercent\">> &\n Pick<CompactionConfig, \"thresholdPercent\">;\n\n/**\n * Compaction defaults. `thresholdPercent` is deliberately absent: a default\n * value there would be indistinguishable from a configured one, and the flat\n * override would then always beat the tiers.\n */\nexport const COMPACTION_DEFAULTS: ResolvedCompactionConfig = {\n enabled: true,\n largeWindowThresholdPercent: 40,\n smallWindowThresholdPercent: 80,\n largeWindowMinTokens: 1_000_000,\n minCooldownMs: 120_000,\n manualCompactEnabled: false,\n};\n\n/** A configured compaction number is used only when it is a finite number above 0. */\nfunction usableCompactionNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\n/**\n * Context fill percentage at which managed compaction fires for a session whose\n * context window is `contextWindow` tokens.\n *\n * Precedence: a configured `thresholdPercent` wins; else a window at or above\n * `largeWindowMinTokens` takes `largeWindowThresholdPercent`, any other window\n * `smallWindowThresholdPercent`. Each value falls back to {@link COMPACTION_DEFAULTS}\n * when it is absent or not a positive number — the YAML block is not validated,\n * and a string or `0` here would otherwise compact on every turn or never.\n *\n * Tiered on the window, not the model id: the window is what the cost scales\n * with, and the runner already folds 1M model aliases into it.\n */\nexport function resolveCompactionThresholdPercent(\n contextWindow: number,\n config: CompactionConfig = {},\n): number {\n if (usableCompactionNumber(config.thresholdPercent)) return config.thresholdPercent;\n const largeWindowMinTokens = usableCompactionNumber(config.largeWindowMinTokens)\n ? config.largeWindowMinTokens\n : COMPACTION_DEFAULTS.largeWindowMinTokens;\n if (contextWindow >= largeWindowMinTokens) {\n return usableCompactionNumber(config.largeWindowThresholdPercent)\n ? config.largeWindowThresholdPercent\n : COMPACTION_DEFAULTS.largeWindowThresholdPercent;\n }\n return usableCompactionNumber(config.smallWindowThresholdPercent)\n ? config.smallWindowThresholdPercent\n : COMPACTION_DEFAULTS.smallWindowThresholdPercent;\n}\n\n// ── Deprecated type aliases ───────────────────────────────────────────────────\n\n/** @deprecated Use AgentConfigProfile */\nexport interface RuntimeDefaults {\n framework?: string;\n driver?: string;\n provider?: string;\n model?: string;\n skills_dir?: string;\n agents_dir?: string;\n prompts_dir?: string;\n}\n\n/** @deprecated Use AiResourceEntry[] */\nexport interface AiResourcesConfig {\n sources?: AiResourceSource[];\n requires?: string[];\n auto_deploy?: boolean;\n}\n\n/** @deprecated Use AiResourceEntry */\nexport interface AiResourceSource {\n name: string;\n path: string;\n branch?: string;\n}\n\n// ── Config file info ──────────────────────────────────────────────────────────\n\nexport interface SkWorkspaceConfigFile {\n /** Absolute path to the config file. */\n path: string;\n /** Workspace name (extracted from filename). */\n name: string;\n /** Parsed config. */\n config: SkWorkspaceConfig;\n /**\n * Diagnostics from decoding this file — legacy-shape warnings (camelCase keys,\n * flat agent-config, the old ai_resources object) and unrecognized\n * driver/provider/access values. Absent on configs synthesized in-memory.\n */\n diagnostics?: Diagnostic[];\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────────\n\n/** Suffix for named workspace configs: `<name>.skaile.yaml` */\nexport const SKAILE_YAML_SUFFIX = \".skaile.yaml\";\n/** Filename for the default workspace config when no name is given. */\nexport const SKAILE_YAML_DEFAULT = \"skaile.yaml\";\n\n/** @deprecated Use SKAILE_YAML_SUFFIX */\nexport const SK_WORKSPACE_SUFFIX = SKAILE_YAML_SUFFIX;\n/** @deprecated Use SKAILE_YAML_DEFAULT */\nexport const SK_WORKSPACE_DEFAULT_NAME = \"default\";\n\n// ── Config I/O ────────────────────────────────────────────────────────────────\n\n/**\n * Return the canonical filename for a workspace config.\n * The default workspace resolves to `\"skaile.yaml\"`; named workspaces resolve to\n * `\"<name>.skaile.yaml\"`.\n *\n * @param name - Optional workspace name (omit or pass `\"default\"` for the primary config)\n * @returns Filename string (not a full path)\n * @docLink packages/core/workspace-config#workspace-config-filename\n */\nexport function workspaceConfigFilename(name?: string): string {\n if (!name || name === \"default\") return SKAILE_YAML_DEFAULT;\n return `${name}${SKAILE_YAML_SUFFIX}`;\n}\n\n/**\n * Return `true` if `filename` matches the workspace config naming convention\n * (`\"skaile.yaml\"` or any `\"*.skaile.yaml\"`).\n *\n * @param filename - Bare filename (no directory component)\n * @docLink packages/core/workspace-config#is-workspace-config-filename\n */\nexport function isWorkspaceConfigFilename(filename: string): boolean {\n return filename === SKAILE_YAML_DEFAULT || filename.endsWith(SKAILE_YAML_SUFFIX);\n}\n\n/**\n * Extract the workspace name from a config filename.\n * `\"skaile.yaml\"` → `\"default\"`, `\"staging.skaile.yaml\"` → `\"staging\"`.\n *\n * @param filename - Bare filename produced by `workspaceConfigFilename`\n * @returns Workspace name string\n * @docLink packages/core/workspace-config#workspace-name-from-filename\n */\nexport function workspaceNameFromFilename(filename: string): string {\n if (filename === SKAILE_YAML_DEFAULT) return \"default\";\n return filename.slice(0, -SKAILE_YAML_SUFFIX.length);\n}\n\n/**\n * Load a single workspace config file from `dir`.\n * When `name` is omitted and no `skaile.yaml` exists, falls back to the sole\n * `*.skaile.yaml` file in the directory if exactly one is present.\n *\n * @param dir - Directory to search for the config file\n * @param name - Optional workspace name (omit for the default `skaile.yaml`)\n * @returns Parsed config file info, or `null` if no matching file was found\n * @docLink packages/core/workspace-config#load-sk-workspace-config\n */\nexport function loadSkWorkspaceConfig(dir: string, name?: string): SkWorkspaceConfigFile | null {\n return loadConfigFile(dir, name, false);\n}\n\n/**\n * Shared body of {@link loadSkWorkspaceConfig}. With `strict`, a file that does not parse\n * (bad YAML, a duplicate key, a non-mapping root) throws {@link configParseError} instead of\n * reading as \"no config\".\n */\nfunction loadConfigFile(\n dir: string,\n name: string | undefined,\n strict: boolean,\n absolute = false,\n): SkWorkspaceConfigFile | null {\n const resolvedDir = resolve(dir);\n const canonicalName = name && name !== \"default\" ? name : undefined;\n\n const filename = workspaceConfigFilename(canonicalName);\n const filePath = join(resolvedDir, filename);\n if (existsSync(filePath)) {\n return parseConfigFile(\n filePath,\n canonicalName ?? \"default\",\n strict ? (absolute ? filePath : filename) : undefined,\n );\n }\n\n if (!canonicalName) {\n const found = listConfigFiles(resolvedDir, strict, absolute);\n if (found.length === 1) return found[0]!;\n }\n\n return null;\n}\n\n/**\n * Serialize and write a workspace config to `dir`, creating the directory if needed.\n *\n * @param dir - Target directory (created recursively if absent)\n * @param config - Config object to serialize as YAML\n * @param name - Optional workspace name (omit for the default `skaile.yaml`)\n * @returns Absolute path of the written file\n * @docLink packages/core/workspace-config#save-sk-workspace-config\n */\nexport function saveSkWorkspaceConfig(\n dir: string,\n config: SkWorkspaceConfig,\n name?: string,\n): string {\n const resolvedDir = resolve(dir);\n const filename = workspaceConfigFilename(name);\n const filePath = join(resolvedDir, filename);\n\n if (!existsSync(resolvedDir)) {\n mkdirSync(resolvedDir, { recursive: true });\n }\n\n writeFileSync(filePath, encodeSkaileYaml(config));\n return filePath;\n}\n\n/**\n * List all workspace config files present in `dir`, sorted alphabetically by name.\n * Returns an empty array when `dir` does not exist or is unreadable.\n *\n * @param dir - Directory to scan for `skaile.yaml` and `*.skaile.yaml` files\n * @returns Array of parsed config file descriptors\n * @docLink packages/core/workspace-config#list-sk-workspace-configs\n */\nexport function listSkWorkspaceConfigs(dir: string): SkWorkspaceConfigFile[] {\n return listConfigFiles(dir, false);\n}\n\n/** Shared body of {@link listSkWorkspaceConfigs}; `strict` throws for a file that does not parse. */\nfunction listConfigFiles(dir: string, strict: boolean, absolute = false): SkWorkspaceConfigFile[] {\n const resolvedDir = resolve(dir);\n if (!existsSync(resolvedDir)) return [];\n\n let entries: string[] = [];\n try {\n entries = readdirSync(resolvedDir);\n } catch {\n /* unreadable dir */\n }\n\n const configs: SkWorkspaceConfigFile[] = [];\n for (const entry of entries) {\n if (!isWorkspaceConfigFilename(entry)) continue;\n const parsed = parseConfigFile(\n join(resolvedDir, entry),\n workspaceNameFromFilename(entry),\n strict ? (absolute ? join(resolvedDir, entry) : entry) : undefined,\n );\n if (parsed) configs.push(parsed);\n }\n\n return configs.sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * The error {@link resolveSkWorkspaceConfig} throws for a config file that does not parse:\n * one line, `<file> — parse error: <reason>`, the same shape `skaile validate` prints. The\n * YAML library's source excerpt below its first line is dropped.\n */\nfunction configParseError(label: string, d: Diagnostic): Error {\n const reason = (d.message.replace(/^Invalid YAML: /, \"\").split(\"\\n\")[0] ?? \"\").replace(/:$/, \"\");\n return new Error(`${label} — parse error: ${reason}`);\n}\n\n/** The error {@link resolveSkWorkspaceConfig} throws for a rejecting diagnostic. */\nfunction rejectedKeyError(d: Diagnostic): Error {\n return d.code === \"invalid_source_entry\" ? new SourceEntryError(d.message) : new Error(d.message);\n}\n\n/**\n * Resolve the effective workspace config by stacking configs across three scope levels:\n * user (`~/.skaile/`) < app (`opts.appDir`) < project (`projectDir`).\n *\n * Each level's config is merged with `mergeSkWorkspaceConfigs`, with higher-priority\n * scopes winning for scalars and unions applied for arrays (deny lists, directories, etc.).\n * Returns an empty object `{}` when no config files are found. A config file that exists but\n * does not parse (bad YAML, a duplicate key, a non-mapping root) is NOT \"no config\": it throws\n * `<file> — parse error: <reason>`, so no caller reads a broken file as \"nothing declared\".\n *\n * @param projectDir - Root directory of the current project\n * @param opts - Optional overrides: `name` selects a named workspace (default: `\"default\"`),\n * `appDir` inserts an app-level config between user and project scopes\n * @returns Merged effective `SkWorkspaceConfig`\n * @throws {Error} `<file> — parse error: …` when a scope's config file does not parse.\n * @docLink packages/core/workspace-config#resolve-sk-workspace-config\n */\nexport function resolveSkWorkspaceConfig(\n projectDir: string,\n opts?: { name?: string; appDir?: string },\n): SkWorkspaceConfig {\n const name = opts?.name ?? SK_WORKSPACE_DEFAULT_NAME;\n const configs: SkWorkspaceConfig[] = [];\n\n // Surface the legacy-key hard error at the runtime boundary. decodeSkaileYaml\n // stays total (records a `legacy_key_rejected` diagnostic) so editor/preview\n // callers don't crash; the merged-runtime resolver re-throws it here so\n // install / serve fail loudly with the migration hint.\n const assertNoLegacyKey = (file: SkWorkspaceConfigFile | null) => {\n const d = file?.diagnostics?.find(\n (x) => x.code === \"legacy_key_rejected\" || x.code === \"invalid_source_entry\",\n );\n if (d) throw rejectedKeyError(d);\n };\n\n const userConfig = loadConfigFile(globalSkaileDir(), name, true, true);\n assertNoLegacyKey(userConfig);\n if (userConfig) configs.push(userConfig.config);\n\n if (opts?.appDir) {\n const appConfig = loadConfigFile(opts.appDir, name, true, true);\n assertNoLegacyKey(appConfig);\n if (appConfig) configs.push(appConfig.config);\n }\n\n const projectConfig = loadConfigFile(projectDir, name, true);\n assertNoLegacyKey(projectConfig);\n if (projectConfig) configs.push(projectConfig.config);\n\n if (configs.length > 0) return configs.reduce(mergeSkWorkspaceConfigs);\n\n return {};\n}\n\n/**\n * Resolve **only** the user-scope global SSOT (`~/.skaile/skaile.yaml`), without\n * stacking any app/project config. This is the single source of truth for global\n * cross-harness installs (`skaile install --global`). Returns `{}` when the file\n * is absent (edge: no `~/.skaile/skaile.yaml` yet). Re-throws the legacy-key\n * error with the `migrate-skaile-manifest` hint, matching\n * {@link resolveSkWorkspaceConfig}.\n *\n * @returns The normalized user-scope config, or `{}` when absent.\n * @throws {Error} on legacy `repositories:` / `ai_resources:` keys.\n * @docLink packages/core/workspace-config#resolve-global-sk-workspace-config\n */\nexport function resolveGlobalSkWorkspaceConfig(): SkWorkspaceConfig {\n const file = loadConfigFile(globalSkaileDir(), SK_WORKSPACE_DEFAULT_NAME, true, true);\n const legacy = file?.diagnostics?.find(\n (x) => x.code === \"legacy_key_rejected\" || x.code === \"invalid_source_entry\",\n );\n if (legacy) throw rejectedKeyError(legacy);\n return file?.config ?? {};\n}\n\n/**\n * Resolve the set of coding-agent harnesses a global install fans out to:\n * the explicit `global_harnesses:` list from `~/.skaile/skaile.yaml` when set\n * (the legacy `global_backends:` spelling is still read), otherwise every\n * {@link DriverTarget} whose global harness root dir already exists under `~`\n * (auto-detection). May return an empty array when no harness is declared and\n * none is present on disk.\n *\n * @returns Deduplicated, declaration-order list of global harnesses.\n * @throws {Error} on legacy keys in `~/.skaile/skaile.yaml`.\n * @docLink packages/core/workspace-config#resolve-global-harnesses\n */\nexport function resolveGlobalHarnesses(): DriverTarget[] {\n const explicit = resolveGlobalSkWorkspaceConfig().global_harnesses;\n if (explicit && explicit.length > 0) return [...new Set(explicit)];\n return SUPPORTED_DRIVER_TARGETS.filter((t) => existsSync(globalHarnessRoot(t)));\n}\n\n/**\n * Walk upward from `startDir` looking for a `skaile.yaml` (or `*.skaile.yaml`).\n * Returns the directory containing the first match, or `undefined` if none found.\n *\n * Stops after 20 levels to avoid scanning all the way to `/`.\n *\n * @param startDir - Directory to start searching from (usually `process.cwd()`)\n * @returns Absolute path to the workspace root, or `undefined`\n * @docLink packages/core/workspace-config#find-workspace-root\n */\nexport function findWorkspaceRoot(startDir: string): string | undefined {\n let dir = resolve(startDir);\n const root = parsePath(dir).root; // filesystem root (e.g. \"/\" or \"C:\\\\\")\n let depth = 0;\n\n while (depth < 20) {\n if (existsSync(join(dir, SKAILE_YAML_DEFAULT))) return dir;\n // Check for named workspace configs (*.skaile.yaml)\n try {\n for (const entry of readdirSync(dir)) {\n if (entry.endsWith(SKAILE_YAML_SUFFIX)) return dir;\n }\n } catch {\n /* unreadable */\n }\n\n if (dir === root) break;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n depth++;\n }\n return undefined;\n}\n\n// ── Merge logic ───────────────────────────────────────────────────────────────\n\n/**\n * Deep-merge two workspace configs according to stacking rules.\n * `overlay` takes priority over `base` for scalar fields.\n * Arrays use concatenation + deduplication; deny lists always union.\n * Mounts and connectors are merged by `id` (overlay entry wins for same id).\n * Hooks are concatenated in order (base first, overlay appended).\n *\n * @param base - Lower-priority config (e.g. user or app scope)\n * @param overlay - Higher-priority config (e.g. project scope)\n * @returns Merged `SkWorkspaceConfig`\n * @docLink packages/core/workspace-config#merge-sk-workspace-configs\n */\nexport function mergeSkWorkspaceConfigs(\n base: SkWorkspaceConfig,\n overlay: SkWorkspaceConfig,\n): SkWorkspaceConfig {\n return {\n name: overlay.name ?? base.name,\n description: overlay.description ?? base.description,\n\n // agent_config: per-profile key, overlay profile wins\n agent_config: {\n ...(base.agent_config ?? {}),\n ...(overlay.agent_config ?? {}),\n },\n\n // roles: per-role key, overlay wins — a project may redefine `smol`\n // without restating the whole table its user-scope config provides.\n roles: { ...(base.roles ?? {}), ...(overlay.roles ?? {}) },\n\n // startup: overlay wins (project-level only)\n startup: overlay.startup ?? base.startup,\n\n // mounts: by id — overlay wins\n mounts: mergeById(base.mounts ?? [], overlay.mounts ?? []),\n\n // connectors: by id — overlay wins\n connectors: mergeById(base.connectors ?? [], overlay.connectors ?? []),\n\n // mcp_servers: by id — overlay wins\n mcp_servers: mergeById(base.mcp_servers ?? [], overlay.mcp_servers ?? []),\n\n agent: mergeAgentConfig(base.agent, overlay.agent),\n\n workspace: mergeWorkspaceConfig(base.workspace, overlay.workspace),\n\n // secrets: overlay wins entirely\n secrets: overlay.secrets ?? base.secrets,\n\n // telemetry: overlay wins entirely (raw pass-through)\n telemetry: overlay.telemetry ?? base.telemetry,\n\n // dependencies: concatenate and dedupe\n dependencies: dedupe([...(base.dependencies ?? []), ...(overlay.dependencies ?? [])]),\n\n // global_harnesses: user-scope SSOT key — overlay wins entirely\n global_harnesses: overlay.global_harnesses ?? base.global_harnesses,\n\n // sources: dedupe by url — overlay entry wins for the same url\n sources: dedupeByKey([...(base.sources ?? []), ...(overlay.sources ?? [])], \"url\"),\n\n // stores: dedupe by url — overlay wins\n stores: dedupeByKey([...(base.stores ?? []), ...(overlay.stores ?? [])], \"url\"),\n\n // overrides: dedupe by ref — overlay wins\n overrides: dedupeByKey([...(base.overrides ?? []), ...(overlay.overrides ?? [])], \"ref\"),\n\n // plugins: concatenate + dedupe (like dependencies)\n plugins: dedupe([...(base.plugins ?? []), ...(overlay.plugins ?? [])]),\n\n // deploy: overlay wins entirely (scalar-like selection)\n deploy: overlay.deploy ?? base.deploy,\n\n // compaction, patches: per-key, overlay wins — a project can raise one tier\n // without restating the rest. Absent from both stays absent.\n compaction: mergeKeyed(base.compaction, overlay.compaction),\n patches: mergeKeyed(base.patches, overlay.patches),\n\n // logging: per-key, overlay wins; retention per key one level down.\n logging: mergeLoggingConfig(base.logging, overlay.logging),\n };\n}\n\n/** Merge the `logging:` block — per key, with `retention` merged per key too. */\nfunction mergeLoggingConfig(\n base: LoggingConfig | undefined,\n overlay: LoggingConfig | undefined,\n): LoggingConfig | undefined {\n const merged = mergeKeyed(base, overlay);\n if (!merged) return undefined;\n const retention = mergeKeyed(base?.retention, overlay?.retention);\n if (retention) merged.retention = retention;\n return merged;\n}\n\n/** Per-key merge where an overlay key set to `undefined` falls through to the base. */\nfunction mergeKeyed<T extends object>(base: T | undefined, overlay: T | undefined): T | undefined {\n if (!base && !overlay) return undefined;\n const merged: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(overlay ?? {})) {\n if (value !== undefined) merged[key] = value;\n }\n return merged as T;\n}\n\n/** Merge the `agent:` block — scalars overlay-win, deny lists union, hooks concat. */\nfunction mergeAgentConfig(\n base: AgentConfig | undefined,\n overlay: AgentConfig | undefined,\n): AgentConfig {\n return {\n definition: overlay?.definition ?? base?.definition,\n context: overlay?.context ?? base?.context,\n // Whole-block overlay: a partial file list merged across scopes would change caps silently.\n ...((overlay?.home ?? base?.home) ? { home: overlay?.home ?? base?.home } : {}),\n permissions: mergeAgentPermissions(base?.permissions, overlay?.permissions),\n ...((base?.instances ?? overlay?.instances)\n ? { instances: mergeAgentInstances(base?.instances, overlay?.instances) }\n : {}),\n hooks: {\n pre_flow: [...(base?.hooks?.pre_flow ?? []), ...(overlay?.hooks?.pre_flow ?? [])],\n post_flow: [...(base?.hooks?.post_flow ?? []), ...(overlay?.hooks?.post_flow ?? [])],\n pre_node: [...(base?.hooks?.pre_node ?? []), ...(overlay?.hooks?.pre_node ?? [])],\n post_node: [...(base?.hooks?.post_node ?? []), ...(overlay?.hooks?.post_node ?? [])],\n },\n };\n}\n\n/** Merge the `workspace:` block — directories/ignore union, setup/container overlay-win. */\nfunction mergeWorkspaceConfig(\n base: WorkspaceLayoutConfig | undefined,\n overlay: WorkspaceLayoutConfig | undefined,\n): WorkspaceLayoutConfig {\n return {\n directories: dedupe([...(base?.directories ?? []), ...(overlay?.directories ?? [])]),\n git: {\n init: overlay?.git?.init ?? base?.git?.init,\n ignore: dedupe([...(base?.git?.ignore ?? []), ...(overlay?.git?.ignore ?? [])]),\n },\n setup: overlay?.setup ?? base?.setup,\n container: overlay?.container ?? base?.container,\n };\n}\n\n// ── Diagnostics ───────────────────────────────────────────────────────────────\n\n/** Severity of a {@link Diagnostic} produced by {@link decodeSkaileYaml}. */\nexport type DiagnosticSeverity = \"error\" | \"warning\" | \"info\";\n\n/**\n * A structured note about a decoded `skaile.yaml` — a syntax error, a tolerated\n * legacy/non-canonical shape that was normalized, or an unrecognized enum value.\n * {@link decodeSkaileYaml} never throws; it reports problems here so each caller\n * (platform editor, runner, CLI) decides how loud to be.\n */\nexport interface Diagnostic {\n /** Stable machine code, e.g. `\"legacy_key_camelcase\"` / `\"unknown_driver\"`. */\n code: string;\n severity: DiagnosticSeverity;\n /** Human-readable, actionable message. */\n message: string;\n /** Dotted path into the config the note refers to, when applicable. */\n path?: string;\n}\n\n/** Result of {@link decodeSkaileYaml}: the normalized config plus any notes. */\nexport interface DecodeResult {\n config: SkWorkspaceConfig;\n diagnostics: Diagnostic[];\n}\n\n/**\n * Known runtime drivers — mirrors the keys of `DRIVER_DEFAULTS` (framework.ts).\n * Kept local to avoid a settings/framework ↔ workspace-config import cycle; a\n * drift test asserts parity.\n */\nconst KNOWN_DRIVERS = [\"omp\", \"claude-sdk\", \"codex\"] as const;\n\nconst KNOWN_ACCESS = [\"read-only\", \"read-write\"] as const;\n\n/** Valid launcher strategies for a local (stdio) MCP server. */\nconst KNOWN_LAUNCHERS = [\"recipe\", \"package-runner\", \"path\"] as const;\n// Runtime transport literals the runner's external-mcp switch branches on.\n// \"streamable-http\" is an MCP-spec alias normalized to \"http\" before this check.\nconst KNOWN_TRANSPORTS = [\"stdio\", \"sse\", \"http\"] as const;\n\n// ── Raw → canonical normalization ─────────────────────────────────────────────\n\n/**\n * Scalar fields that identify a flat (un-profiled) agent-config block.\n *\n * `provider` and `cloud` are rejected keys, not schema fields — they stay in\n * this list so a flat legacy block (`agent-config: {provider: anthropic}`) is\n * still recognized as a profile and reaches the guard that names\n * `skaile migrate providers`, instead of being read as a profile named\n * \"provider\".\n */\nconst AGENT_PROFILE_FIELDS = [\n \"driver\",\n \"provider\",\n \"cloud\",\n \"model\",\n \"thinking\",\n \"effort\",\n \"skills_dir\",\n \"agents_dir\",\n \"prompts_dir\",\n] as const;\n\n/**\n * Coerce a raw agent-config block into the canonical profile-map shape\n * (`{ default: {...}, … }`).\n *\n * Accepts two authoring shapes:\n * - **Profile map** (canonical): `{ default: { driver, model }, staging: {…} }`\n * - **Flat profile**: `{ driver, model, provider }` — emitted by clients that\n * serialize a runtime config object straight to YAML. Wrapped as the\n * `default` profile so `settingsFromWorkspaceConfig` finds it.\n *\n * `wrappedFlat` reports whether a flat block was wrapped, so the caller can emit\n * a diagnostic. A block is flat when any known profile field is present as a\n * scalar; a profile named e.g. `driver` carries an object value, so the scalar\n * check disambiguates.\n */\nfunction normalizeAgentConfig(raw: Record<string, unknown>): {\n profiles: Record<string, AgentConfigProfile>;\n wrappedFlat: boolean;\n} {\n const looksFlat = AGENT_PROFILE_FIELDS.some((f) => typeof raw[f] === \"string\");\n return looksFlat\n ? { profiles: { default: raw as AgentConfigProfile }, wrappedFlat: true }\n : { profiles: raw as Record<string, AgentConfigProfile>, wrappedFlat: false };\n}\n\n/**\n * Normalize a raw parsed YAML object into the canonical SkWorkspaceConfig shape.\n * Pure structural pass; see {@link decodeSkaileYaml} for the diagnostics-aware\n * entry point. Tolerates backward-compatible fields:\n * - `agent-config` (hyphen) / `agent_config` (underscore) / `agentConfig` (camelCase) → `agent_config`\n * - flat agent-config (`{ driver, model }`) → `{ default: { driver, model } }`\n *\n * Hard cut: legacy top-level keys `repositories:` and `ai_resources:` (any case)\n * now throw — the migration is performed by the `migrate-skaile-manifest` skill.\n * @docLink packages/core/workspace-config#normalize-config\n */\nexport function normalizeConfig(raw: Record<string, unknown>): SkWorkspaceConfig {\n return normalizeConfigInternal(raw).config;\n}\n\n/**\n * Endpoint/credential keys a committed `skaile.yaml` may never carry (§1.6).\n *\n * Rejected at the top level and inside an `agent-config` profile — the two\n * scopes where they would describe the *session's* AI provider. They are not\n * reserved words everywhere: `mcp_servers[].transport` and\n * `mcp_servers[].headers` are unrelated fields of a different noun and keep\n * working.\n */\nconst RESERVED_PROVIDER_KEYS = [\n \"providers\",\n \"base_url\",\n \"credential\",\n \"headers\",\n \"query_params\",\n \"transport\",\n] as const;\n\n/** The one instruction every rejection message ends with. */\nconst MIGRATE_PROVIDERS_HINT =\n \"run `skaile migrate providers` — it rewrites this file into \" +\n \"`model: <providerId>/<modelId>` and moves the endpoint definition into \" +\n \"~/.skaile/providers.yml\";\n\n/**\n * Reject the endpoint-definition keys in one `agent-config` profile.\n *\n * Hard cutover, no warning period (decision §9.6): `provider:` and `cloud:`\n * selected an endpoint out of a hardcoded axis that no longer exists, and a\n * committed `base_url:` next to a platform-injected credential is an\n * exfiltration primitive. The replacement is one selector plus a registry\n * entry, and `skaile migrate providers` writes both.\n */\nfunction assertNoProviderDefinitionKeys(profile: string, raw: Record<string, unknown>): void {\n const path = `agent-config.${profile}`;\n if (raw.provider !== undefined) {\n throw new Error(\n `skaile.yaml: \\`${path}.provider\\` is no longer valid — a model is selected with ` +\n \"one namespaced string, `model: <providerId>/<modelId>` (or a bare model id, or \" +\n `\\`@role\\`), against the providers defined in providers.yml. To convert this file, ` +\n `${MIGRATE_PROVIDERS_HINT}.`,\n );\n }\n for (const key of [\"cloud\", \"cloud_config\", \"cloudConfig\"] as const) {\n if (raw[key] !== undefined) {\n throw new Error(\n `skaile.yaml: \\`${path}.${key}\\` is no longer valid — the transport is an AI provider ` +\n \"registry entry now (`transport:` + `params:` in providers.yml), not a per-profile \" +\n `axis. To convert this file, ${MIGRATE_PROVIDERS_HINT}.`,\n );\n }\n }\n for (const key of RESERVED_PROVIDER_KEYS) {\n if (raw[key] !== undefined) {\n throw new Error(\n `skaile.yaml: \\`${path}.${key}\\` is a reserved AI provider registry key and cannot be ` +\n \"set in a committed workspace config — endpoints and credentials are defined in \" +\n `providers.yml, which skaile.yaml only selects from. To convert this file, ` +\n `${MIGRATE_PROVIDERS_HINT}.`,\n );\n }\n }\n}\n\n/**\n * Normalize the `agent-config` block (hyphen/underscore/camelCase key + flat\n * single-profile shape) onto `config.agent_config`, recording warnings for\n * non-canonical shapes. No-op when no recognized key is present.\n *\n * Throws on a profile that still defines a provider/endpoint — see\n * {@link assertNoProviderDefinitionKeys}.\n */\nfunction normalizeAgentConfigSection(\n raw: Record<string, unknown>,\n config: SkWorkspaceConfig,\n diagnostics: Diagnostic[],\n): void {\n // agent_config: accept hyphen (canonical), underscore, or camelCase, plus a\n // flat single-profile block. Non-canonical shapes are normalized + flagged.\n let agentConfigRaw: unknown;\n let agentConfigKey: string | undefined;\n if (raw[\"agent-config\"] !== undefined) {\n agentConfigRaw = raw[\"agent-config\"];\n agentConfigKey = \"agent-config\";\n } else if (raw.agent_config !== undefined) {\n agentConfigRaw = raw.agent_config;\n agentConfigKey = \"agent_config\";\n } else if (raw.agentConfig !== undefined) {\n agentConfigRaw = raw.agentConfig;\n agentConfigKey = \"agentConfig\";\n }\n if (!agentConfigRaw || typeof agentConfigRaw !== \"object\" || Array.isArray(agentConfigRaw)) {\n return;\n }\n if (agentConfigKey === \"agentConfig\") {\n diagnostics.push({\n code: \"legacy_key_camelcase\",\n severity: \"warning\",\n message: 'Non-canonical key \"agentConfig\" — use \"agent-config\".',\n path: \"agentConfig\",\n });\n }\n const { profiles, wrappedFlat } = normalizeAgentConfig(agentConfigRaw as Record<string, unknown>);\n if (wrappedFlat) {\n diagnostics.push({\n code: \"legacy_agent_config_flat\",\n severity: \"warning\",\n message:\n 'Flat agent-config block wrapped as the \"default\" profile — nest fields under \"default:\".',\n path: agentConfigKey,\n });\n }\n for (const [name, profile] of Object.entries(profiles)) {\n if (profile && typeof profile === \"object\" && !Array.isArray(profile)) {\n assertNoProviderDefinitionKeys(name, profile as unknown as Record<string, unknown>);\n }\n }\n config.agent_config = profiles;\n}\n\n/**\n * Normalize the top-level `roles:` table (§9.8). Non-string targets are\n * dropped with a warning rather than failing the file: a role is an alias, and\n * a broken alias must not take the workspace down — `parseModelRef` applies\n * the same leniency to a target that names a provider this machine lacks.\n */\nfunction normalizeRolesSection(\n raw: Record<string, unknown>,\n config: SkWorkspaceConfig,\n diagnostics: Diagnostic[],\n): void {\n if (!raw.roles || typeof raw.roles !== \"object\" || Array.isArray(raw.roles)) {\n if (raw.roles !== undefined) {\n diagnostics.push({\n code: \"invalid_roles\",\n severity: \"warning\",\n message: \"`roles:` must be a map of role name → model selector — ignoring it.\",\n path: \"roles\",\n });\n }\n return;\n }\n const roles: Record<string, string> = {};\n for (const [role, target] of Object.entries(raw.roles as Record<string, unknown>)) {\n if (typeof target === \"string\" && target.trim().length > 0) {\n roles[role] = target.trim();\n continue;\n }\n diagnostics.push({\n code: \"invalid_role_target\",\n severity: \"warning\",\n message: `roles.${role} must be a model selector string (\"<providerId>/<modelId>\" or a bare model id) — ignoring it.`,\n path: `roles.${role}`,\n });\n }\n if (Object.keys(roles).length > 0) config.roles = roles;\n}\n\n// Absolute on purpose: `docs/` is not in the published `files` list and the\n// skill lives in `skaile-ai/ai-assets`, so bare names resolve to nothing for an\n// npm consumer. Keep the literal substrings — tests and the docs grep for them.\nconst MANIFEST_SCHEMA_DOC_URL =\n \"https://github.com/skaile-ai/workspaces/blob/main/docs/concepts/manifest-schema.md\";\nconst MIGRATE_SKILL_HINT =\n \"ask your AI assistant to apply the `migrate-skaile-manifest` skill \" +\n \"(published from https://github.com/skaile-ai/ai-assets)\";\n\n/**\n * Hard-cut guard for legacy/migrated top-level keys. `repositories:` /\n * `ai_resources:` were removed with the canonical-identity schema; `publisher:` /\n * `version:` / `assets:` are publication keys that moved to `skaile.manifest.yaml`\n * (2026-06-03 split). All throw with the spec wording — the migration is done by\n * the `migrate-skaile-manifest` skill, not code. decodeSkaileYaml catches the\n * throw and records a single `legacy_key_rejected` diagnostic (the message\n * carries the specifics); resolveSkWorkspaceConfig re-throws it at the runtime\n * boundary.\n *\n * Consumer-facing migration guidance lives in `docs/migration-v2-to-v3.md` and\n * the root `MIGRATION.md`; both quote these strings verbatim so they are\n * greppable from a failing session.\n */\nfunction assertNoLegacyTopLevelKeys(raw: Record<string, unknown>): void {\n if (raw.repositories !== undefined) {\n throw new Error(\n \"skaile.yaml: unknown top-level key `repositories:`. The schema changed — \" +\n \"replace it with `sources:`, a list of `{url, pin?}`. See \" +\n `${MANIFEST_SCHEMA_DOC_URL}, or ${MIGRATE_SKILL_HINT}.`,\n );\n }\n if (raw.ai_resources !== undefined || raw.aiResources !== undefined) {\n throw new Error(\n \"skaile.yaml: unknown top-level key `ai_resources:`. The schema changed — \" +\n \"replace it with `dependencies:` (canonical refs) plus the `sources:` / \" +\n \"`stores:` that resolve them. See \" +\n `${MANIFEST_SCHEMA_DOC_URL}, or ${MIGRATE_SKILL_HINT}.`,\n );\n }\n for (const key of [\"publisher\", \"version\", \"assets\"] as const) {\n if (raw[key] !== undefined) {\n throw new Error(\n `skaile.yaml: \\`${key}:\\` is no longer valid here — publication keys ` +\n \"(publisher, version, assets) describe what a repo publishes and now live in \" +\n `skaile.manifest.yaml. See ${MANIFEST_SCHEMA_DOC_URL}, or ${MIGRATE_SKILL_HINT}.`,\n );\n }\n }\n for (const key of RESERVED_PROVIDER_KEYS) {\n if (raw[key] !== undefined) {\n throw new Error(\n `skaile.yaml: \\`${key}:\\` is a reserved AI provider registry key and cannot be a ` +\n \"top-level key — endpoints, credentials and headers are defined in providers.yml \" +\n \"(`~/.skaile/providers.yml`, or `<workspace>/.skaile/providers.yml` for a \" +\n `project-local override), which skaile.yaml only selects from. To convert this file, ` +\n `${MIGRATE_PROVIDERS_HINT}.`,\n );\n }\n }\n if (isRecord(raw.agent) && raw.agent.subagents !== undefined) {\n throw new Error(\n \"skaile.yaml: `agent.subagents:` was removed — inline prompt-only subagents had no driver \" +\n \"consumer. Declare each one as an agent asset (`.skaile/agents/<name>/agent.yaml`) and \" +\n \"bind it under the root `agents:` map (`agents.<name>: { ref: ./.skaile/agents/<name>, \" +\n \"lifecycle: role }`). See MIGRATION.md.\",\n );\n }\n}\n\n/** Normalize a single raw `overrides[]` item into an OverrideEntry, or `null` to skip. */\nfunction normalizeOverrideEntry(item: unknown): OverrideEntry | null {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return null;\n const o = item as Record<string, unknown>;\n const ref = typeof o.ref === \"string\" ? o.ref : \"\";\n const source = typeof o.source === \"string\" ? o.source : \"\";\n if (!ref || !source) return null;\n if (typeof o.reason !== \"string\") {\n throw new Error(\n `skaile.yaml: overrides[] entry for ${ref}: reason is required ` +\n \"and must be a non-empty string.\",\n );\n }\n if (o.reason.trim().length === 0) {\n throw new Error(`skaile.yaml: overrides[] entry for ${ref}: reason must not be empty.`);\n }\n return { ref, source, reason: o.reason };\n}\n\n/** Normalize the consumption-half `stores[]` array onto `config`. */\nfunction normalizeStoresSection(raw: Record<string, unknown>, config: SkWorkspaceConfig): void {\n if (!Array.isArray(raw.stores)) return;\n const entries: StoreEntry[] = [];\n for (const item of raw.stores) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n const s = item as Record<string, unknown>;\n const url = typeof s.url === \"string\" ? s.url : \"\";\n if (!url) continue;\n entries.push({ url });\n }\n if (entries.length > 0) config.stores = entries;\n}\n\n/** Normalize the consumption-half `overrides[]` array onto `config`. */\nfunction normalizeOverridesSection(raw: Record<string, unknown>, config: SkWorkspaceConfig): void {\n if (!Array.isArray(raw.overrides)) return;\n const entries: OverrideEntry[] = [];\n for (const item of raw.overrides) {\n const entry = normalizeOverrideEntry(item);\n if (entry) entries.push(entry);\n }\n if (entries.length > 0) config.overrides = entries;\n}\n\n/** Normalize the consumption-half `stores[]` and `overrides[]` arrays. */\nfunction normalizeConsumptionSection(\n raw: Record<string, unknown>,\n config: SkWorkspaceConfig,\n): void {\n normalizeStoresSection(raw, config);\n normalizeOverridesSection(raw, config);\n}\n\n/**\n * Normalize the `agent:` block (tolerant cast) and the root `agents:` instance\n * map, which is stored as `agent.instances`. `agents.default` next to\n * `agent.definition` is an `agent_default_conflict` error.\n */\nfunction normalizeAgentSection(\n raw: Record<string, unknown>,\n config: SkWorkspaceConfig,\n diagnostics: Diagnostic[],\n): void {\n if (raw.agent) {\n config.agent = (isRecord(raw.agent) ? { ...raw.agent } : raw.agent) as AgentConfig;\n }\n diagnostics.push(...agentBlockKeyDiagnostics(raw.agent));\n if (config.agent?.instances !== undefined) {\n diagnostics.push({\n code: \"misplaced_agent_instances\",\n severity: \"error\",\n message:\n \"`agent.instances` is not a skaile.yaml key — declare instances under root `agents:`.\",\n path: \"agent.instances\",\n });\n delete config.agent.instances;\n }\n const instances = normalizeAgentInstances(raw.agents, diagnostics);\n if (instances) config.agent = { ...config.agent, instances };\n diagnostics.push(...agentInstanceDiagnostics(config));\n}\n\n/**\n * Normalize the tolerantly-cast sections (mounts, connectors, mcp_servers,\n * plugins, deploy, agent, workspace, secrets, compaction, patches). Structural\n * validation is deferred — the runtime tolerates unexpected shapes.\n */\nfunction normalizeStructuralSections(\n raw: Record<string, unknown>,\n config: SkWorkspaceConfig,\n diagnostics: Diagnostic[],\n): void {\n if (Array.isArray(raw.mounts)) {\n config.mounts = raw.mounts as MountDeclaration[];\n }\n // connectors: no data_resources fallback — clean break\n if (Array.isArray(raw.connectors)) {\n config.connectors = raw.connectors as ConnectorDeclaration[];\n }\n if (Array.isArray(raw.mcp_servers)) {\n // Strip unknown launcher values at parse time so they never reach the runner.\n // A warning diagnostic is emitted for each stripped entry (mirroring unknown_driver/access).\n config.mcp_servers = (raw.mcp_servers as McpServerDeclaration[]).map((entry) => {\n if (\n entry.launcher !== undefined &&\n !(KNOWN_LAUNCHERS as readonly string[]).includes(entry.launcher)\n ) {\n diagnostics.push({\n code: \"unknown_launcher\",\n severity: \"warning\",\n message: `Unknown launcher \"${entry.launcher}\" on mcp_servers entry \"${entry.id}\" — expected one of: ${KNOWN_LAUNCHERS.join(\", \")}.`,\n path: `mcp_servers.${entry.id}.launcher`,\n });\n const { launcher: _dropped, ...rest } = entry;\n return rest as McpServerDeclaration;\n }\n return entry;\n });\n }\n if (Array.isArray(raw.plugins)) {\n const specs = raw.plugins.filter((p): p is string => typeof p === \"string\" && p.length > 0);\n if (specs.length > 0) config.plugins = specs;\n }\n // deploy: structural only — the target id is resolved/validated against\n // pluginRegistry at deploy time, not here. A block missing a string target is\n // dropped silently (mirrors connectors' tolerant cast).\n if (raw.deploy && typeof raw.deploy === \"object\" && !Array.isArray(raw.deploy)) {\n const d = raw.deploy as Record<string, unknown>;\n if (typeof d.target === \"string\" && d.target.length > 0) {\n config.deploy = { target: d.target };\n if (d.config !== undefined) config.deploy.config = d.config;\n }\n }\n normalizeAgentSection(raw, config, diagnostics);\n if (raw.workspace) config.workspace = raw.workspace as WorkspaceLayoutConfig;\n if (raw.secrets && typeof raw.secrets === \"object\") {\n config.secrets = raw.secrets as SecretsConfig;\n }\n if (raw.compaction && typeof raw.compaction === \"object\" && !Array.isArray(raw.compaction)) {\n config.compaction = raw.compaction as CompactionConfig;\n }\n if (raw.patches && typeof raw.patches === \"object\" && !Array.isArray(raw.patches)) {\n config.patches = raw.patches as Record<string, string>;\n }\n const logging = normalizeLoggingSection(raw.logging, diagnostics);\n if (logging) config.logging = logging;\n}\n\n/**\n * Normalize the `logging:` block. An unknown `mode` or `level` is dropped with a\n * warning: the runner's log-store resolver throws on one, and a typo in this\n * block must not stop the session from starting.\n */\nfunction normalizeLoggingSection(\n raw: unknown,\n diagnostics: Diagnostic[],\n): LoggingConfig | undefined {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return undefined;\n const block = raw as Record<string, unknown>;\n const logging: LoggingConfig = {};\n const pick = <T extends string>(key: \"mode\" | \"level\", known: Record<T, true>): T | undefined => {\n const value = block[key];\n if (value === undefined) return undefined;\n if (typeof value === \"string\" && Object.hasOwn(known, value)) return value as T;\n diagnostics.push({\n code: `unknown_log_${key}`,\n severity: \"warning\",\n message: `Unknown logging.${key} \"${String(value)}\" — expected one of: ${Object.keys(known).join(\", \")}. The default is used.`,\n path: `logging.${key}`,\n });\n return undefined;\n };\n const mode = pick(\"mode\", KNOWN_LOG_MODES);\n if (mode) logging.mode = mode;\n const level = pick(\"level\", KNOWN_LOG_LEVELS);\n if (level) logging.level = level;\n const retention = normalizeLogRetention(block.retention, diagnostics);\n if (retention) logging.retention = retention;\n return Object.keys(logging).length > 0 ? logging : undefined;\n}\n\n/**\n * Keep each retention limit that passes `isRetentionValue`, the rule\n * `resolveLogsRetention` applies. Any other value is dropped with a warning, so\n * the runner falls back to the platform default for that limit.\n */\nfunction normalizeLogRetention(\n raw: unknown,\n diagnostics: Diagnostic[],\n): LogStoreRetention | undefined {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return undefined;\n const block = raw as Record<string, unknown>;\n const retention: LogStoreRetention = {};\n for (const key of [\"maxEntries\", \"maxAgeDays\"] as const) {\n const value = block[key];\n if (value === undefined) continue;\n if (isRetentionValue(value)) {\n retention[key] = value;\n continue;\n }\n diagnostics.push({\n code: \"invalid_log_retention\",\n severity: \"warning\",\n message: `Invalid logging.retention.${key} ${JSON.stringify(value)} — expected a number of 0 or more. The default is used.`,\n path: `logging.retention.${key}`,\n });\n }\n return Object.keys(retention).length > 0 ? retention : undefined;\n}\n\n/** Normalize `dependencies[]`, `sources[]`, and the raw `telemetry` pass-through. */\nfunction normalizeDependencySection(raw: Record<string, unknown>, config: SkWorkspaceConfig): void {\n if (Array.isArray(raw.dependencies)) {\n config.dependencies = raw.dependencies.filter((d): d is string => typeof d === \"string\");\n }\n\n // global_harnesses: accept underscore or hyphen. The pre-4.34 spellings\n // `global_backends` / `global-backends` still parse (read-only; the canonical\n // write is `global_harnesses`). Keep only known DriverTargets — an unknown id\n // is dropped here; `resolveGlobalHarnesses` additionally falls back to\n // auto-detection when the result is empty.\n const rawHarnesses =\n raw.global_harnesses ??\n raw[\"global-harnesses\"] ??\n raw.global_backends ??\n raw[\"global-backends\"];\n if (Array.isArray(rawHarnesses)) {\n const valid = rawHarnesses.filter((b): b is DriverTarget =>\n (SUPPORTED_DRIVER_TARGETS as string[]).includes(b as string),\n );\n if (valid.length > 0) config.global_harnesses = [...new Set(valid)];\n }\n\n if (Array.isArray(raw.sources)) {\n const entries = parseSourceEntries(raw.sources);\n if (entries.length > 0) config.sources = entries;\n }\n\n // telemetry: pass through raw — parsed by @skaile/workspaces/telemetry\n if (raw.telemetry && typeof raw.telemetry === \"object\" && !Array.isArray(raw.telemetry)) {\n config.telemetry = raw.telemetry as Record<string, unknown>;\n }\n}\n\n/** Diagnostics-collecting core of {@link normalizeConfig}. */\nfunction normalizeConfigInternal(raw: Record<string, unknown>): DecodeResult {\n const config: SkWorkspaceConfig = {};\n const diagnostics: Diagnostic[] = [];\n\n // Reject before normalizing anything: a file carrying a removed key gets one\n // actionable error, not a half-decoded config plus an error.\n assertNoLegacyTopLevelKeys(raw);\n\n if (raw.name) config.name = String(raw.name);\n if (raw.description) config.description = String(raw.description);\n\n normalizeAgentConfigSection(raw, config, diagnostics);\n normalizeRolesSection(raw, config, diagnostics);\n\n if (Array.isArray(raw.startup)) {\n config.startup = raw.startup as StartupDirective[];\n }\n\n normalizeConsumptionSection(raw, config);\n normalizeStructuralSections(raw, config, diagnostics);\n normalizeDependencySection(raw, config);\n\n return { config, diagnostics };\n}\n\n// ── Codec (decode / encode) ────────────────────────────────────────────────────\n\n/**\n * Decode `skaile.yaml` text into a normalized {@link SkWorkspaceConfig} plus\n * {@link Diagnostic}s. Total — never throws: a YAML syntax error or a non-object\n * root is reported as an `error`-severity diagnostic with an empty config.\n * Legacy/non-canonical shapes (camelCase keys, flat agent-config, the old\n * ai_resources object) are normalized and reported as `warning`s; unrecognized\n * driver/provider/access values are reported as `warning`s too.\n *\n * Pair with {@link encodeSkaileYaml} for round-tripping. The round-trip is\n * canonical-lossless on the typed model (`decode(encode(config)).config` deep-\n * equals `config`) but does not preserve comments or key order — use\n * `WorkspaceYamlEditor` for comment-preserving in-place edits.\n * @docLink packages/core/workspace-config#decode-skaile-yaml\n */\nexport function decodeSkaileYaml(text: string): DecodeResult {\n let parsed: unknown;\n try {\n parsed = parse(text) ?? {};\n } catch (err) {\n return {\n config: {},\n diagnostics: [\n {\n code: \"yaml_syntax\",\n severity: \"error\",\n message: `Invalid YAML: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n };\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return {\n config: {},\n diagnostics: [\n {\n code: \"non_object_root\",\n severity: \"error\",\n message: \"skaile.yaml must be a mapping at the top level.\",\n },\n ],\n };\n }\n // normalizeConfigInternal hard-throws on legacy keys (repositories:/ai_resources:).\n // decodeSkaileYaml is total by contract, so convert that throw into an\n // `error`-severity diagnostic for editor/preview callers.\n let result: DecodeResult;\n try {\n result = normalizeConfigInternal(parsed as Record<string, unknown>);\n } catch (err) {\n return {\n config: {},\n diagnostics: [\n {\n // A url-less `sources:` item is its own code so the runtime boundary can re-throw\n // the typed error the CLI prints as one line.\n code: err instanceof SourceEntryError ? \"invalid_source_entry\" : \"legacy_key_rejected\",\n severity: \"error\",\n message: err instanceof Error ? err.message : String(err),\n },\n ],\n };\n }\n validateConfigValues(result.config, result.diagnostics);\n return result;\n}\n\n/**\n * Encode a {@link SkWorkspaceConfig} to canonical `skaile.yaml` text:\n * deterministic key order, the hyphenated `agent-config` key, only defined\n * fields. This is the single sanctioned writer — clients should build a typed\n * config and encode it here rather than hand-serializing YAML.\n * @docLink packages/core/workspace-config#encode-skaile-yaml\n */\nexport function encodeSkaileYaml(config: SkWorkspaceConfig): string {\n return stringify(toCanonicalObject(config), { lineWidth: 120 });\n}\n\n/** Append `warning` diagnostics for unrecognized driver/access values. */\nfunction validateConfigValues(config: SkWorkspaceConfig, diagnostics: Diagnostic[]): void {\n for (const [profile, p] of Object.entries(config.agent_config ?? {})) {\n if (p?.driver && !(KNOWN_DRIVERS as readonly string[]).includes(p.driver)) {\n diagnostics.push({\n code: \"unknown_driver\",\n severity: \"warning\",\n message: `Unknown driver \"${p.driver}\" — expected one of: ${KNOWN_DRIVERS.join(\", \")}.`,\n path: `agent-config.${profile}.driver`,\n });\n }\n }\n const checkAccess = (access: string | undefined, path: string) => {\n if (access && !(KNOWN_ACCESS as readonly string[]).includes(access)) {\n diagnostics.push({\n code: \"unknown_access\",\n severity: \"warning\",\n message: `Unknown access \"${access}\" — expected \"read-only\" or \"read-write\".`,\n path,\n });\n }\n };\n for (const c of config.connectors ?? []) {\n checkAccess(c.access, `connectors.${c.id}.access`);\n if (typeof c.driver !== \"string\" || c.driver === \"\") {\n const legacy = (c as unknown as Record<string, unknown>).adapter;\n diagnostics.push({\n code: \"connector_missing_driver\",\n severity: \"error\",\n message:\n legacy !== undefined\n ? `Connector \"${c.id}\" sets \\`adapter: ${String(legacy)}\\`; the key is \\`driver\\`. Rename \\`adapter\\` to \\`driver\\`.`\n : `Connector \"${c.id}\" has no \\`driver\\`; the runner cannot mount it. Add \\`driver: <name>\\`.`,\n path: `connectors.${c.id}.driver`,\n });\n }\n checkUnavailable(c, diagnostics);\n }\n for (const m of config.mounts ?? []) checkAccess(m.access, `mounts.${m.id}.access`);\n\n const networks: Array<[NetworkPolicy | undefined, string]> = [\n [config.agent?.permissions?.network, \"agent.permissions.network\"],\n ...Object.entries(config.agent?.instances ?? {}).map(\n ([id, instance]): [NetworkPolicy | undefined, string] => [\n instance.permissions?.network,\n `agents.${id}.permissions.network`,\n ],\n ),\n ];\n for (const [network, path] of networks) {\n if (!network) continue;\n if (network.mode && !(KNOWN_NETWORK_MODES as readonly string[]).includes(network.mode)) {\n diagnostics.push({\n code: \"unknown_network_mode\",\n severity: \"warning\",\n message: `Unknown network mode \"${network.mode}\" — expected one of: ${KNOWN_NETWORK_MODES.join(\", \")}.`,\n path: `${path}.mode`,\n });\n }\n if (network.allowlist && network.allowlist.length > 0 && network.mode !== \"allowlist\") {\n diagnostics.push({\n code: \"unexpected_network_allowlist\",\n severity: \"warning\",\n message: `network.allowlist is set but mode is \"${network.mode}\" — the allowlist is ignored unless mode is \"allowlist\".`,\n path: `${path}.allowlist`,\n });\n }\n }\n}\n\n/**\n * Warn about an `unavailable:` marker that is neither a reason string nor\n * `{ reason: string, detail?: string }`.\n * The runner still treats such a connector as unavailable (a generic reason\n * replaces the missing one), so this only points the host at its bug.\n */\nfunction checkUnavailable(c: ConnectorDeclaration, diagnostics: Diagnostic[]): void {\n const value: unknown = c.unavailable;\n if (value === undefined || value === null || value === false) return;\n if (typeof value === \"string\" && value.trim() !== \"\") return;\n const obj = typeof value === \"object\" ? (value as { reason?: unknown; detail?: unknown }) : null;\n const reasonOk = typeof obj?.reason === \"string\" && obj.reason.trim() !== \"\";\n const detailOk = obj?.detail === undefined || typeof obj.detail === \"string\";\n if (reasonOk && detailOk) return;\n diagnostics.push({\n code: \"invalid_unavailable\",\n severity: \"warning\",\n message: `Connector \"${c.id}\" has a malformed \"unavailable\" marker — expected a reason string or { reason: string, detail?: string }. It is still treated as unavailable.`,\n path: `connectors.${c.id}.unavailable`,\n });\n}\n\n/**\n * Canonical key order for encode. `agent_config` is emitted under the hyphenated\n * `agent-config` key (see {@link CONFIG_KEY_TO_YAML}); any field not listed here\n * is appended afterward so forward-compat keys survive a round-trip.\n */\nconst CANONICAL_KEY_ORDER: (keyof SkWorkspaceConfig)[] = [\n \"name\",\n \"description\",\n \"agent_config\",\n \"roles\",\n \"dependencies\",\n \"global_harnesses\",\n \"plugins\",\n \"sources\",\n \"stores\",\n \"overrides\",\n \"startup\",\n \"connectors\",\n \"mcp_servers\",\n \"deploy\",\n \"mounts\",\n \"agent\",\n \"workspace\",\n \"secrets\",\n \"telemetry\",\n \"compaction\",\n \"patches\",\n \"logging\",\n];\n\n/** Internal field name → canonical YAML key, where they differ. */\nconst CONFIG_KEY_TO_YAML: Partial<Record<keyof SkWorkspaceConfig, string>> = {\n agent_config: \"agent-config\",\n};\n\nfunction toCanonicalObject(config: SkWorkspaceConfig): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n const emit = (key: keyof SkWorkspaceConfig) => {\n const value = config[key];\n if (value === undefined) return;\n if (key === \"agent\") {\n // Instances live under the root `agents:` key, not inside `agent:`.\n const { instances, ...agent } = config.agent ?? {};\n if (Object.keys(agent).length > 0) out.agent = agent;\n if (instances) out.agents = instances;\n return;\n }\n out[CONFIG_KEY_TO_YAML[key] ?? key] = value;\n };\n for (const key of CANONICAL_KEY_ORDER) emit(key);\n // Preserve any field not in the canonical order (forward-compat).\n for (const key of Object.keys(config) as (keyof SkWorkspaceConfig)[]) {\n if (CANONICAL_KEY_ORDER.includes(key)) continue;\n emit(key);\n }\n return out;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\n/**\n * Read and decode one config file. An unparseable file reads as \"no config\" (`null`) for the\n * editor/preview callers; with `strictLabel` the runtime resolver gets the parse error instead,\n * named by that label, so it never mistakes a broken file for an empty one.\n */\nfunction parseConfigFile(\n filePath: string,\n name: string,\n strictLabel?: string,\n): SkWorkspaceConfigFile | null {\n let raw: string;\n try {\n raw = readFileSync(filePath, \"utf-8\");\n } catch {\n return null;\n }\n const { config, diagnostics } = decodeSkaileYaml(raw);\n const unparseable = diagnostics.find(\n (d) => d.code === \"yaml_syntax\" || d.code === \"non_object_root\",\n );\n if (unparseable && strictLabel !== undefined) throw configParseError(strictLabel, unparseable);\n if (diagnostics.some((d) => d.code === \"yaml_syntax\")) return null;\n return { path: filePath, name, config, diagnostics };\n}\n\nfunction dedupe(arr: string[]): string[] {\n return [...new Set(arr)];\n}\n\nfunction dedupeByKey<T extends object>(arr: T[], key: string | ((item: T) => string)): T[] {\n const keyOf = typeof key === \"function\" ? key : (item: T) => String((item as any)[key] ?? \"\");\n const seen = new Set<string>();\n const result: T[] = [];\n for (let i = arr.length - 1; i >= 0; i--) {\n const val = keyOf(arr[i]!);\n if (!seen.has(val)) {\n seen.add(val);\n result.unshift(arr[i]!);\n }\n }\n return result;\n}\n\nfunction mergeById<T extends { id: string }>(base: T[], overlay: T[]): T[] {\n const map = new Map<string, T>();\n for (const r of base) map.set(r.id, r);\n for (const r of overlay) map.set(r.id, r);\n return [...map.values()];\n}\n\n// ── MCP server loader ─────────────────────────────────────────────────────────\n\n/**\n * Build a `McpServerDeclaration` from a resolved `CatalogEntry` with `kind: \"mcp-server\"`.\n * Maps `metadata` fields (transport, command, args, env, url, headers) to declaration fields.\n * Returns `null` when the entry has no usable metadata (no command and no url).\n */\nfunction mcpDeclFromCatalogEntry(entry: CatalogEntry): McpServerDeclaration | null {\n const m = entry.metadata;\n if (!m) return null;\n\n const decl: McpServerDeclaration = { id: entry.name };\n if (m.transport) {\n // Normalize the MCP-spec alias to the runtime literal the runner branches on,\n // then allow-list: an unrecognized value is warned-and-skipped rather than cast\n // through to the runner (mirrors the unknown_launcher diagnostic).\n const raw = String(m.transport);\n const t = raw === \"streamable-http\" ? \"http\" : raw;\n if ((KNOWN_TRANSPORTS as readonly string[]).includes(t)) {\n decl.transport = t as (typeof KNOWN_TRANSPORTS)[number];\n } else {\n console.warn(\n `[workspace-config] mcpDeclFromCatalogEntry: unknown transport \"${raw}\" on entry \"${entry.name}\" — expected one of: ${KNOWN_TRANSPORTS.join(\", \")}. Ignoring.`,\n );\n }\n }\n if (m.command) decl.command = String(m.command);\n if (Array.isArray(m.args)) decl.args = m.args.map(String);\n if (m.env && typeof m.env === \"object\") decl.env = m.env as Record<string, string>;\n if (m.url) decl.url = String(m.url);\n if (typeof m.ca === \"string\") decl.ca = m.ca;\n if (m.headers && typeof m.headers === \"object\") {\n decl.headers = m.headers as Record<string, string>;\n }\n if (entry.description) decl.description = entry.description;\n if (m.recipe && typeof m.recipe === \"object\" && !Array.isArray(m.recipe)) {\n const recipe = parseCatalogRecipe(m.recipe as Record<string, unknown>, entry.name);\n if (recipe) decl.recipe = recipe;\n }\n\n // Must have at least a command (stdio) or url (sse/http) to be useful\n if (!decl.command && !decl.url) return null;\n return decl;\n}\n\n/**\n * Parse a raw recipe object from `MCP.md` metadata into a validated\n * {@link AssetRecipe}. Returns `null` when there is no effective attr, or when\n * validation fails (the recipe is then treated as absent — the server may still\n * be usable via command/url without recipe substitution). `entryName` is used\n * only in the warning message.\n */\nfunction parseCatalogRecipe(r: Record<string, unknown>, entryName: string): AssetRecipe | null {\n const hasFlake = typeof r.flake === \"string\";\n // BYO-flake form: `attr` is optional and defaults to \"default\"; legacy form\n // requires `attr`. Compute the effective attr to validate.\n const rawAttr = typeof r.attr === \"string\" ? r.attr : undefined;\n const effectiveAttr = rawAttr ?? (hasFlake ? DEFAULT_RECIPE_ATTR : undefined);\n if (effectiveAttr === undefined) return null;\n\n try {\n validateAssetRecipeAttr(effectiveAttr);\n if (hasFlake) {\n // Validate the flake source too; invalid flake drops the WHOLE recipe\n // (do not silently fall back to a platform-flake attr — a publisher\n // that declared a flake intends to build it; building a same-named\n // platform attr would be a confusing security footgun).\n validateAssetRecipeFlake(r.flake as string);\n const recipe: AssetRecipe = { attr: effectiveAttr, flake: r.flake as string };\n if (typeof r.publisher === \"string\") recipe.publisher = r.publisher;\n return recipe;\n }\n return { attr: effectiveAttr };\n } catch (err) {\n // Invalid attr or flake — skip the recipe field entirely (treat as if\n // recipe was absent). The MCP server may still be usable via a\n // command/url without recipe substitution.\n console.warn(\n `[workspace-config] mcpDeclFromCatalogEntry: invalid recipe for entry \"${entryName}\": ${err instanceof Error ? err.message : String(err)}`,\n );\n return null;\n }\n}\n\n/**\n * Merge two `McpServerDeclaration` objects field-by-field.\n * `overlay` values win for every non-undefined field; `base` provides defaults.\n */\nfunction mergeMcpDeclarations(\n base: McpServerDeclaration,\n overlay: McpServerDeclaration,\n): McpServerDeclaration {\n return {\n id: overlay.id,\n transport: overlay.transport ?? base.transport,\n command: overlay.command ?? base.command,\n args: overlay.args ?? base.args,\n env: overlay.env ? (base.env ? { ...base.env, ...overlay.env } : overlay.env) : base.env,\n url: overlay.url ?? base.url,\n ca: overlay.ca ?? base.ca,\n headers: overlay.headers\n ? base.headers\n ? { ...base.headers, ...overlay.headers }\n : overlay.headers\n : base.headers,\n description: overlay.description ?? base.description,\n tags: overlay.tags ?? base.tags,\n recipe: overlay.recipe ?? base.recipe,\n // Sticky: once either side carried folded `.instance.json` secrets, the\n // merged `env` does too — the flag must not be lost by an overlay.\n instanceSecretsFolded: overlay.instanceSecretsFolded ?? base.instanceSecretsFolded,\n };\n}\n\n/**\n * Scan `<projectDir>/.skaile/assets/mcp-server/<name>/MCP.md` for MCP servers\n * that the platform materializer has written to disk for a subscribed asset.\n *\n * For each immediate subdirectory containing an `MCP.md`, the manifest is parsed\n * via {@link fromMcpServerMdContent} and mapped to a declaration via\n * {@link mcpDeclFromCatalogEntry}. A sibling `.instance.json` (written by the\n * platform materializer) is folded into `decl.env`.\n *\n * **Env-fold precedence (lowest → highest):**\n * 1. `MCP.md` `env` defaults\n * 2. string-valued entries of `.instance.json` `config` (non-string config\n * values — objects/arrays/numbers — are skipped so env never contains\n * `[object Object]`)\n * 3. `.instance.json` `resolvedSecrets` (always folded, all keys)\n *\n * Folded secret *values* are never logged. A malformed `MCP.md` for one asset\n * is caught per-directory and skipped (warned without secret values) so one bad\n * asset never aborts the whole scan.\n *\n * @param projectDir - Workspace root containing `.skaile/assets/mcp-server/`\n * @returns Declarations for every materialized MCP asset (empty if the dir is absent)\n */\n// Strip a publisher scope so a declared `@pub/name` matches a materialized dir\n// named `name` (and vice versa) without a false strict-mode exclusion.\nconst unscopedTail = (x: string): string => (x.includes(\"/\") ? x.split(\"/\").pop()! : x);\n\n/**\n * Fold a sibling `.instance.json` (written by the platform materializer) into\n * `decl.env`. Env-fold precedence (lowest → highest): existing `decl.env` <\n * string-valued `config` entries < `resolvedSecrets`. A malformed transient\n * `.instance.json` must not nuke a valid MCP server — parse errors are caught\n * here (warned without secret values) so the decl survives with its `MCP.md`\n * env. No-op when the file is absent. `name` is used only in the warning.\n */\nfunction foldInstanceEnv(decl: McpServerDeclaration, instancePath: string, name: string): void {\n if (!existsSync(instancePath)) return;\n try {\n const instance = JSON.parse(readFileSync(instancePath, \"utf8\")) as {\n config?: Record<string, unknown>;\n resolvedSecrets?: Record<string, unknown>;\n };\n\n const env: Record<string, string> = { ...(decl.env ?? {}) };\n\n // string-config < resolvedSecrets (folded after, so secrets win)\n if (instance.config && typeof instance.config === \"object\") {\n for (const [k, v] of Object.entries(instance.config)) {\n if (typeof v === \"string\") env[k] = v;\n }\n }\n if (instance.resolvedSecrets && typeof instance.resolvedSecrets === \"object\") {\n for (const [k, v] of Object.entries(instance.resolvedSecrets)) {\n // Guard like the config fold above — a non-string secret (serializer\n // bug) must not land in subprocess env as \"[object Object]\"/\"null\".\n if (typeof v === \"string\") {\n env[k] = v;\n // Mark the decl so disk-persisting consumers skip it — these are live\n // plaintext credentials that must never leave memory.\n decl.instanceSecretsFolded = true;\n }\n }\n }\n\n if (Object.keys(env).length > 0) decl.env = env;\n } catch (err) {\n // Never include secret values in the warning — only the failing path + message.\n console.warn(\n `[workspace-config] foldInstanceEnv: ignoring malformed \".instance.json\" for \"${name}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n}\n\n/**\n * Derive a single MCP declaration from a materialized on-disk subdir.\n * Returns `null` when the subdir has no `MCP.md` or when parsing fails\n * (warns without aborting the caller's scan).\n */\nexport function deriveSingleMaterializedMcpDeclaration(\n subDir: string,\n name: string,\n): McpServerDeclaration | null {\n const mdPath = join(subDir, \"MCP.md\");\n if (!existsSync(mdPath)) return null;\n\n try {\n const mdContent = readFileSync(mdPath, \"utf8\");\n const { body } = parseFrontmatter(mdContent);\n const entry = fromMcpServerMdContent(mdContent, name, mdPath);\n const decl = mcpDeclFromCatalogEntry(entry);\n if (!decl) return null;\n\n decl.id = entry.name || name;\n foldInstanceEnv(decl, join(subDir, \".instance.json\"), name);\n const trimmedBody = body.trim();\n if (trimmedBody.length > 0) decl.instructions = trimmedBody;\n return decl;\n } catch (err) {\n // Never include secret values — only the failing path + message.\n console.warn(\n `[workspace-config] deriveSingleMaterializedMcpDeclaration: failed to load \"${mdPath}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n return null;\n }\n}\n\nfunction loadMaterializedMcpDeclarations(projectDir: string): McpServerDeclaration[] {\n const dir = join(projectDir, \".skaile/assets/mcp-server\");\n if (!existsSync(dir)) return [];\n\n const result: McpServerDeclaration[] = [];\n\n let subdirs: string[];\n try {\n subdirs = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n } catch {\n return [];\n }\n\n for (const name of subdirs) {\n const subDir = join(dir, name);\n const decl = deriveSingleMaterializedMcpDeclaration(subDir, name);\n if (decl) result.push(decl);\n }\n\n return result;\n}\n\n/** Immediate subdirectory names of `dir`; `[]` when it is missing or unreadable. */\nfunction subdirNames(dir: string): string[] {\n try {\n return readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n } catch {\n return [];\n }\n}\n\n/**\n * MCP declarations derived from **store-staged** bytes. `skaile add\n * mcp-server:@pub/name` fetches the asset into\n * `<projectDir>/.skaile/cache/store/<publisher>/mcp-server/<name>/<version>/`\n * but never copies it into a driver target dir (an MCP is wired at session\n * start, not read as a file by the driver) — so unless this scan runs, the\n * staged `MCP.md` is invisible and the install is a silent no-op (#462).\n *\n * The store cache is a *cache*, so every read is best-effort: a missing or\n * unreadable dir at any level yields no declarations rather than throwing.\n * Nothing prunes superseded version dirs, so multiple versions of one asset can\n * sit side by side; they are walked in **numeric-collation** order (`0.9.0` <\n * `0.10.0`, which a plain lexicographic sort gets backwards) so the newest merges\n * on top and an upgrade never keeps wiring the stale `command` / `args` / `env`.\n *\n * Reusing {@link deriveSingleMaterializedMcpDeclaration} also folds a sibling\n * `.instance.json` — a file the platform materializer writes, but which a store\n * publisher could now ship. That grants no capability the asset's own `MCP.md`\n * `env` / `command` does not already have, and folded values are never logged.\n */\nfunction loadStoreStagedMcpDeclarations(projectDir: string): McpServerDeclaration[] {\n const root = join(projectDir, \".skaile/cache/store\");\n if (!existsSync(root)) return [];\n\n const result: McpServerDeclaration[] = [];\n for (const publisher of subdirNames(root)) {\n const kindDir = join(root, publisher, \"mcp-server\");\n for (const name of subdirNames(kindDir)) {\n const nameDir = join(kindDir, name);\n const versions = subdirNames(nameDir).sort((a, b) =>\n a.localeCompare(b, \"en\", { numeric: true }),\n );\n for (const version of versions) {\n const decl = deriveSingleMaterializedMcpDeclaration(join(nameDir, version), name);\n if (decl) result.push(decl);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Multiplier applied to the base filesystem deadline for whole-tree copies.\n * A recursive copy legitimately takes far longer than the single `stat` the\n * base deadline is sized for, and a false timeout here would silently drop a\n * declared skill.\n */\nconst TREE_COPY_DEADLINE_FACTOR = 4;\n\n/**\n * Copy each materialized skill the platform materializer wrote to\n * `<projectDir>/.skaile/assets/skill/<name>/` into the active driver's native\n * skills dir (`<projectDir>/<skillsDir>/<name>/`) so native discovery surfaces\n * them to the LLM. Mirrors {@link loadMaterializedMcpDeclarations}: the scan\n * ALWAYS runs, independent of `dependencies:`.\n *\n * Only immediate subdirectories containing a `SKILL.md` are staged. The copy is\n * idempotent (`force: true` overwrites a previously staged copy on refresh).\n * `.instance.json` is NEVER copied — it can hold a materializer's\n * `resolvedSecrets`, which must not leak into `.claude/skills/`; Claude Code\n * skills do not consume it either.\n *\n * **Async by necessity.** Both `projectDir` and the driver's skills dir can sit\n * on (or beside) an rclone FUSE mount. The former synchronous `existsSync` +\n * `cpSync` pair parked the whole event loop for as long as the mount took to\n * answer — unbounded, and invisible to `try/catch` because a hang is not an\n * error. Every filesystem call here is now awaited and deadline-bounded, so a\n * wedged mount costs one failed staging attempt instead of the session.\n *\n * A failure staging one skill is caught per-directory, warned (path + message\n * only, never file contents), and skipped so one bad skill never aborts the scan.\n *\n * Each staged copy gets a {@link STAGED_SKILL_MARKER}. The copy merges over a\n * same-named dir exactly as before the marker existed, and marks it — so a copy\n * staged by an older runner is claimed on its next restage while its skill is\n * still delivered. The flip side, unchanged from before: a delivered skill\n * overwrites a user-authored skill of the same name, and after this it is\n * marked, so a later unassign removes it. Staging only ever adds: removal\n * happens only on an explicit {@link unstageSkill}, never because a\n * materialized source is momentarily absent (broker delivery and\n * re-materialization both empty the source tree before rewriting it).\n *\n * When `opts.declared` is provided, only skills whose dir name appears in it are\n * staged — undeclared on-disk dirs (\"ghosts\") are skipped so the effective set\n * equals `skaile.yaml` exactly (the canonical-contract invariant; the runner\n * always passes `declared`). Publisher-scope tolerance: `@pub/name` declared\n * matches a dir named `name`, and vice versa. When `opts.declared` is omitted the\n * scan stages every materialized skill (used by callers that do their own gating).\n *\n * @param projectDir - Workspace root containing `.skaile/assets/skill/`\n * @param skillsDir - Driver-relative skills dir, e.g. `.claude/skills`\n * @param opts - When `declared` is present, restrict staging to those names\n * @returns Names of the skills staged (empty if the source dir is absent)\n */\nexport async function stageMaterializedSkills(\n projectDir: string,\n skillsDir: string,\n opts?: { declared?: string[] },\n): Promise<string[]> {\n const dir = join(projectDir, \".skaile/assets/skill\");\n\n const staged: string[] = [];\n\n // One readdir replaces the former existsSync + readdirSync pair: a missing\n // dir and an unreadable dir are the same \"nothing to stage\" outcome, so the\n // separate probe bought nothing but a second trip to a possibly-wedged mount.\n let subdirs: string[];\n try {\n const entries = await withFsDeadline(`readdir ${dir}`, () =>\n readdirAsync(dir, { withFileTypes: true }),\n );\n subdirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);\n } catch {\n return [];\n }\n\n // When a declared set is provided, build it once; each dir name is matched\n // against both its full form and its unscoped tail (publisher-scope tolerance).\n let declaredSet: Set<string> | undefined;\n if (opts?.declared !== undefined) {\n declaredSet = new Set<string>(opts.declared.flatMap((d) => [d, unscopedTail(d)]));\n }\n\n for (const name of subdirs) {\n const src = join(dir, name);\n\n // Declared-set filter first: it is free, and skipping it early spares an\n // undeclared ghost dir a filesystem round-trip we would then discard.\n if (declaredSet && !declaredSet.has(name) && !declaredSet.has(unscopedTail(name))) continue;\n\n const hasSkillMd = await tryWithFsDeadline(\n `stat ${join(src, \"SKILL.md\")}`,\n async () => {\n await statAsync(join(src, \"SKILL.md\"));\n return true;\n },\n false,\n );\n if (!hasSkillMd) continue;\n\n const dest = join(projectDir, skillsDir, name);\n try {\n // cp recursive creates dest; exclude `.instance.json` at any depth (resolvedSecrets).\n // A skill tree can carry bundled assets, so the copy gets a wider budget\n // than a single stat — scaled off the operator-tunable base deadline.\n await withFsDeadline(\n `cp ${src} -> ${dest}`,\n () =>\n cpAsync(src, dest, {\n recursive: true,\n force: true,\n filter: (source) => basename(source) !== \".instance.json\",\n }),\n fsDeadlineMs() * TREE_COPY_DEADLINE_FACTOR,\n );\n staged.push(name);\n // Best-effort: the skill is staged and loads either way; without the\n // marker it just cannot be detached or restaged until a later write lands.\n try {\n await withFsDeadline(`write ${join(dest, STAGED_SKILL_MARKER)}`, () =>\n writeStagedSkillMarker(join(dest, STAGED_SKILL_MARKER), name),\n );\n } catch (err) {\n console.warn(\n `[workspace-config] stageMaterializedSkills: staged \"${dest}\" but could not mark it: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n } catch (err) {\n // Never include file contents in the warning — only the failing path + message.\n console.warn(\n `[workspace-config] stageMaterializedSkills: failed to stage \"${src}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n\n return staged;\n}\n\n/**\n * File written into every skill dir {@link stageMaterializedSkills} stages. It is\n * the runner's claim of ownership: {@link unstageSkill} never deletes a dir\n * that lacks it. \"Marked\" means staged by the runner OR a same-named\n * pre-existing dir the delivered skill was copied over — such a dir, including\n * any extra files a user kept in it, is removed when that skill leaves the set.\n */\nexport const STAGED_SKILL_MARKER = \".skaile-staged\";\n\n/** What a skill dir's {@link STAGED_SKILL_MARKER} says about who owns it. */\nexport type StagedSkillMarkerState = \"named\" | \"legacy\" | \"other\" | \"absent\";\n\n/** More than any skill dir name; the marker is agent-writable, so it is never read whole. */\nconst MARKER_READ_LIMIT = 512;\n\n/** Open errors that mean \"something other than our regular marker file is there\". */\nconst FOREIGN_MARKER_CODES = new Set([\"ELOOP\", \"ENXIO\", \"EAGAIN\", \"EISDIR\", \"ENOTDIR\", \"EACCES\"]);\n\n/**\n * Write the marker without following an agent-planted link: unlink whatever is\n * at the path, then create it exclusively with `O_NOFOLLOW`. The runner and the\n * agent can run as different uids, so a followed link would let the agent make\n * the runner truncate a file only the runner may write. One retry on EEXIST\n * covers a racing re-plant; after that it fails, and the caller treats that as\n * best-effort.\n */\nasync function writeStagedSkillMarker(path: string, name: string): Promise<void> {\n const flags =\n fsConstants.O_CREAT | fsConstants.O_EXCL | fsConstants.O_WRONLY | fsConstants.O_NOFOLLOW;\n for (let attempt = 0; ; attempt++) {\n await rmAsync(path, { force: true });\n try {\n const handle = await openAsync(path, flags, 0o644);\n try {\n await handle.writeFile(name);\n } finally {\n await handle.close();\n }\n return;\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code !== \"EEXIST\" || attempt > 0) throw err;\n }\n }\n}\n\n/**\n * Read `dir`'s {@link STAGED_SKILL_MARKER}. The runner writes the dir name into\n * it, so an agent's copy or rename of a staged skill (which carries the marker\n * along) reads `\"other\"`. `\"legacy\"` is an older runner's empty marker: an\n * explicit, host-named detach may remove it, a sweep may not; the next restage\n * of an assigned skill rewrites it.\n *\n * The marker is agent-writable and this runs under the skill-fs lock, so it is\n * opened with `O_NOFOLLOW | O_NONBLOCK` (a symlink, FIFO or device never blocks\n * or streams), must be a regular file of at most {@link MARKER_READ_LIMIT}\n * bytes, and is read only that far. Anything else is `\"other\"`, never an\n * error, so it cannot make a detach fail. Any other failure (a timeout)\n * throws: callers delete on this.\n */\nexport async function stagedSkillMarkerState(\n dir: string,\n name: string,\n): Promise<StagedSkillMarkerState> {\n const path = join(dir, STAGED_SKILL_MARKER);\n let content: string | null;\n try {\n content = await withFsDeadline(`read ${path}`, async () => {\n const handle = await openAsync(\n path,\n fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW | fsConstants.O_NONBLOCK,\n );\n try {\n const st = await handle.stat();\n if (!st.isFile() || st.size > MARKER_READ_LIMIT) return null;\n const buf = Buffer.alloc(MARKER_READ_LIMIT);\n const { bytesRead } = await handle.read(buf, 0, MARKER_READ_LIMIT, 0);\n return buf.subarray(0, bytesRead).toString(\"utf8\");\n } finally {\n await handle.close();\n }\n });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException)?.code;\n if (code === \"ENOENT\") return \"absent\";\n if (code !== undefined && FOREIGN_MARKER_CODES.has(code)) return \"other\";\n throw err;\n }\n if (content === null) return \"other\";\n const claimed = content.trim();\n if (claimed === \"\") return \"legacy\";\n return claimed === name ? \"named\" : \"other\";\n}\n\n/** Whether `dir`'s marker names `name` exactly (the only proof a sweep accepts). */\nexport async function isStagedSkillMarkerFor(dir: string, name: string): Promise<boolean> {\n return (await stagedSkillMarkerState(dir, name)) === \"named\";\n}\n\n/**\n * Session-root-relative path of the skill allowlist a host may deliver next to\n * the materialized assets: `{ \"version\": 1, \"skills\": [\"<dir name>\", ...] }`,\n * the complete set of skill dir names the host's latest delivery allows. A\n * restage removes a MARKED staged skill that the list does not name and whose\n * materialized asset is absent. No list, or one that does not parse, removes\n * nothing. It sits under `.skaile/assets/` because that is the tree a broker\n * host can write in the session root, and a delivery that empties that tree\n * therefore also drops the list until its last write replaces it.\n */\nexport const SKILL_ALLOWLIST_FILE = \".skaile/assets/skill-allowlist.json\";\n\n/** The only allowlist format a runner acts on; any other version is ignored. */\nexport const SKILL_ALLOWLIST_VERSION = 1;\n\n/**\n * Read {@link SKILL_ALLOWLIST_FILE}. Returns the listed names (a scoped\n * `@publisher/name` also contributes its dir-name tail), or `null` when there\n * is no usable list: missing, unreadable, timed out, not valid JSON (a write\n * still in flight reads as a truncated document), an unknown version, or any\n * entry that is not a string. `null` means \"remove nothing\"; never throws.\n */\nexport async function readSkillAllowList(projectDir: string): Promise<ReadonlySet<string> | null> {\n const path = join(projectDir, SKILL_ALLOWLIST_FILE);\n const raw = await tryWithFsDeadline(\n `read ${path}`,\n () => readFileAsync(path, \"utf8\") as Promise<string | null>,\n null,\n );\n if (raw === null) return null;\n let doc: unknown;\n try {\n doc = JSON.parse(raw);\n } catch {\n return null;\n }\n if (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) return null;\n const { version, skills } = doc as { version?: unknown; skills?: unknown };\n if (version !== SKILL_ALLOWLIST_VERSION || !Array.isArray(skills)) return null;\n if (!skills.every((s): s is string => typeof s === \"string\")) return null;\n return new Set(skills.flatMap((s) => [s, unscopedTail(s)]));\n}\n\n/** A skill dir name or `@publisher/name`; anything else could escape the skills dir. */\nconst SKILL_NAME_RE = /^(?:@[A-Za-z0-9._-]+\\/)?[A-Za-z0-9._-]+$/;\n\n/** Validate a skill ref and return the dir name it stages under. Throws on unsafe input. */\nfunction skillDirName(name: string): string {\n const tail = SKILL_NAME_RE.test(name) ? unscopedTail(name) : \"\";\n if (tail === \"\" || tail === \".\" || tail === \"..\") {\n throw new Error(`invalid skill name: ${JSON.stringify(name)}`);\n }\n return tail;\n}\n\n/**\n * Deadline-bounded existence probe. Only ENOENT means absent; any other error\n * (a timeout on a wedged mount, EACCES) is rethrown, because callers delete or\n * skip based on the answer and must never do so on a guess.\n */\nasync function probePath(path: string): Promise<boolean> {\n try {\n await withFsDeadline(`stat ${path}`, () => statAsync(path));\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"ENOENT\") return false;\n throw err;\n }\n}\n\n/** Deadline-bounded recursive remove, sized like the staging copy. */\nfunction removeTree(path: string): Promise<void> {\n return withFsDeadline(\n `rm -r ${path}`,\n () => rmAsync(path, { recursive: true, force: true }),\n fsDeadlineMs() * TREE_COPY_DEADLINE_FACTOR,\n );\n}\n\n/** Outcome of {@link unstageSkill}. */\nexport type UnstageSkillResult =\n | { name: string; removedStaged: boolean; removedAsset: boolean }\n | { name: string; removedStaged: false; removedAsset: boolean; reason: \"not_staged\" };\n\n/**\n * Unload one skill on an explicit request: remove its staged copy\n * `<projectDir>/<skillsDir>/<dir>/` AND its materialized source\n * `<projectDir>/.skaile/assets/skill/<dir>/`, so no later\n * {@link stageMaterializedSkills} pass can bring it back. Accepts\n * `@publisher/name` (the dir is the unscoped tail).\n *\n * A same-named skills dir whose {@link STAGED_SKILL_MARKER} is missing or names\n * another dir (see {@link stagedSkillMarkerState}) was not staged by this runner\n * (a catalog deploy, the agent's own skill or its copy of a staged one, or an\n * older runner's copy never marked) and is never deleted: the result\n * carries `reason: \"not_staged\"`. `.skaile/assets` is per-session in every mode (in\n * broker it sits under the session's own root), so removing the asset touches\n * no other session.\n *\n * `opts.knownStaged` is the caller's own record that this runner staged the\n * dir (its marker write may have failed); it is then removed without a marker.\n * `opts.keepAsset` leaves the materialized source alone (it belongs to the\n * host; a caller that already saw it absent must not delete a fresh delivery).\n *\n * @throws When `name` is not a plain skill name (path traversal guard), or a\n * probe or removal fails for any reason other than the path being absent\n */\nexport async function unstageSkill(\n projectDir: string,\n skillsDir: string,\n name: string,\n opts?: { knownStaged?: boolean; keepAsset?: boolean },\n): Promise<UnstageSkillResult> {\n const dir = skillDirName(name);\n const staged = join(projectDir, skillsDir, dir);\n const asset = join(projectDir, \".skaile/assets/skill\", dir);\n\n // Decide ownership first, then remove the asset BEFORE the copy: a failure\n // after that leaves the copy (still loaded) in place rather than a driver\n // with no copy and no restart scheduled.\n const owned = (await probePath(staged))\n ? opts?.knownStaged === true ||\n [\"named\", \"legacy\"].includes(await stagedSkillMarkerState(staged, dir))\n : null;\n const removedAsset = opts?.keepAsset !== true && (await probePath(asset));\n if (removedAsset) await removeTree(asset);\n if (owned === false) {\n return { name: dir, removedStaged: false, removedAsset, reason: \"not_staged\" };\n }\n if (owned) await removeTree(staged);\n return { name: dir, removedStaged: owned === true, removedAsset };\n}\n\n/**\n * Resolve each `sources[]` entry to an on-disk clone path under the unified\n * machine cache (`<cache>/sources/<host>/<owner>/<repo>/`) and its resolved HEAD\n * commit. Entries with no on-disk clone are skipped — the install pipeline\n * clones them first.\n */\nfunction buildSourceClones(sources: SourceEntry[]): SourceClone[] {\n const sourcesDir = getGlobalCacheDir();\n const clones: SourceClone[] = [];\n for (const s of sources) {\n const localPath = join(sourcesDir, sourceCacheKey(s.url));\n if (!existsSync(localPath)) continue;\n const commit = getRepoCommit(localPath) ?? \"0\".repeat(40);\n clones.push({\n localPath,\n sourceUrl: s.url,\n commit,\n tag: s.pin,\n ...(s.publisher ? { publisher: s.publisher } : {}),\n });\n }\n return clones;\n}\n\n/** Build a synthetic CatalogEntry from a provenance candidate's MCP metadata. */\nfunction catalogEntryFromCandidate(c: ProvenanceCandidate): CatalogEntry {\n const md = c.metadata ?? {};\n const entry: CatalogEntry = {\n name: c.name,\n kind: c.kind as CatalogEntry[\"kind\"],\n description: c.description ?? (typeof md.description === \"string\" ? md.description : \"\"),\n source: c.files[0]?.path ?? \"\",\n publisher: c.publisher,\n version: c.version,\n requires: [],\n dependencies: c.deps ?? [],\n metadata: c.metadata,\n };\n if (c.category != null) entry.category = c.category;\n if (c.keywords && c.keywords.length > 0) entry.keywords = c.keywords;\n if (c.license != null) entry.license = c.license;\n if (c.homepage != null) entry.homepage = c.homepage;\n return entry;\n}\n\n/**\n * Load MCP server declarations by merging four sources:\n *\n * 1. **Catalog defaults** — `mcp-server:*` refs in the top-level `dependencies`\n * array, resolved against the provenance index built from the project's\n * cloned `sources[]`. The `MCP.md` frontmatter (captured on the walker's\n * `metadata` field) provides default config (transport, command, args, env,\n * url, headers).\n *\n * 2. **Store-staged assets** — MCP servers `skaile add mcp-server:<store-ref>`\n * fetched into `<projectDir>/.skaile/cache/store/<publisher>/mcp-server/<name>/<version>/`\n * (see {@link loadStoreStagedMcpDeclarations}). A store-sourced MCP has no\n * clone to resolve against, so this is its only route into a session.\n *\n * 3. **Materialized assets** — MCP servers the platform materializer has written\n * to `<projectDir>/.skaile/assets/mcp-server/<name>/MCP.md` for subscribed\n * assets (see {@link loadMaterializedMcpDeclarations}). This scan ALWAYS runs,\n * so a subscribed asset on disk with no `dependencies:` and no `mcp_servers:`\n * entry is still picked up.\n *\n * 4. **Explicit declarations** — entries in the `mcp_servers` section of\n * `skaile.yaml`. These override the other three sources field-by-field when\n * the `id` matches.\n *\n * **Precedence (lowest → highest):** catalog-dep refs < store-staged assets <\n * materialized assets < explicit `mcp_servers:`. Same-id entries from different\n * sources merge (higher overlays onto lower) rather than double-counting.\n *\n * @param projectDir - Workspace root where `skaile.yaml` lives\n * @returns Unified array of `McpServerDeclaration` objects ready for the runner\n * @docLink packages/core/workspace-config#load-mcp-server-declarations\n */\n/**\n * Resolve the first provenance candidate for an `mcp-server` ref. Prefers the\n * publisher-keyed candidate; falls back to any candidate whose key ends with\n * `/<kind>:<name>`. Returns `undefined` when nothing matches.\n */\nfunction lookupMcpCandidate(\n provenanceIndex: ProvenanceIndex,\n ref: ReturnType<typeof parseAssetRef>,\n): ProvenanceCandidate | undefined {\n let candidates: ProvenanceCandidate[] | undefined;\n if (ref.publisher) {\n candidates = provenanceIndex.get(`${ref.publisher}/${ref.kind}:${ref.name}`);\n }\n if (!candidates) {\n for (const [key, arr] of provenanceIndex) {\n if (key.endsWith(`/${ref.kind}:${ref.name}`)) {\n candidates = arr;\n break;\n }\n }\n }\n return candidates?.[0];\n}\n\n/**\n * Build the strict-mode declared-name set: explicit `mcp_servers` ids ∪ dep-ref\n * names (kind `mcp-server`), each contributing both its full and unscoped form\n * so a scoped declaration (e.g. id `@pub/excel`) still admits a materialized dir\n * named `excel`.\n */\nfunction buildDeclaredMcpNames(\n explicit: McpServerDeclaration[],\n mcpRefStrings: string[],\n): Set<string> {\n return new Set<string>([\n ...explicit.flatMap((e) => [e.id, unscopedTail(e.id)]),\n ...mcpRefStrings.flatMap((refStr) => {\n try {\n const r = parseAssetRef(refStr);\n return [r.name, unscopedTail(r.name)];\n } catch {\n return [];\n }\n }),\n ]);\n}\n\n/**\n * Collect `mcp-server` dep refs from the top-level `dependencies` array only.\n * (ai_resources[].dependencies is no longer a thing.) Parse failures surface\n * elsewhere (install pipeline) and are skipped here.\n */\nfunction collectMcpRefStrings(dependencies: string[] | undefined): string[] {\n const mcpRefStrings: string[] = [];\n for (const dep of dependencies ?? []) {\n try {\n const ref = parseAssetRef(dep);\n if (ref.kind === \"mcp-server\") mcpRefStrings.push(dep);\n } catch {\n // Parse failures surface elsewhere (install pipeline). Skip here.\n }\n }\n return mcpRefStrings;\n}\n\nconst MCP_LOOKUP_KINDS: ReadonlySet<string> = new Set([\"mcp-server\"]);\n\n/** Build the provenance index from cloned sources for catalog-default lookup. */\nasync function buildMcpProvenanceIndex(\n sources: SourceEntry[],\n projectDir: string,\n): Promise<ProvenanceIndex> {\n return sources.length > 0\n ? await buildProvenanceIndex(buildSourceClones(sources), {\n projectDir,\n // Only `mcp-server` refs are looked up in this index.\n knownKinds: MCP_LOOKUP_KINDS,\n })\n : (new Map() as ProvenanceIndex);\n}\n\n/**\n * Source 1 (lowest): upsert catalog-dep refs resolved via the provenance index.\n */\nfunction upsertCatalogMcpDecls(\n mcpRefStrings: string[],\n provenanceIndex: ProvenanceIndex,\n upsert: (decl: McpServerDeclaration) => void,\n): void {\n const seen = new Set<string>();\n for (const refStr of mcpRefStrings) {\n let ref: ReturnType<typeof parseAssetRef>;\n try {\n ref = parseAssetRef(refStr);\n } catch {\n continue;\n }\n if (seen.has(ref.name)) continue;\n seen.add(ref.name);\n\n const candidate = lookupMcpCandidate(provenanceIndex, ref);\n if (!candidate) continue;\n\n const catalogDecl = mcpDeclFromCatalogEntry(catalogEntryFromCandidate(candidate));\n if (!catalogDecl) continue;\n\n upsert(catalogDecl);\n }\n}\n\n/**\n * Sources 2 and 3: upsert a batch of on-disk decls (store-staged, then\n * materialized), overlaying onto a matching catalog base. Only\n * `skaile.yaml`-declared assets may load (the canonical-contract invariant);\n * undeclared on-disk entries (\"ghosts\") are silently skipped so the effective set\n * equals skaile.yaml exactly. The platform always writes the full effective set,\n * so nothing legitimately active is dropped.\n */\nfunction upsertGatedMcpDecls(\n decls: McpServerDeclaration[],\n explicit: McpServerDeclaration[],\n mcpRefStrings: string[],\n upsert: (decl: McpServerDeclaration) => void,\n): void {\n const declaredNames = buildDeclaredMcpNames(explicit, mcpRefStrings);\n for (const decl of decls) {\n if (declaredNames.has(decl.id) || declaredNames.has(unscopedTail(decl.id))) upsert(decl);\n }\n}\n\nexport async function loadMcpServerDeclarations(\n projectDir: string,\n): Promise<McpServerDeclaration[]> {\n const config = resolveSkWorkspaceConfig(projectDir);\n const explicit = config.mcp_servers ?? [];\n\n // Materialized scan always runs — the primary use case is a subscribed asset\n // on disk with no dependencies: and no mcp_servers: entry.\n const materialized = loadMaterializedMcpDeclarations(projectDir);\n\n const mcpRefStrings = collectMcpRefStrings(config.dependencies);\n const provenanceIndex = await buildMcpProvenanceIndex(config.sources ?? [], projectDir);\n\n // byId tracks the current merged decl per id so later, higher-precedence\n // sources overlay onto it instead of double-counting.\n const byId = new Map<string, McpServerDeclaration>();\n const order: string[] = [];\n\n const upsert = (decl: McpServerDeclaration) => {\n const existing = byId.get(decl.id);\n if (existing) {\n byId.set(decl.id, mergeMcpDeclarations(existing, decl));\n } else {\n byId.set(decl.id, decl);\n order.push(decl.id);\n }\n };\n\n // Source 1 (lowest): catalog-dep refs resolved via the provenance index.\n upsertCatalogMcpDecls(mcpRefStrings, provenanceIndex, upsert);\n\n // Source 2: store-staged bytes (`skaile add mcp-server:<store-ref>`) — the only\n // route for a store-sourced MCP, which has no clone to resolve against.\n upsertGatedMcpDecls(loadStoreStagedMcpDeclarations(projectDir), explicit, mcpRefStrings, upsert);\n\n // Source 3: materialized assets — overlay onto matching catalog/staged base.\n // Only declared assets load (canonical-contract invariant); ghosts drop.\n upsertGatedMcpDecls(materialized, explicit, mcpRefStrings, upsert);\n\n // Source 4 (highest): explicit mcp_servers: — overlay field-by-field.\n for (const decl of explicit) {\n upsert(decl);\n }\n\n return order.map((id) => byId.get(id) as McpServerDeclaration);\n}\n\n// ── Agent definition resolver ──────────────────────────────────────────────────\n\n/**\n * Walk upward from `from` (max 8 levels) until a directory containing\n * `ai-assets/` is found. Returns the absolute path to that `ai-assets/`\n * directory, or undefined if none found.\n */\nfunction findAiAssetsDir(from: string): string | undefined {\n let dir = resolve(from);\n for (let i = 0; i < 8; i++) {\n const candidate = join(dir, \"ai-assets\");\n if (existsSync(candidate)) return candidate;\n const resolved = resolve(dir, \"..\");\n if (resolved === dir) break;\n dir = resolved;\n }\n return undefined;\n}\n\n/** Manifest file that marks a directory as an agent definition. */\nconst AGENT_MANIFEST_FILE = \"agent.yaml\";\n\n/**\n * How many directory levels below the `ai-assets/` root the `agent:<name>`\n * lookup descends. Catalog agents sit 2–5 levels down (`<repo>/<group>/agent/`,\n * `<repo>/<group>/<subgroup>/agents/<name>/`); 6 leaves one level of headroom.\n */\nconst AI_ASSETS_AGENT_WALK_DEPTH = 6;\n\n/** Why an `agent:<name>` definition could not be resolved to one directory. */\nexport type AgentRefErrorCode = \"invalid_ref\" | \"not_found\" | \"ambiguous\";\n\n/**\n * Thrown by {@link resolveAgentDir} when `agent.definition` is an\n * `agent:<name>` reference it cannot map to exactly one agent directory.\n *\n * Distinct from the `undefined` return, which means \"no agent configured\": a\n * caller that catches this knows an agent WAS configured and must not silently\n * fall back to a default identity.\n *\n * - `invalid_ref` — the definition is not `agent:@<publisher>/<name>[#pin]` or\n * `agent:<name>`.\n * - `not_found` — no `agent.yaml` in any searched tree declares the name.\n * - `ambiguous` — several `agent.yaml` in the same tree declare the name.\n * @docLink packages/core/workspace-config#resolve-agent-dir\n */\nexport class AgentRefResolutionError extends Error {\n readonly code: AgentRefErrorCode;\n /** The raw `agent.definition` value. */\n readonly definition: string;\n /** Agent trees searched, in precedence order (empty for `invalid_ref`). */\n readonly searched: string[];\n /** Directories declaring the name (`ambiguous` only). */\n readonly matches: string[];\n\n constructor(\n code: AgentRefErrorCode,\n definition: string,\n message: string,\n searched: string[] = [],\n matches: string[] = [],\n ) {\n super(message);\n this.name = \"AgentRefResolutionError\";\n this.code = code;\n this.definition = definition;\n this.searched = searched;\n this.matches = matches;\n }\n}\n\n/**\n * The agent name an `agent:` definition refers to. Accepts the canonical\n * `agent:@<publisher>/<name>[#pin]` and the bare `agent:<name>` form. Publisher\n * and pin do not take part in the lookup: every searched tree is one checkout,\n * so the declared `name:` alone identifies the agent.\n */\nfunction agentRefName(definition: string): string {\n let canonicalError: string;\n try {\n return parseAssetRef(definition).name;\n } catch (err) {\n canonicalError = err instanceof Error ? err.message : String(err);\n }\n const bare = /^agent:([\\w.-]+)$/.exec(definition.trim());\n if (bare) return bare[1];\n throw new AgentRefResolutionError(\n \"invalid_ref\",\n definition,\n `agent.definition \"${definition}\" is not a valid agent reference — use ` +\n `\\`agent:@<publisher>/<name>[#pin]\\` or \\`agent:<name>\\` (${canonicalError})`,\n );\n}\n\n/** The `name:` an `agent.yaml` declares, or undefined when absent or unreadable. */\nfunction declaredAgentName(manifestPath: string): string | undefined {\n let raw: string;\n try {\n raw = readFileSync(manifestPath, \"utf-8\");\n } catch {\n return undefined; // not an agent directory\n }\n try {\n const doc = parse(raw) as { name?: unknown } | null;\n return typeof doc?.name === \"string\" ? doc.name : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Child directories of `dir` worth searching, sorted; follows symlinked dirs. */\nfunction agentSearchSubdirs(dir: string): string[] {\n let entries: Dirent[];\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return [];\n }\n const result: string[] = [];\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n result.push(full);\n } else if (entry.isSymbolicLink()) {\n try {\n if (statSync(full).isDirectory()) result.push(full);\n } catch {\n // dangling link\n }\n }\n }\n return result.sort();\n}\n\n/**\n * Directories up to `depth` levels below `root` whose `agent.yaml` declares\n * `name`. Indexed by the declared name, never the directory name — the two\n * disagree in practice (`skaile-forge/agent/` declares `forge-project-assistant`).\n */\nfunction findAgentDirsByName(root: string, name: string, depth: number): string[] {\n const matches: string[] = [];\n const visit = (dir: string, remaining: number): void => {\n if (remaining === 0) return;\n for (const child of agentSearchSubdirs(dir)) {\n if (declaredAgentName(join(child, AGENT_MANIFEST_FILE)) === name) matches.push(child);\n visit(child, remaining - 1);\n }\n };\n visit(root, depth);\n return matches;\n}\n\n/**\n * Where `skaile add` / `skaile install` keep the source (`agent.yaml`, `SOUL.md`, …)\n * of every agent they deploy, one `<name>/` directory each. The deployed copy is a\n * harness rendering that has lost the composition an instance needs, so\n * `agent:@pub/name` resolves an added library / source / store agent from here.\n * Under `.skaile/cache/`, so it is not committed and is rebuilt by `skaile install`.\n */\nexport function agentSourceCacheDir(projectDir: string): string {\n return join(projectDir, \".skaile\", \"cache\", \"agents\");\n}\n\n/**\n * Resolve an `agent:<name>` definition to the one agent directory whose\n * `agent.yaml` declares that `name:`. Trees are searched in precedence order\n * and the first tree holding the name wins:\n *\n * 1. `<projectDir>/.skaile/assets/agent/<dir>/` — agents the platform session\n * materializer installed for this workspace.\n * 2. `<projectDir>/agents/<dir>/` — project-local agents.\n * 3. `<projectDir>/.skaile/cache/agents/<dir>/` — agents added with\n * `skaile add` (see {@link agentSourceCacheDir}).\n * 4. The `ai-assets/` catalog found by the same upward walk as `ai-assets://`\n * URIs, searched {@link AI_ASSETS_AGENT_WALK_DEPTH} levels deep (dot-dirs\n * and `node_modules` skipped).\n *\n * @throws AgentRefResolutionError when the ref is malformed, no tree declares\n * the name, or one tree declares it more than once.\n */\nfunction resolveAgentRef(projectDir: string, definition: string): string {\n const name = agentRefName(definition);\n const trees: Array<{ root: string; depth: number }> = [\n { root: join(projectDir, \".skaile\", \"assets\", \"agent\"), depth: 1 },\n { root: join(projectDir, \"agents\"), depth: 1 },\n { root: agentSourceCacheDir(projectDir), depth: 1 },\n ];\n const aiAssetsDir = findAiAssetsDir(projectDir);\n if (aiAssetsDir) trees.push({ root: aiAssetsDir, depth: AI_ASSETS_AGENT_WALK_DEPTH });\n const searched = trees.map((t) => t.root);\n\n for (const { root, depth } of trees) {\n const matches = findAgentDirsByName(root, name, depth);\n if (matches.length === 1) return matches[0];\n if (matches.length > 1) {\n throw new AgentRefResolutionError(\n \"ambiguous\",\n definition,\n `agent.definition \"${definition}\": ${matches.length} agent.yaml files under ${root} ` +\n `declare name \"${name}\": ${matches.join(\", \")}`,\n searched,\n matches,\n );\n }\n }\n\n throw new AgentRefResolutionError(\n \"not_found\",\n definition,\n `agent.definition \"${definition}\": no agent.yaml declaring name \"${name}\" in ` +\n `${searched.join(\", \")}${aiAssetsDir ? \"\" : \" (no ai-assets/ directory above the project)\"}`,\n searched,\n );\n}\n\n/**\n * Resolve the `agent.definition` field from `skaile.yaml` in `projectDir`\n * to an absolute filesystem path.\n *\n * Resolution rules:\n * - Absent or empty → undefined (no agent configured)\n * - Relative/absolute local path → resolve(projectDir, definition)\n * - `ai-assets://<rest>` → walk up for ai-assets/, join with <rest>\n * (undefined when no ai-assets/ is found)\n * - `agent:@<publisher>/<name>[#pin]` or `agent:<name>` → the directory whose\n * `agent.yaml` declares `name: <name>`, searched in\n * `.skaile/assets/agent/` (materialized), then `agents/` (project-local),\n * then `.skaile/cache/agents/` (agents added with `skaile add`), then the\n * walked-up `ai-assets/` catalog. Throws\n * {@link AgentRefResolutionError} when that fails, so \"agent configured\n * but unresolvable\" never looks like \"no agent configured\".\n *\n * Used by the runner to determine agentDir without requiring --agent-dir.\n * @throws AgentRefResolutionError for an `agent:` definition that resolves to\n * no directory or to more than one.\n * @docLink packages/core/workspace-config#resolve-agent-dir\n */\nexport function resolveAgentDir(projectDir: string): string | undefined {\n const config = resolveSkWorkspaceConfig(projectDir);\n const definition = config.agent?.definition;\n if (!definition) return undefined;\n return resolveAgentDefinitionDir(projectDir, definition);\n}\n\n/**\n * Resolve one agent reference — `agent.definition` or an `agents.<id>.ref` —\n * to an absolute directory, by the rules {@link resolveAgentDir} documents.\n * `undefined` only for an `ai-assets://` ref when no `ai-assets/` directory\n * exists above `projectDir`.\n * @throws AgentRefResolutionError for an `agent:` ref that resolves to no\n * directory or to more than one.\n */\nexport function resolveAgentDefinitionDir(\n projectDir: string,\n definition: string,\n): string | undefined {\n // ai-assets:// URI\n if (definition.startsWith(\"ai-assets://\")) {\n const relPath = definition.slice(\"ai-assets://\".length);\n const aiAssetsDir = findAiAssetsDir(projectDir);\n if (!aiAssetsDir) return undefined;\n return join(aiAssetsDir, relPath);\n }\n\n // Catalog reference — indexed by the manifests' declared `name:`.\n if (definition.startsWith(\"agent:\")) {\n return resolveAgentRef(projectDir, definition);\n }\n\n // Local path (relative or absolute)\n return resolve(projectDir, definition);\n}\n"]}