@skaile/workspaces 5.17.0 → 5.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/{asset-feeds-MALYFZUM.js → asset-feeds-MKB5JUML.js} +21 -21
  3. package/dist/{asset-feeds-MALYFZUM.js.map → asset-feeds-MKB5JUML.js.map} +1 -1
  4. package/dist/asset-manager/catalog-deployer.js +8 -8
  5. package/dist/asset-manager/index.js +18 -14
  6. package/dist/asset-manager/installer.js +10 -10
  7. package/dist/asset-manager/renderers.js +9 -9
  8. package/dist/asset-manager/src/index.d.ts +122 -5
  9. package/dist/asset-manager/src/index.d.ts.map +1 -1
  10. package/dist/asset-manager/src/installer.d.ts +13 -10
  11. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  12. package/dist/asset-manager/src/mcp-config.d.ts +61 -1
  13. package/dist/asset-manager/src/mcp-config.d.ts.map +1 -1
  14. package/dist/asset-manager/src/renderers.d.ts.map +1 -1
  15. package/dist/bridge/drivers/claude-sdk.js +12 -12
  16. package/dist/bridge/drivers/codex.js +12 -12
  17. package/dist/bridge/drivers/continue.js +11 -11
  18. package/dist/bridge/drivers/echo.js +27 -8
  19. package/dist/bridge/drivers/echo.js.map +1 -1
  20. package/dist/bridge/drivers/gemini.js +7 -7
  21. package/dist/bridge/drivers/goose.js +11 -11
  22. package/dist/bridge/drivers/omp.js +31 -5
  23. package/dist/bridge/drivers/omp.js.map +1 -1
  24. package/dist/bridge/drivers/opencode.js +11 -11
  25. package/dist/bridge/drivers/qwen.js +7 -7
  26. package/dist/bridge/index.js +14 -14
  27. package/dist/bridge/src/driver-model-check.d.ts +8 -8
  28. package/dist/bridge/src/driver-model-check.d.ts.map +1 -1
  29. package/dist/bridge/src/drivers/echo.d.ts +3 -0
  30. package/dist/bridge/src/drivers/echo.d.ts.map +1 -1
  31. package/dist/bridge/src/drivers/omp-models-yml.d.ts +5 -0
  32. package/dist/bridge/src/drivers/omp-models-yml.d.ts.map +1 -1
  33. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  34. package/dist/bridge/src/index.d.ts +1 -1
  35. package/dist/bridge/src/index.d.ts.map +1 -1
  36. package/dist/{chunk-CWAWYXD5.js → chunk-2ABUJYVI.js} +3 -3
  37. package/dist/{chunk-CWAWYXD5.js.map → chunk-2ABUJYVI.js.map} +1 -1
  38. package/dist/{chunk-ZVZTCDUN.js → chunk-2NOLF7B2.js} +37 -9
  39. package/dist/chunk-2NOLF7B2.js.map +1 -0
  40. package/dist/{chunk-QSLXB44M.js → chunk-34C2EKWJ.js} +3 -3
  41. package/dist/{chunk-QSLXB44M.js.map → chunk-34C2EKWJ.js.map} +1 -1
  42. package/dist/{chunk-3OYOBTY4.js → chunk-3KMREAR2.js} +3 -3
  43. package/dist/{chunk-3OYOBTY4.js.map → chunk-3KMREAR2.js.map} +1 -1
  44. package/dist/{chunk-D54T2F54.js → chunk-5TBFN46Z.js} +4 -4
  45. package/dist/chunk-5TBFN46Z.js.map +1 -0
  46. package/dist/{chunk-PGZDSDOB.js → chunk-6Z5KTFJT.js} +3 -3
  47. package/dist/{chunk-PGZDSDOB.js.map → chunk-6Z5KTFJT.js.map} +1 -1
  48. package/dist/{chunk-WY22FMZF.js → chunk-7ANRSTNR.js} +5 -5
  49. package/dist/{chunk-WY22FMZF.js.map → chunk-7ANRSTNR.js.map} +1 -1
  50. package/dist/{chunk-GYZJKZPJ.js → chunk-7FHZB2QU.js} +3 -3
  51. package/dist/{chunk-GYZJKZPJ.js.map → chunk-7FHZB2QU.js.map} +1 -1
  52. package/dist/{chunk-QBY74UBH.js → chunk-AIBAOXDU.js} +7 -7
  53. package/dist/{chunk-QBY74UBH.js.map → chunk-AIBAOXDU.js.map} +1 -1
  54. package/dist/{chunk-ZPCABSSW.js → chunk-BBWSGVVE.js} +4 -4
  55. package/dist/{chunk-ZPCABSSW.js.map → chunk-BBWSGVVE.js.map} +1 -1
  56. package/dist/{chunk-QEX75L77.js → chunk-BO426QWN.js} +13 -7
  57. package/dist/chunk-BO426QWN.js.map +1 -0
  58. package/dist/{chunk-46IRZJV4.js → chunk-CD7SVH6W.js} +4 -4
  59. package/dist/{chunk-46IRZJV4.js.map → chunk-CD7SVH6W.js.map} +1 -1
  60. package/dist/{chunk-WKEBNB5S.js → chunk-CKBCX3HQ.js} +4 -4
  61. package/dist/{chunk-WKEBNB5S.js.map → chunk-CKBCX3HQ.js.map} +1 -1
  62. package/dist/{chunk-H7R7R5BN.js → chunk-CKICWXMU.js} +18 -15
  63. package/dist/chunk-CKICWXMU.js.map +1 -0
  64. package/dist/{chunk-YK3XLEQJ.js → chunk-CKNIYIV2.js} +83 -77
  65. package/dist/chunk-CKNIYIV2.js.map +1 -0
  66. package/dist/{chunk-SPV2CXJ3.js → chunk-D6UBEYQH.js} +4 -4
  67. package/dist/{chunk-SPV2CXJ3.js.map → chunk-D6UBEYQH.js.map} +1 -1
  68. package/dist/{chunk-D5REDKVU.js → chunk-FKU57Q5Q.js} +3 -3
  69. package/dist/{chunk-D5REDKVU.js.map → chunk-FKU57Q5Q.js.map} +1 -1
  70. package/dist/{chunk-5SWED2LW.js → chunk-GBYNC5V3.js} +3 -3
  71. package/dist/{chunk-5SWED2LW.js.map → chunk-GBYNC5V3.js.map} +1 -1
  72. package/dist/{chunk-YW2BNDSE.js → chunk-GOCWM7FN.js} +22 -4
  73. package/dist/chunk-GOCWM7FN.js.map +1 -0
  74. package/dist/{chunk-ZWUJ22RF.js → chunk-GOK4QRJR.js} +16 -23
  75. package/dist/chunk-GOK4QRJR.js.map +1 -0
  76. package/dist/{chunk-AP24HESN.js → chunk-H6UVIKQ2.js} +3 -3
  77. package/dist/{chunk-AP24HESN.js.map → chunk-H6UVIKQ2.js.map} +1 -1
  78. package/dist/{chunk-ES6ARJPQ.js → chunk-HPVMTX6M.js} +15 -10
  79. package/dist/chunk-HPVMTX6M.js.map +1 -0
  80. package/dist/{chunk-BVXXBZWA.js → chunk-IW6F6R2W.js} +24 -15
  81. package/dist/chunk-IW6F6R2W.js.map +1 -0
  82. package/dist/{chunk-HUKUYWBJ.js → chunk-JYWW32JI.js} +17 -6
  83. package/dist/chunk-JYWW32JI.js.map +1 -0
  84. package/dist/{chunk-5RDZ5JHH.js → chunk-KC6HGWXN.js} +4 -4
  85. package/dist/{chunk-5RDZ5JHH.js.map → chunk-KC6HGWXN.js.map} +1 -1
  86. package/dist/{chunk-FACRITOL.js → chunk-KSBDLCZI.js} +8 -4
  87. package/dist/chunk-KSBDLCZI.js.map +1 -0
  88. package/dist/{chunk-LQT2IKYY.js → chunk-KY4UXX7M.js} +2 -2
  89. package/dist/{chunk-LQT2IKYY.js.map → chunk-KY4UXX7M.js.map} +1 -1
  90. package/dist/{chunk-L6UMSKDF.js → chunk-LW7ZI6EQ.js} +8 -36
  91. package/dist/chunk-LW7ZI6EQ.js.map +1 -0
  92. package/dist/{chunk-DR5ZOEYI.js → chunk-OYIENLJI.js} +32 -18
  93. package/dist/chunk-OYIENLJI.js.map +1 -0
  94. package/dist/{chunk-EOKWTN4N.js → chunk-PBSN4RTV.js} +44 -29
  95. package/dist/chunk-PBSN4RTV.js.map +1 -0
  96. package/dist/{chunk-WXWQNJCT.js → chunk-PUK7TQT4.js} +3 -3
  97. package/dist/{chunk-WXWQNJCT.js.map → chunk-PUK7TQT4.js.map} +1 -1
  98. package/dist/{chunk-5DCOG5B5.js → chunk-RD6N2D7I.js} +3 -3
  99. package/dist/{chunk-5DCOG5B5.js.map → chunk-RD6N2D7I.js.map} +1 -1
  100. package/dist/{chunk-OXUCYHL5.js → chunk-RP3FZ2T6.js} +53 -16
  101. package/dist/chunk-RP3FZ2T6.js.map +1 -0
  102. package/dist/{chunk-6GSE63K2.js → chunk-SRNCN4X2.js} +13 -5
  103. package/dist/chunk-SRNCN4X2.js.map +1 -0
  104. package/dist/{chunk-PIC23DDE.js → chunk-T2TQAH2X.js} +42 -11
  105. package/dist/chunk-T2TQAH2X.js.map +1 -0
  106. package/dist/{chunk-SXWGLW23.js → chunk-U2FI547Z.js} +4 -4
  107. package/dist/{chunk-SXWGLW23.js.map → chunk-U2FI547Z.js.map} +1 -1
  108. package/dist/{chunk-KZWZRNIY.js → chunk-U7V5SIFW.js} +55 -17
  109. package/dist/chunk-U7V5SIFW.js.map +1 -0
  110. package/dist/{chunk-EYDRONKO.js → chunk-V3D4HQMS.js} +4 -4
  111. package/dist/{chunk-EYDRONKO.js.map → chunk-V3D4HQMS.js.map} +1 -1
  112. package/dist/{chunk-D3PU3C6F.js → chunk-VKPBUPH7.js} +41 -15
  113. package/dist/chunk-VKPBUPH7.js.map +1 -0
  114. package/dist/{chunk-W44KA24A.js → chunk-VM3PH7BB.js} +695 -96
  115. package/dist/chunk-VM3PH7BB.js.map +1 -0
  116. package/dist/{chunk-HLETG3CX.js → chunk-VOBXINUZ.js} +3 -3
  117. package/dist/{chunk-HLETG3CX.js.map → chunk-VOBXINUZ.js.map} +1 -1
  118. package/dist/{chunk-FT4ZHLYR.js → chunk-WDXZA7QW.js} +33 -3
  119. package/dist/chunk-WDXZA7QW.js.map +1 -0
  120. package/dist/{chunk-FSSRBWYL.js → chunk-WJCQFNF6.js} +4 -4
  121. package/dist/chunk-WJCQFNF6.js.map +1 -0
  122. package/dist/{chunk-2SKPPIV7.js → chunk-WJLYL6RY.js} +5 -5
  123. package/dist/{chunk-2SKPPIV7.js.map → chunk-WJLYL6RY.js.map} +1 -1
  124. package/dist/{chunk-MMARPEV7.js → chunk-WMF2C5U7.js} +6 -6
  125. package/dist/{chunk-MMARPEV7.js.map → chunk-WMF2C5U7.js.map} +1 -1
  126. package/dist/{chunk-OQN7PCI4.js → chunk-X3AUS4RW.js} +4 -4
  127. package/dist/{chunk-OQN7PCI4.js.map → chunk-X3AUS4RW.js.map} +1 -1
  128. package/dist/{chunk-BBRMS4IC.js → chunk-X6GUNN7X.js} +8 -8
  129. package/dist/{chunk-BBRMS4IC.js.map → chunk-X6GUNN7X.js.map} +1 -1
  130. package/dist/{chunk-QXA2W6UB.js → chunk-XTO436PV.js} +3 -3
  131. package/dist/{chunk-QXA2W6UB.js.map → chunk-XTO436PV.js.map} +1 -1
  132. package/dist/{chunk-QW534EZB.js → chunk-YARXR3CN.js} +53 -8
  133. package/dist/chunk-YARXR3CN.js.map +1 -0
  134. package/dist/{chunk-FSLVMZXR.js → chunk-YZ3N7IUU.js} +72 -31
  135. package/dist/chunk-YZ3N7IUU.js.map +1 -0
  136. package/dist/{chunk-V5CDPKDA.js → chunk-ZBMC6IAE.js} +44 -27
  137. package/dist/chunk-ZBMC6IAE.js.map +1 -0
  138. package/dist/cli/index.js +346 -147
  139. package/dist/cli/index.js.map +1 -1
  140. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  141. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  142. package/dist/cli/src/commands/config.d.ts.map +1 -1
  143. package/dist/cli/src/commands/integration.d.ts.map +1 -1
  144. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  145. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  146. package/dist/cli/src/commands/plugin/claude-code.d.ts.map +1 -1
  147. package/dist/cli/src/commands/plugin/codex.d.ts +6 -0
  148. package/dist/cli/src/commands/plugin/codex.d.ts.map +1 -1
  149. package/dist/cli/src/commands/project.d.ts.map +1 -1
  150. package/dist/cli/src/commands/run.d.ts.map +1 -1
  151. package/dist/cli/src/commands/serve.d.ts +5 -0
  152. package/dist/cli/src/commands/serve.d.ts.map +1 -1
  153. package/dist/cli/src/commands/source.d.ts.map +1 -1
  154. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  155. package/dist/cli/src/commands/verify.d.ts.map +1 -1
  156. package/dist/cli/src/driver-error.d.ts +3 -1
  157. package/dist/cli/src/driver-error.d.ts.map +1 -1
  158. package/dist/cli/src/helpers.d.ts +6 -4
  159. package/dist/cli/src/helpers.d.ts.map +1 -1
  160. package/dist/cli/src/plugin-store/index.d.ts +6 -0
  161. package/dist/cli/src/plugin-store/index.d.ts.map +1 -1
  162. package/dist/cli/src/skill-checks.d.ts +4 -3
  163. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  164. package/dist/connectors/config.js +5 -5
  165. package/dist/connectors/index.js +20 -20
  166. package/dist/connectors/src/connector-manager.d.ts.map +1 -1
  167. package/dist/connectors/src/connector-types.d.ts +5 -0
  168. package/dist/connectors/src/connector-types.d.ts.map +1 -1
  169. package/dist/connectors/src/watcher.d.ts.map +1 -1
  170. package/dist/{connectors-CIEIMJY2.js → connectors-YNQ3WJGM.js} +23 -23
  171. package/dist/{connectors-CIEIMJY2.js.map → connectors-YNQ3WJGM.js.map} +1 -1
  172. package/dist/core/index.js +7 -7
  173. package/dist/core/manifest.js +2 -2
  174. package/dist/core/models.js +1 -1
  175. package/dist/core/publish-manifest.js +3 -3
  176. package/dist/core/ref.js +1 -1
  177. package/dist/core/runtime-assets.js +5 -5
  178. package/dist/core/src/bind.d.ts +30 -0
  179. package/dist/core/src/bind.d.ts.map +1 -0
  180. package/dist/core/src/index.d.ts +4 -3
  181. package/dist/core/src/index.d.ts.map +1 -1
  182. package/dist/core/src/lock.d.ts +11 -2
  183. package/dist/core/src/lock.d.ts.map +1 -1
  184. package/dist/core/src/manifest.d.ts.map +1 -1
  185. package/dist/core/src/models.d.ts +19 -0
  186. package/dist/core/src/models.d.ts.map +1 -1
  187. package/dist/core/src/publish-manifest.d.ts +15 -13
  188. package/dist/core/src/publish-manifest.d.ts.map +1 -1
  189. package/dist/core/src/store.d.ts +2 -1
  190. package/dist/core/src/store.d.ts.map +1 -1
  191. package/dist/core/src/workspace-config.d.ts +26 -1
  192. package/dist/core/src/workspace-config.d.ts.map +1 -1
  193. package/dist/core/store.js +1 -1
  194. package/dist/core/workspace-config.js +4 -4
  195. package/dist/deploy/index.js +7 -7
  196. package/dist/discovery/index.js +5 -5
  197. package/dist/discovery/src/parse-manifest.d.ts +1 -1
  198. package/dist/discovery/src/source-config.d.ts +2 -1
  199. package/dist/discovery/src/source-config.d.ts.map +1 -1
  200. package/dist/{ensure-sources-I62QMZZP.js → ensure-sources-UJWEZSR3.js} +21 -17
  201. package/dist/ensure-sources-UJWEZSR3.js.map +1 -0
  202. package/dist/factory-assets/connectors/box.js +20 -20
  203. package/dist/factory-assets/connectors/deploy.js +20 -20
  204. package/dist/factory-assets/connectors/devserver.js +20 -20
  205. package/dist/factory-assets/connectors/flow/adapter.js +20 -20
  206. package/dist/factory-assets/connectors/flow/engine.js +9 -9
  207. package/dist/factory-assets/connectors/flow/run-flow.js +22 -22
  208. package/dist/factory-assets/connectors/flow.js +20 -20
  209. package/dist/factory-assets/connectors/git.js +20 -20
  210. package/dist/factory-assets/connectors/gmail.js +20 -20
  211. package/dist/factory-assets/connectors/googledrive.js +20 -20
  212. package/dist/factory-assets/connectors/local.js +20 -20
  213. package/dist/factory-assets/connectors/mattermost.js +20 -20
  214. package/dist/factory-assets/connectors/memory.js +20 -20
  215. package/dist/factory-assets/connectors/minio.js +20 -20
  216. package/dist/factory-assets/connectors/postgres.js +20 -20
  217. package/dist/factory-assets/connectors/s3.js +20 -20
  218. package/dist/factory-assets/connectors/sharepoint.js +20 -20
  219. package/dist/factory-assets/connectors/sqlite.js +20 -20
  220. package/dist/factory-assets/connectors/static-server.js +20 -20
  221. package/dist/factory-assets/connectors/tunnel.js +20 -20
  222. package/dist/factory-assets/connectors/webdav.js +20 -20
  223. package/dist/factory-assets/connectors/xstate-store/adapter.d.ts +1 -1
  224. package/dist/factory-assets/connectors/xstate-store/adapter.d.ts.map +1 -1
  225. package/dist/factory-assets/connectors/xstate-store.js +20 -20
  226. package/dist/factory-assets/connectors/xstate.js +20 -20
  227. package/dist/{flows-YKC53LDP.js → flows-BHY73K3O.js} +12 -12
  228. package/dist/{flows-YKC53LDP.js.map → flows-BHY73K3O.js.map} +1 -1
  229. package/dist/{helpers-3FOM37BO.js → helpers-3CG7ZVX4.js} +21 -17
  230. package/dist/{helpers-3FOM37BO.js.map → helpers-3CG7ZVX4.js.map} +1 -1
  231. package/dist/library/index.js +11 -11
  232. package/dist/library/install.js +4 -4
  233. package/dist/library/src/index.d.ts +1 -1
  234. package/dist/library/src/index.d.ts.map +1 -1
  235. package/dist/library/src/manifest-writer.d.ts +17 -1
  236. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  237. package/dist/{library-publish-EFKITCGE.js → library-publish-NWWVYJUK.js} +60 -63
  238. package/dist/library-publish-NWWVYJUK.js.map +1 -0
  239. package/dist/model-endpoint/index.js +10 -10
  240. package/dist/model-endpoint/src/server.d.ts.map +1 -1
  241. package/dist/open-library-7ZG2FFAX.js +42 -0
  242. package/dist/{open-library-NZUI4XGF.js.map → open-library-7ZG2FFAX.js.map} +1 -1
  243. package/dist/open-registry-RBELV5YH.js +32 -0
  244. package/dist/{open-registry-YPRQDUMK.js.map → open-registry-RBELV5YH.js.map} +1 -1
  245. package/dist/paths-BFM6K2QO.js +22 -0
  246. package/dist/{paths-P55DTBEK.js.map → paths-BFM6K2QO.js.map} +1 -1
  247. package/dist/plugin-store-QOQDM24E.js +23 -0
  248. package/dist/{plugin-store-IPIBZRBX.js.map → plugin-store-QOQDM24E.js.map} +1 -1
  249. package/dist/{project-2BNFZ2CR.js → project-YQM3I25D.js} +45 -45
  250. package/dist/{project-2BNFZ2CR.js.map → project-YQM3I25D.js.map} +1 -1
  251. package/dist/resolver/index.js +8 -8
  252. package/dist/runner/index.js +37 -37
  253. package/dist/runner/src/agent.d.ts.map +1 -1
  254. package/dist/runner/src/capability-roundtrip.d.ts.map +1 -1
  255. package/dist/sdk/asset-manager.js +18 -14
  256. package/dist/sdk/bridge.js +14 -14
  257. package/dist/sdk/core.js +7 -7
  258. package/dist/sdk/flow.js +9 -9
  259. package/dist/sdk/index.js +37 -37
  260. package/dist/sdk/resolver.js +8 -8
  261. package/dist/sdk/runner.js +37 -37
  262. package/dist/sdk/transport/ws/server.js +19 -1
  263. package/dist/sdk/transport/ws.js +19 -1
  264. package/dist/sdk/transport.js +19 -1
  265. package/dist/{serve-preflight-V5GM33T3.js → serve-preflight-5QMY7DBC.js} +9 -9
  266. package/dist/{serve-preflight-V5GM33T3.js.map → serve-preflight-5QMY7DBC.js.map} +1 -1
  267. package/dist/{setup-ZMAPTKJW.js → setup-AAHVAXRA.js} +28 -24
  268. package/dist/setup-AAHVAXRA.js.map +1 -0
  269. package/dist/{skills-7G6QCDEM.js → skills-RSZVUIYZ.js} +13 -13
  270. package/dist/{skills-7G6QCDEM.js.map → skills-RSZVUIYZ.js.map} +1 -1
  271. package/dist/{source-6BZA34F5.js → source-KWMCMEMB.js} +47 -47
  272. package/dist/{source-6BZA34F5.js.map → source-KWMCMEMB.js.map} +1 -1
  273. package/dist/{source-manifest-publish-MJXCSUKT.js → source-manifest-publish-EDYKM4YZ.js} +49 -49
  274. package/dist/{source-manifest-publish-MJXCSUKT.js.map → source-manifest-publish-EDYKM4YZ.js.map} +1 -1
  275. package/dist/transport/index.js +19 -1
  276. package/dist/transport/src/ws/server.d.ts +2 -16
  277. package/dist/transport/src/ws/server.d.ts.map +1 -1
  278. package/dist/transport/ws/server.js +19 -1
  279. package/dist/transport/ws.js +19 -1
  280. package/dist/tui/index.js +54 -42
  281. package/dist/tui/index.js.map +1 -1
  282. package/dist/tui/src/repl.d.ts +4 -1
  283. package/dist/tui/src/repl.d.ts.map +1 -1
  284. package/dist/types/manifests.js +1 -1
  285. package/dist/types/src/manifests/index.d.ts +1 -1
  286. package/dist/types/src/manifests/index.d.ts.map +1 -1
  287. package/dist/types/src/manifests/scaffold-body.d.ts +8 -0
  288. package/dist/types/src/manifests/scaffold-body.d.ts.map +1 -1
  289. package/dist/types/src/manifests/skill.d.ts +0 -2
  290. package/dist/types/src/manifests/skill.d.ts.map +1 -1
  291. package/dist/workspace-plugin/adapters/mcp.js +27 -27
  292. package/dist/workspace-plugin/adapters/omp.js +32 -18
  293. package/dist/workspace-plugin/adapters/omp.js.map +1 -1
  294. package/dist/workspace-plugin/index.js +1 -1
  295. package/dist/workspace-plugin/src/adapters/claude-code.d.ts +1 -1
  296. package/dist/workspace-plugin/src/adapters/omp.d.ts +8 -5
  297. package/dist/workspace-plugin/src/adapters/omp.d.ts.map +1 -1
  298. package/dist/workspace-plugin/src/plugin.d.ts +7 -1
  299. package/dist/workspace-plugin/src/plugin.d.ts.map +1 -1
  300. package/package.json +1 -1
  301. package/dist/chunk-6GSE63K2.js.map +0 -1
  302. package/dist/chunk-BVXXBZWA.js.map +0 -1
  303. package/dist/chunk-D3PU3C6F.js.map +0 -1
  304. package/dist/chunk-D54T2F54.js.map +0 -1
  305. package/dist/chunk-DR5ZOEYI.js.map +0 -1
  306. package/dist/chunk-EOKWTN4N.js.map +0 -1
  307. package/dist/chunk-ES6ARJPQ.js.map +0 -1
  308. package/dist/chunk-FACRITOL.js.map +0 -1
  309. package/dist/chunk-FSLVMZXR.js.map +0 -1
  310. package/dist/chunk-FSSRBWYL.js.map +0 -1
  311. package/dist/chunk-FT4ZHLYR.js.map +0 -1
  312. package/dist/chunk-H7R7R5BN.js.map +0 -1
  313. package/dist/chunk-HUKUYWBJ.js.map +0 -1
  314. package/dist/chunk-KZWZRNIY.js.map +0 -1
  315. package/dist/chunk-L6UMSKDF.js.map +0 -1
  316. package/dist/chunk-OXUCYHL5.js.map +0 -1
  317. package/dist/chunk-PIC23DDE.js.map +0 -1
  318. package/dist/chunk-QEX75L77.js.map +0 -1
  319. package/dist/chunk-QW534EZB.js.map +0 -1
  320. package/dist/chunk-V5CDPKDA.js.map +0 -1
  321. package/dist/chunk-W44KA24A.js.map +0 -1
  322. package/dist/chunk-YK3XLEQJ.js.map +0 -1
  323. package/dist/chunk-YW2BNDSE.js.map +0 -1
  324. package/dist/chunk-ZVZTCDUN.js.map +0 -1
  325. package/dist/chunk-ZWUJ22RF.js.map +0 -1
  326. package/dist/ensure-sources-I62QMZZP.js.map +0 -1
  327. package/dist/library-publish-EFKITCGE.js.map +0 -1
  328. package/dist/open-library-NZUI4XGF.js +0 -40
  329. package/dist/open-registry-YPRQDUMK.js +0 -32
  330. package/dist/paths-P55DTBEK.js +0 -22
  331. package/dist/plugin-store-IPIBZRBX.js +0 -23
  332. package/dist/setup-ZMAPTKJW.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../library/src/install/install-from-manifest.ts"],"names":[],"mappings":"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","file":"chunk-SXWGLW23.js","sourcesContent":["/**\n * Pointer-only install path.\n *\n * Given an {@link InstallManifest} (the Pointer Triple the Catalog hands\n * clients), this:\n *\n * 1. fetches the asset bytes directly from the upstream repo at the pinned\n * commit (via an injectable fetcher, default {@link fetchAssetFilesFromGitHub});\n * 2. verifies EVERY per-file SHA256 against `manifest.files[].sha256`;\n * 3. verifies the composite SHA256 rollup over the sorted\n * `<path>:<sha256>\\n` lines against `manifest.sha256`;\n * 4. writes the verified bytes under `<libraryRoot>/@<publisher>/<name>/<version>`.\n *\n * Any hash mismatch is a hard failure — bytes are not written if per-file\n * verification fails, and the composite check is the second gate.\n *\n * @docLink packages/library/concepts#install\n */\n\nimport { createHash } from \"node:crypto\";\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, resolve, sep } from \"node:path\";\nimport type { InstallManifest } from \"@skaile/workspaces/types\";\n// Narrow module, not the `core` barrel: the barrel's chunks carry `import.meta`,\n// which breaks consumers that transpile this entry to CommonJS.\nimport { parseAssetRef } from \"../../../core/src/models.js\";\nimport { compositeSha256 } from \"../../../core/src/publish-manifest.js\";\n\n/**\n * Validate a single manifest-supplied file path against path traversal.\n *\n * `manifest.files[].path` comes off the network — the attacker controls the\n * entire manifest (and therefore every hash in it), so hash verification can\n * NEVER mitigate a malicious *destination*. A path like\n * `../../../../home/user/.bashrc` or an absolute path would escape\n * `installPath` and yield an arbitrary file write. Every path is checked\n * BEFORE any fetch or write happens; the first bad path aborts the entire\n * install with a hard throw.\n *\n * A path is rejected if ANY of:\n * - it is empty;\n * - it is absolute (`path.isAbsolute`) or has a leading slash;\n * - it contains a `..` segment;\n * - `path.resolve(installPath, p)` is not `installPath` itself and does not\n * start with `installPath + path.sep` (escapes the install dir).\n *\n * @throws An error matching `/unsafe path in manifest/` on the first bad path.\n */\nexport function assertSafeManifestPath(installPath: string, p: string): void {\n const bad = (): never => {\n throw new Error(`unsafe path in manifest: ${p}`);\n };\n if (!p || p.length === 0) bad();\n if (isAbsolute(p) || p.startsWith(\"/\") || p.startsWith(\"\\\\\")) bad();\n const segments = p.split(/[/\\\\]/);\n if (segments.some((s) => s === \"..\")) bad();\n const resolved = resolve(installPath, p);\n if (resolved !== installPath && !resolved.startsWith(installPath + sep)) bad();\n}\n\n/**\n * Validate one component (publisher / name / version) of the attacker-controlled\n * `manifest.ref`.\n *\n * `installPath` is built by joining these components onto `libraryRoot`. A\n * component containing a path separator or a `..` / leading-dot segment would\n * let `installPath` itself escape `libraryRoot` — yielding an arbitrary file\n * write AND, via the pre-write `rm(installPath, { recursive })`, an arbitrary\n * recursive delete. The per-file `assertSafeManifestPath` guard cannot catch\n * this: it only validates each `f.path` *relative to* `installPath`, never\n * `installPath` itself. Components must be plain identifier-like strings.\n *\n * @throws An error matching `/unsafe ref/` on a bad component.\n */\nfunction assertSafeRefComponent(kind: string, value: string): void {\n // Reject empty, leading-dot (covers `.` and `..`), path separators, and\n // ASCII control characters (NUL et al.) — fails a malformed segment fast\n // with a domain-specific error rather than a raw EINVAL deeper in.\n const hasControlChar = [...value].some((c) => c.charCodeAt(0) < 0x20);\n if (!value || value.startsWith(\".\") || /[/\\\\]/.test(value) || hasControlChar) {\n throw new Error(`unsafe ref ${kind} component in manifest: '${value}'`);\n }\n}\n\n/**\n * Longest common **directory** prefix across manifest paths, compared by whole\n * slash-delimited segments (never raw-string — so `app/` and `app-data/` never\n * collide). Each path's basename is excluded, so the result is always a\n * directory prefix and every path keeps a non-empty remainder after stripping.\n *\n * Used by flat mode to reproduce the platform pointer-installer's asset-rooting:\n * the store persists repo-root-relative paths (e.g. `skaile-platform/mcpo/xls/MCP.md`)\n * but the runner scans `.skaile/assets/<kind>/<name>/` for immediate-child files,\n * so this prefix is stripped from the WRITE path while the fetch keeps the full\n * repo path. Returns `''` when there is no common directory (a no-op strip).\n */\nexport function longestCommonDirPrefix(paths: readonly string[]): string {\n if (paths.length === 0) return \"\";\n const dirSegments = paths.map((p) => p.split(\"/\").slice(0, -1));\n let common = dirSegments[0]!;\n for (let i = 1; i < dirSegments.length && common.length > 0; i++) {\n const segs = dirSegments[i]!;\n let n = 0;\n while (n < common.length && n < segs.length && common[n] === segs[n]) n++;\n common = common.slice(0, n);\n }\n return common.join(\"/\");\n}\n\n/**\n * Fetcher signature — fetches `{ path → Buffer }` for the requested paths at\n * a pinned upstream commit. {@link fetchAssetFilesFromGitHub} is the default\n * production implementation; tests inject a mock.\n */\nexport type AssetFetcher = (opts: {\n url: string;\n commitSha: string;\n paths: string[];\n}) => Promise<Record<string, Buffer>>;\n\n/**\n * Options for {@link installFromManifest}.\n */\nexport interface InstallOpts {\n /** The pointer-only install manifest from the Catalog. */\n manifest: InstallManifest;\n /** Filesystem root the asset is installed under (ref-derived mode). */\n libraryRoot: string;\n /**\n * Pluggable fetcher so tests can inject mock data. Defaults to\n * {@link fetchAssetFilesFromGitHub} in production.\n */\n fetcher?: AssetFetcher;\n /**\n * Flat-layout mode. When set, install-core reproduces the platform\n * pointer-installer's behavior: it ignores `libraryRoot`/ref-derivation, does\n * NOT parse `manifest.ref` and does NOT verify the composite sha256, strips\n * the longest-common-dir prefix from each path, per-file sha256-verifies, and\n * writes the stripped paths as immediate children of `targetDir` (what the\n * runner's `.skaile/assets/<kind>/<name>/` scan requires). `installPath` is\n * `targetDir`. Absent → unchanged ref-derived `@<pub>/name/version/<path>`\n * layout with composite verify.\n */\n targetDir?: string;\n}\n\n/**\n * Result of a successful {@link installFromManifest} call.\n */\nexport interface InstallResult {\n /** Absolute path the asset files were written to. */\n installPath: string;\n}\n\n/**\n * Fetch, verify, and write an asset's files per its {@link InstallManifest}.\n *\n * @throws An error matching `/hash mismatch/i` if any per-file SHA256 differs.\n * @throws An error matching `/composite hash mismatch/i` if the rollup differs.\n * @throws An error if the ref is malformed or the fetcher omits a file.\n */\nexport async function installFromManifest(opts: InstallOpts): Promise<InstallResult> {\n const { manifest, libraryRoot } = opts;\n const fetcher =\n opts.fetcher ?? (await import(\"./source-fetch-github.js\")).fetchAssetFilesFromGitHub;\n\n // Flat mode: reproduce the platform pointer-installer's asset-rooted layout.\n // No ref parse, no composite verify — the platform store may not satisfy a\n // ref-grammar or composite, and the runner only needs immediate-child files.\n if (opts.targetDir !== undefined) {\n return installFlat(manifest, opts.targetDir, fetcher);\n }\n\n // 1. Parse ref into install path: `skill:@x/git#1.0.0` → `<root>/@x/git/1.0.0`.\n // Done first so the C1 path-traversal guard can resolve against installPath\n // BEFORE any network fetch happens. The ref is attacker-controlled, so each\n // segment is further validated as a safe path component (H1) after parsing.\n // `parseAssetRef` is the single canonical grammar (`kind:@publisher/name#version`);\n // the legacy trailing-`@version` shape was removed in core and is rejected here.\n let parsed: ReturnType<typeof parseAssetRef>;\n try {\n parsed = parseAssetRef(manifest.ref);\n } catch (e) {\n throw new Error(`invalid ref: ${manifest.ref}: ${e instanceof Error ? e.message : String(e)}`);\n }\n const publisher = parsed.publisher;\n const name = parsed.name;\n const version = parsed.pin;\n if (!publisher) throw new Error(`invalid ref: ${manifest.ref} (missing publisher)`);\n if (!version) throw new Error(`invalid ref: ${manifest.ref} (missing version pin)`);\n assertSafeRefComponent(\"publisher\", publisher);\n assertSafeRefComponent(\"name\", name);\n assertSafeRefComponent(\"version\", version);\n const root = resolve(libraryRoot);\n const installPath = resolve(join(root, `@${publisher}`, name, version));\n // Defense in depth: even with the segment guards above, assert the built\n // installPath stays strictly inside libraryRoot before any write or `rm`.\n if (installPath !== root && !installPath.startsWith(root + sep)) {\n throw new Error(`unsafe install path: ref '${manifest.ref}' resolves outside the library root`);\n }\n\n // 2. [C1] Validate EVERY manifest path against traversal BEFORE fetching.\n // The attacker controls the manifest (and thus all hashes) — hashes verify\n // content, never destination. Reject the whole install on the first bad path.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n }\n\n // 3. Fetch all files at the pinned commit.\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // 4. Verify per-file SHA256 — hard fail before writing anything. The path\n // key used to read from the fetcher result is re-guarded as defense in depth.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n }\n\n // 5. Verify composite SHA256 over the sorted `<path>:<sha256>\\n` lines.\n const actualComposite = compositeSha256(manifest.files);\n if (actualComposite !== manifest.sha256) {\n throw new Error(`composite hash mismatch: expected ${manifest.sha256}, got ${actualComposite}`);\n }\n\n // 6. [M1] Write all verified files. A failed install must leave NO partial\n // directory: any prior `installPath` is removed first (clean overwrite), and\n // a mid-loop write failure removes the partially-written tree before\n // rethrowing.\n await rm(installPath, { recursive: true, force: true });\n try {\n for (const f of manifest.files) {\n const target = join(installPath, f.path);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, bytes[f.path]!);\n }\n } catch (e) {\n await rm(installPath, { recursive: true, force: true }).catch(() => {});\n throw e;\n }\n\n return { installPath };\n}\n\n/**\n * Flat-layout install — the platform pointer-installer's behavior, made canonical\n * in install-core. Validates every path, fetches with the FULL repo paths, per-file\n * sha256-verifies, then strips the longest-common-dir prefix and writes each file\n * as `join(targetDir, path.slice(assetRoot.length + 1))` — immediate children of\n * `targetDir`. No ref parse, no composite check.\n */\nasync function installFlat(\n manifest: InstallManifest,\n targetDir: string,\n fetcher: AssetFetcher,\n): Promise<InstallResult> {\n const target = resolve(targetDir);\n\n // Gate every path before any fetch — the attacker controls the whole manifest.\n for (const f of manifest.files) {\n assertSafeManifestPath(target, f.path);\n }\n\n // Fetch keys off the FULL repo path (matches the upstream tree).\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // Strip the asset-root dir prefix from the WRITE path only — the fetch above\n // still keyed off the full repo path. Stripping removes leading whole segments\n // (never the basename), so a non-empty remainder always survives.\n const assetRoot = longestCommonDirPrefix(paths);\n\n for (const f of manifest.files) {\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n const relPath = assetRoot ? f.path.slice(assetRoot.length + 1) : f.path;\n // Re-guard the post-strip destination — it is what we actually write.\n assertSafeManifestPath(target, relPath);\n const dest = join(target, relPath);\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, buf);\n }\n\n return { installPath: target };\n}\n"]}
1
+ {"version":3,"sources":["../library/src/install/install-from-manifest.ts"],"names":[],"mappings":"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","file":"chunk-U2FI547Z.js","sourcesContent":["/**\n * Pointer-only install path.\n *\n * Given an {@link InstallManifest} (the Pointer Triple the Catalog hands\n * clients), this:\n *\n * 1. fetches the asset bytes directly from the upstream repo at the pinned\n * commit (via an injectable fetcher, default {@link fetchAssetFilesFromGitHub});\n * 2. verifies EVERY per-file SHA256 against `manifest.files[].sha256`;\n * 3. verifies the composite SHA256 rollup over the sorted\n * `<path>:<sha256>\\n` lines against `manifest.sha256`;\n * 4. writes the verified bytes under `<libraryRoot>/@<publisher>/<name>/<version>`.\n *\n * Any hash mismatch is a hard failure — bytes are not written if per-file\n * verification fails, and the composite check is the second gate.\n *\n * @docLink packages/library/concepts#install\n */\n\nimport { createHash } from \"node:crypto\";\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, resolve, sep } from \"node:path\";\nimport type { InstallManifest } from \"@skaile/workspaces/types\";\n// Narrow module, not the `core` barrel: the barrel's chunks carry `import.meta`,\n// which breaks consumers that transpile this entry to CommonJS.\nimport { parseAssetRef } from \"../../../core/src/models.js\";\nimport { compositeSha256 } from \"../../../core/src/publish-manifest.js\";\n\n/**\n * Validate a single manifest-supplied file path against path traversal.\n *\n * `manifest.files[].path` comes off the network — the attacker controls the\n * entire manifest (and therefore every hash in it), so hash verification can\n * NEVER mitigate a malicious *destination*. A path like\n * `../../../../home/user/.bashrc` or an absolute path would escape\n * `installPath` and yield an arbitrary file write. Every path is checked\n * BEFORE any fetch or write happens; the first bad path aborts the entire\n * install with a hard throw.\n *\n * A path is rejected if ANY of:\n * - it is empty;\n * - it is absolute (`path.isAbsolute`) or has a leading slash;\n * - it contains a `..` segment;\n * - `path.resolve(installPath, p)` is not `installPath` itself and does not\n * start with `installPath + path.sep` (escapes the install dir).\n *\n * @throws An error matching `/unsafe path in manifest/` on the first bad path.\n */\nexport function assertSafeManifestPath(installPath: string, p: string): void {\n const bad = (): never => {\n throw new Error(`unsafe path in manifest: ${p}`);\n };\n if (!p || p.length === 0) bad();\n if (isAbsolute(p) || p.startsWith(\"/\") || p.startsWith(\"\\\\\")) bad();\n const segments = p.split(/[/\\\\]/);\n if (segments.some((s) => s === \"..\")) bad();\n const resolved = resolve(installPath, p);\n if (resolved !== installPath && !resolved.startsWith(installPath + sep)) bad();\n}\n\n/**\n * Validate one component (publisher / name / version) of the attacker-controlled\n * `manifest.ref`.\n *\n * `installPath` is built by joining these components onto `libraryRoot`. A\n * component containing a path separator or a `..` / leading-dot segment would\n * let `installPath` itself escape `libraryRoot` — yielding an arbitrary file\n * write AND, via the pre-write `rm(installPath, { recursive })`, an arbitrary\n * recursive delete. The per-file `assertSafeManifestPath` guard cannot catch\n * this: it only validates each `f.path` *relative to* `installPath`, never\n * `installPath` itself. Components must be plain identifier-like strings.\n *\n * @throws An error matching `/unsafe ref/` on a bad component.\n */\nfunction assertSafeRefComponent(kind: string, value: string): void {\n // Reject empty, leading-dot (covers `.` and `..`), path separators, and\n // ASCII control characters (NUL et al.) — fails a malformed segment fast\n // with a domain-specific error rather than a raw EINVAL deeper in.\n const hasControlChar = [...value].some((c) => c.charCodeAt(0) < 0x20);\n if (!value || value.startsWith(\".\") || /[/\\\\]/.test(value) || hasControlChar) {\n throw new Error(`unsafe ref ${kind} component in manifest: '${value}'`);\n }\n}\n\n/**\n * Longest common **directory** prefix across manifest paths, compared by whole\n * slash-delimited segments (never raw-string — so `app/` and `app-data/` never\n * collide). Each path's basename is excluded, so the result is always a\n * directory prefix and every path keeps a non-empty remainder after stripping.\n *\n * Used by flat mode to reproduce the platform pointer-installer's asset-rooting:\n * the store persists repo-root-relative paths (e.g. `skaile-platform/mcpo/xls/MCP.md`)\n * but the runner scans `.skaile/assets/<kind>/<name>/` for immediate-child files,\n * so this prefix is stripped from the WRITE path while the fetch keeps the full\n * repo path. Returns `''` when there is no common directory (a no-op strip).\n */\nexport function longestCommonDirPrefix(paths: readonly string[]): string {\n if (paths.length === 0) return \"\";\n const dirSegments = paths.map((p) => p.split(\"/\").slice(0, -1));\n let common = dirSegments[0]!;\n for (let i = 1; i < dirSegments.length && common.length > 0; i++) {\n const segs = dirSegments[i]!;\n let n = 0;\n while (n < common.length && n < segs.length && common[n] === segs[n]) n++;\n common = common.slice(0, n);\n }\n return common.join(\"/\");\n}\n\n/**\n * Fetcher signature — fetches `{ path → Buffer }` for the requested paths at\n * a pinned upstream commit. {@link fetchAssetFilesFromGitHub} is the default\n * production implementation; tests inject a mock.\n */\nexport type AssetFetcher = (opts: {\n url: string;\n commitSha: string;\n paths: string[];\n}) => Promise<Record<string, Buffer>>;\n\n/**\n * Options for {@link installFromManifest}.\n */\nexport interface InstallOpts {\n /** The pointer-only install manifest from the Catalog. */\n manifest: InstallManifest;\n /** Filesystem root the asset is installed under (ref-derived mode). */\n libraryRoot: string;\n /**\n * Pluggable fetcher so tests can inject mock data. Defaults to\n * {@link fetchAssetFilesFromGitHub} in production.\n */\n fetcher?: AssetFetcher;\n /**\n * Flat-layout mode. When set, install-core reproduces the platform\n * pointer-installer's behavior: it ignores `libraryRoot`/ref-derivation, does\n * NOT parse `manifest.ref` and does NOT verify the composite sha256, strips\n * the longest-common-dir prefix from each path, per-file sha256-verifies, and\n * writes the stripped paths as immediate children of `targetDir` (what the\n * runner's `.skaile/assets/<kind>/<name>/` scan requires). `installPath` is\n * `targetDir`. Absent → unchanged ref-derived `@<pub>/name/version/<path>`\n * layout with composite verify.\n */\n targetDir?: string;\n}\n\n/**\n * Result of a successful {@link installFromManifest} call.\n */\nexport interface InstallResult {\n /** Absolute path the asset files were written to. */\n installPath: string;\n}\n\n/**\n * Fetch, verify, and write an asset's files per its {@link InstallManifest}.\n *\n * @throws An error matching `/hash mismatch/i` if any per-file SHA256 differs.\n * @throws An error matching `/composite hash mismatch/i` if the rollup differs.\n * @throws An error if the ref is malformed or the fetcher omits a file.\n */\nexport async function installFromManifest(opts: InstallOpts): Promise<InstallResult> {\n const { manifest, libraryRoot } = opts;\n const fetcher =\n opts.fetcher ?? (await import(\"./source-fetch-github.js\")).fetchAssetFilesFromGitHub;\n\n // Flat mode: reproduce the platform pointer-installer's asset-rooted layout.\n // No ref parse, no composite verify — the platform store may not satisfy a\n // ref-grammar or composite, and the runner only needs immediate-child files.\n if (opts.targetDir !== undefined) {\n return installFlat(manifest, opts.targetDir, fetcher);\n }\n\n // 1. Parse ref into install path: `skill:@x/git#1.0.0` → `<root>/@x/git/1.0.0`.\n // Done first so the C1 path-traversal guard can resolve against installPath\n // BEFORE any network fetch happens. The ref is attacker-controlled, so each\n // segment is further validated as a safe path component (H1) after parsing.\n // `parseAssetRef` is the single canonical grammar (`kind:@publisher/name#version`);\n // the legacy trailing-`@version` shape was removed in core and is rejected here.\n let parsed: ReturnType<typeof parseAssetRef>;\n try {\n parsed = parseAssetRef(manifest.ref);\n } catch (e) {\n throw new Error(`invalid ref: ${manifest.ref}: ${e instanceof Error ? e.message : String(e)}`);\n }\n const publisher = parsed.publisher;\n const name = parsed.name;\n const version = parsed.pin;\n if (!publisher) throw new Error(`invalid ref: ${manifest.ref} (missing publisher)`);\n if (!version) throw new Error(`invalid ref: ${manifest.ref} (missing version pin)`);\n assertSafeRefComponent(\"publisher\", publisher);\n assertSafeRefComponent(\"name\", name);\n assertSafeRefComponent(\"version\", version);\n const root = resolve(libraryRoot);\n const installPath = resolve(join(root, `@${publisher}`, name, version));\n // Defense in depth: even with the segment guards above, assert the built\n // installPath stays strictly inside libraryRoot before any write or `rm`.\n if (installPath !== root && !installPath.startsWith(root + sep)) {\n throw new Error(`unsafe install path: ref '${manifest.ref}' resolves outside the library root`);\n }\n\n // 2. [C1] Validate EVERY manifest path against traversal BEFORE fetching.\n // The attacker controls the manifest (and thus all hashes) — hashes verify\n // content, never destination. Reject the whole install on the first bad path.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n }\n\n // 3. Fetch all files at the pinned commit.\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // 4. Verify per-file SHA256 — hard fail before writing anything. The path\n // key used to read from the fetcher result is re-guarded as defense in depth.\n for (const f of manifest.files) {\n assertSafeManifestPath(installPath, f.path);\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n }\n\n // 5. Verify composite SHA256 over the sorted `<path>:<sha256>\\n` lines.\n const actualComposite = compositeSha256(manifest.files);\n if (actualComposite !== manifest.sha256) {\n throw new Error(`composite hash mismatch: expected ${manifest.sha256}, got ${actualComposite}`);\n }\n\n // 6. [M1] Write all verified files. A failed install must leave NO partial\n // directory: any prior `installPath` is removed first (clean overwrite), and\n // a mid-loop write failure removes the partially-written tree before\n // rethrowing.\n await rm(installPath, { recursive: true, force: true });\n try {\n for (const f of manifest.files) {\n const target = join(installPath, f.path);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, bytes[f.path]!);\n }\n } catch (e) {\n await rm(installPath, { recursive: true, force: true }).catch(() => {});\n throw e;\n }\n\n return { installPath };\n}\n\n/**\n * Flat-layout install — the platform pointer-installer's behavior, made canonical\n * in install-core. Validates every path, fetches with the FULL repo paths, per-file\n * sha256-verifies, then strips the longest-common-dir prefix and writes each file\n * as `join(targetDir, path.slice(assetRoot.length + 1))` — immediate children of\n * `targetDir`. No ref parse, no composite check.\n */\nasync function installFlat(\n manifest: InstallManifest,\n targetDir: string,\n fetcher: AssetFetcher,\n): Promise<InstallResult> {\n const target = resolve(targetDir);\n\n // Gate every path before any fetch — the attacker controls the whole manifest.\n for (const f of manifest.files) {\n assertSafeManifestPath(target, f.path);\n }\n\n // Fetch keys off the FULL repo path (matches the upstream tree).\n const paths = manifest.files.map((f) => f.path);\n const bytes = await fetcher({\n url: manifest.source.url,\n commitSha: manifest.source.commitSha,\n paths,\n });\n\n // Strip the asset-root dir prefix from the WRITE path only — the fetch above\n // still keyed off the full repo path. Stripping removes leading whole segments\n // (never the basename), so a non-empty remainder always survives.\n const assetRoot = longestCommonDirPrefix(paths);\n\n for (const f of manifest.files) {\n const buf = bytes[f.path];\n if (!buf) throw new Error(`fetcher returned no bytes for ${f.path}`);\n const actual = createHash(\"sha256\").update(buf).digest(\"hex\");\n if (actual !== f.sha256) {\n throw new Error(`hash mismatch for ${f.path}: expected ${f.sha256}, got ${actual}`);\n }\n const relPath = assetRoot ? f.path.slice(assetRoot.length + 1) : f.path;\n // Re-guard the post-strip destination — it is what we actually write.\n assertSafeManifestPath(target, relPath);\n const dest = join(target, relPath);\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, buf);\n }\n\n return { installPath: target };\n}\n"]}
@@ -1,17 +1,17 @@
1
- import { registeredAssetKeys, unresolvedManifestDependencies, warnIgnoredDomainFiles, warnLegacyBundleFiles, removedDomainOption, rejectRemovedDomainOption, reportLibrarySymlinks, composeRefContext, assetEntryRef, manifestPublisherProblems, manifestRootProblems, manifestEntryNameProblems, manifestRequiresProblems, findAssetManifestFile, declaredVersion, manifestVersionMismatchMessage, checkAsset, invalidSemverText } from './chunk-OXUCYHL5.js';
2
- import { AI_RESOURCES } from './chunk-WKEBNB5S.js';
3
- import { logErr, logInfo, logWarn, logOk } from './chunk-QEX75L77.js';
4
- import { getKindRegistry } from './chunk-2SKPPIV7.js';
5
- import { validateFlowVersions } from './chunk-D5REDKVU.js';
6
- import { loadFlow } from './chunk-SPV2CXJ3.js';
1
+ import { registeredAssetKeys, unresolvedManifestDependencies, warnIgnoredDomainFiles, warnLegacyBundleFiles, removedDomainOption, rejectRemovedDomainOption, reportLibrarySymlinks, composeRefContext, assetEntryRef, manifestPublisherProblems, manifestRootProblems, manifestEntryNameProblems, manifestRequiresProblems, findAssetManifestFile, declaredVersion, manifestVersionMismatchMessage, checkAsset, invalidPublisherMessage, invalidSemverText } from './chunk-RP3FZ2T6.js';
2
+ import { AI_RESOURCES } from './chunk-CKBCX3HQ.js';
3
+ import { logErr, logInfo, logWarn, logOk } from './chunk-BO426QWN.js';
4
+ import { getKindRegistry } from './chunk-WJLYL6RY.js';
5
+ import { validateFlowVersions } from './chunk-FKU57Q5Q.js';
6
+ import { loadFlow } from './chunk-D6UBEYQH.js';
7
7
  import { flowSkillVersionPins } from './chunk-7RGTAEG6.js';
8
- import { missingRootAssets, assertManifestEditable } from './chunk-D3PU3C6F.js';
9
- import { parseManifestFile } from './chunk-ES6ARJPQ.js';
10
- import { resolveRuntimeAssets } from './chunk-5RDZ5JHH.js';
11
- import { decodeSkaileYaml, normalizeAgentInstances, agentBlockKeyDiagnostics, agentInstanceDiagnostics, localConnectorMountDir, isInsideProject, resolveAgentDefinitionDir, AgentRefResolutionError } from './chunk-ZVZTCDUN.js';
12
- import { SKAILE_MANIFEST_FILENAME, loadSkPublishManifest, isNonAssetPath } from './chunk-H7R7R5BN.js';
13
- import { readAssetBody } from './chunk-YW2BNDSE.js';
14
- import { parseAssetRef, isValidAssetName, ASSET_NAME_HINT } from './chunk-FT4ZHLYR.js';
8
+ import { missingRootAssets, assertManifestEditable, scanUnlistedAssets, UNLISTED_SCAN_SKIP_DIRS } from './chunk-VKPBUPH7.js';
9
+ import { parseManifestFile } from './chunk-HPVMTX6M.js';
10
+ import { resolveRuntimeAssets } from './chunk-KC6HGWXN.js';
11
+ import { decodeSkaileYaml, normalizeAgentInstances, agentBlockKeyDiagnostics, agentInstanceDiagnostics, localConnectorMountDir, symlinkEscapeOfProject, isInsideProject, resolveAgentDefinitionDir, AgentRefResolutionError } from './chunk-2NOLF7B2.js';
12
+ import { SKAILE_MANIFEST_FILENAME, loadSkPublishManifest, isNonAssetPath } from './chunk-CKICWXMU.js';
13
+ import { readAssetBody } from './chunk-GOCWM7FN.js';
14
+ import { parseAssetRef, isValidPublisher, isValidAssetName, ASSET_NAME_HINT } from './chunk-WDXZA7QW.js';
15
15
  import { execFileSync } from 'child_process';
16
16
  import fs2 from 'fs';
17
17
  import path2 from 'path';
@@ -240,6 +240,8 @@ var MANIFEST_GLOBS = [
240
240
  { pattern: /\/agent\.yaml$/, kind: "agent" },
241
241
  { pattern: /\/AGENT\.md$/, kind: "agent" },
242
242
  { pattern: /\/CONTRACT\.md$/, kind: "contract" },
243
+ { pattern: /\/PERSONA\.md$/, kind: "persona" },
244
+ { pattern: /\/RULESET\.md$/, kind: "ruleset" },
243
245
  { pattern: /\.flow\.yaml$/, kind: "flow" },
244
246
  { pattern: /\.flow\.json$/, kind: "flow" },
245
247
  { pattern: /\/CONNECTOR\.md$/, kind: "connector" },
@@ -448,7 +450,12 @@ function validateWorkspaceRefs(refFields, relPath) {
448
450
  let errors = 0;
449
451
  for (const [field, ref] of refFields) {
450
452
  try {
451
- parseAssetRef(ref);
453
+ const parsedRef = parseAssetRef(ref);
454
+ const publisher = parsedRef.publisher?.replace(/^@/, "");
455
+ if (publisher !== void 0 && !isValidPublisher(publisher)) {
456
+ logErr(`${relPath} [${field}] \u2014 ${ref}: ${invalidPublisherMessage(publisher)}`);
457
+ errors++;
458
+ }
452
459
  } catch (e) {
453
460
  logErr(`${relPath} [${field}] \u2014 ${e instanceof Error ? e.message : String(e)}`);
454
461
  errors++;
@@ -492,11 +499,17 @@ function validateLocalConnectorMountPaths(projectDir, relPath, connectors) {
492
499
  if (c.driver !== "local" || c.mount) continue;
493
500
  const dir = localConnectorMountDir(c, projectDir);
494
501
  if (!dir) continue;
502
+ const escapesTo = symlinkEscapeOfProject(dir, projectDir);
495
503
  if (!fs2.existsSync(dir)) {
496
504
  logErr(
497
505
  `${relPath} [connectors] \u2014 connector_mount_path_missing: connectors.${c.id}.mountPath: ${dir} does not exist; create the directory or fix the path`
498
506
  );
499
507
  errors++;
508
+ } else if (escapesTo !== null) {
509
+ logErr(
510
+ `${relPath} [connectors] \u2014 connector_mount_path_symlink: connectors.${c.id}.mountPath: ${dir} is a symlink to ${escapesTo}, outside the project ${projectDir}; point mountPath at the real directory`
511
+ );
512
+ errors++;
500
513
  } else if (!isInsideProject(dir, projectDir)) {
501
514
  logWarn(
502
515
  `${relPath} [connectors] \u2014 connectors.${c.id}.mountPath: ${dir} is outside the project ${projectDir}; the agent reads${c.access === "read-write" ? " and writes" : ""} there`
@@ -566,6 +579,23 @@ function validatePublishManifestRoots(rootPath) {
566
579
  }
567
580
  return missing.length;
568
581
  }
582
+ async function validatePublishManifestUnlisted(rootPath) {
583
+ const absRoot = path2.resolve(rootPath);
584
+ const manifest = loadSkPublishManifest(absRoot);
585
+ if (!manifest) return 0;
586
+ const unlisted = (await scanUnlistedAssets(
587
+ absRoot,
588
+ manifest.publisher ?? path2.basename(absRoot),
589
+ getKindRegistry(),
590
+ UNLISTED_SCAN_SKIP_DIRS
591
+ )).filter((u) => !u.registeredAt);
592
+ for (const u of unlisted) {
593
+ logErr(
594
+ `${path2.relative(absRoot, u.entry.source)} [${u.entry.kind}] \u2014 ${u.entry.kind}:${u.entry.name} is on disk but not in ${SKAILE_MANIFEST_FILENAME}, so it is not published. Run \`skaile library index <library>\` to list it, or delete the directory.`
595
+ );
596
+ }
597
+ return unlisted.length;
598
+ }
569
599
  function validatePublishManifestRequires(rootPath) {
570
600
  const problems = manifestRequiresProblems(path2.resolve(rootPath));
571
601
  for (const p of problems) {
@@ -896,6 +926,13 @@ function runVersionsCheck(pathArg, opts) {
896
926
  return;
897
927
  }
898
928
  let assets = collectAssetVersions(root);
929
+ if (assets.length === 0) {
930
+ logErr(
931
+ `Nothing to check in ${root}: no versioned asset (skill, agent, flow, prompt, contract or preset) found. Pass the library directory.`
932
+ );
933
+ process.exit(1);
934
+ return;
935
+ }
899
936
  if (opts.changedOnly) {
900
937
  const changed = changedFiles(root, "HEAD", "--changed-only", { untracked: true });
901
938
  if (changed === null) {
@@ -953,12 +990,13 @@ function makeValidateCommand() {
953
990
  const rootPathErrors = validatePublishManifestRootPaths(absPath);
954
991
  const parseErrors = validatePublishManifestParses(absPath);
955
992
  const requiresErrors = validatePublishManifestRequires(absPath);
993
+ const unlistedErrors = await validatePublishManifestUnlisted(absPath);
956
994
  const versionWarnings = validatePublishManifestVersions(absPath);
957
995
  const publisherWarnings = validatePublishManifestPublishers(absPath);
958
996
  const dependencyProblems = await unresolvedManifestDependencies(absPath);
959
997
  for (const w of dependencyProblems) logWarn(w);
960
998
  const dependencyWarnings = dependencyProblems.length;
961
- const totalErrors = errors + ws.errors + rootErrors + slugErrors + rootPathErrors + parseErrors + requiresErrors;
999
+ const totalErrors = errors + ws.errors + rootErrors + slugErrors + rootPathErrors + parseErrors + requiresErrors + unlistedErrors;
962
1000
  console.log();
963
1001
  warnIgnoredDomainFiles(absPath);
964
1002
  warnLegacyBundleFiles(absPath);
@@ -1012,5 +1050,5 @@ function makeValidateCommand() {
1012
1050
  }
1013
1051
 
1014
1052
  export { isRecord, makeValidateCommand, scanIdentities };
1015
- //# sourceMappingURL=chunk-KZWZRNIY.js.map
1016
- //# sourceMappingURL=chunk-KZWZRNIY.js.map
1053
+ //# sourceMappingURL=chunk-U7V5SIFW.js.map
1054
+ //# sourceMappingURL=chunk-U7V5SIFW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../cli/src/type-guards.ts","../cli/src/commands/validate-instances.ts","../cli/src/commands/validate.ts"],"names":["path","fs","parseYaml","err","parsed","a","c"],"mappings":"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","file":"chunk-U7V5SIFW.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 * `skaile validate` rules for the root `agents:` map of one `skaile.yaml`.\n *\n * Normalisation errors, the `agent:` + `agents.default` conflict, and the\n * asset-dependent rules: every `ref` resolves to an `agent.yaml`, role\n * instances need the asset's `io`, `connectors` bind real connector slots to\n * real `connectors[]` ids, and trigger ids are unique and known.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n AgentRefResolutionError,\n type AgentInstanceConfig,\n type AgentInstanceTrigger,\n agentBlockKeyDiagnostics,\n agentInstanceDiagnostics,\n type Diagnostic,\n normalizeAgentInstances,\n resolveAgentDefinitionDir,\n} from \"@skaile/workspaces/core\";\nimport { parse as parseYaml } from \"yaml\";\nimport { isRecord } from \"../type-guards.ts\";\n\nconst AGENT_MANIFEST_FILE = \"agent.yaml\";\n\n/** Fields a trigger needs when it declares itself in full (no asset trigger to override). */\nconst TRIGGER_REQUIRED_FIELDS: Record<NonNullable<AgentInstanceTrigger[\"kind\"]>, string[]> = {\n schedule: [\"cron\", \"prompt\"],\n webhook: [\"prompt\"],\n channel: [\"when\"],\n event: [\"event\"],\n};\n\nconst err = (code: string, message: string, at: string): Diagnostic => ({\n code,\n severity: \"error\",\n message,\n path: at,\n});\n\n/** The parts of an agent asset the instance rules read. */\ninterface AssetFacts {\n lifecycle: unknown;\n hasIo: boolean;\n /** `composes[].id` of `kind: connector` items. */\n connectorSlots: string[];\n /** `composes[].id` of every other item that has one. */\n otherSlots: string[];\n triggerIds: string[];\n}\n\nfunction readAssetFacts(manifest: Record<string, unknown>): AssetFacts {\n const facts: AssetFacts = {\n lifecycle: manifest.lifecycle,\n hasIo: manifest.io !== undefined && manifest.io !== null,\n connectorSlots: [],\n otherSlots: [],\n triggerIds: [],\n };\n for (const item of Array.isArray(manifest.composes) ? manifest.composes : []) {\n if (!isRecord(item) || typeof item.id !== \"string\") continue;\n (item.kind === \"connector\" ? facts.connectorSlots : facts.otherSlots).push(item.id);\n }\n for (const t of Array.isArray(manifest.triggers) ? manifest.triggers : []) {\n if (isRecord(t) && typeof t.id === \"string\") facts.triggerIds.push(t.id);\n }\n return facts;\n}\n\n/** Resolve an instance `ref` to its parsed `agent.yaml`, or an error diagnostic. */\nfunction loadAsset(\n projectDir: string,\n id: string,\n ref: string,\n): { facts: AssetFacts } | { diagnostic: Diagnostic } {\n const at = `agents.${id}.ref`;\n let dir: string | undefined;\n try {\n dir = resolveAgentDefinitionDir(projectDir, ref);\n } catch (e) {\n if (!(e instanceof AgentRefResolutionError)) throw e;\n return { diagnostic: err(\"agent_ref_unresolved\", `agents.${id}: ${e.message}`, at) };\n }\n if (dir === undefined) {\n return {\n diagnostic: err(\n \"agent_ref_unresolved\",\n `agents.${id}: ref \"${ref}\" cannot be resolved — no ai-assets/ directory above the project`,\n at,\n ),\n };\n }\n const manifestPath = path.join(dir, AGENT_MANIFEST_FILE);\n let text: string;\n try {\n text = fs.readFileSync(manifestPath, \"utf-8\");\n } catch {\n return {\n diagnostic: err(\n \"agent_ref_unresolved\",\n `agents.${id}: ref \"${ref}\" resolves to ${dir}, which has no ${AGENT_MANIFEST_FILE}`,\n at,\n ),\n };\n }\n let manifest: unknown;\n try {\n manifest = parseYaml(text);\n } catch (e) {\n return {\n diagnostic: err(\n \"agent_manifest_invalid\",\n `agents.${id}: ${manifestPath} is not valid YAML: ${e instanceof Error ? e.message : String(e)}`,\n at,\n ),\n };\n }\n if (!isRecord(manifest)) {\n return {\n diagnostic: err(\n \"agent_manifest_invalid\",\n `agents.${id}: ${manifestPath} is not a mapping`,\n at,\n ),\n };\n }\n return { facts: readAssetFacts(manifest) };\n}\n\n/**\n * Trigger rules. Duplicate ids are always an error; the asset-dependent rules\n * (known id, complete full declaration) run only when `assetTriggerIds` is\n * known — i.e. the instance's `ref` resolved.\n */\nfunction checkTriggers(\n id: string,\n triggers: AgentInstanceTrigger[],\n assetTriggerIds: string[] | undefined,\n): Diagnostic[] {\n const out: Diagnostic[] = [];\n const seen = new Set<string>();\n triggers.forEach((trigger, i) => {\n const at = `agents.${id}.triggers[${i}]`;\n if (seen.has(trigger.id)) {\n out.push(\n err(\n \"agent_trigger_duplicate\",\n `agents.${id}: trigger id \"${trigger.id}\" is declared twice`,\n `${at}.id`,\n ),\n );\n return;\n }\n seen.add(trigger.id);\n if (!assetTriggerIds || assetTriggerIds.includes(trigger.id)) return;\n if (!trigger.kind) {\n out.push(\n err(\n \"agent_trigger_unknown\",\n `agents.${id}: trigger \"${trigger.id}\" is not declared by the agent asset (${assetTriggerIds.length > 0 ? `has: ${assetTriggerIds.join(\", \")}` : \"it declares no triggers\"}) — add \\`kind\\` and the trigger's fields to declare a new one`,\n `${at}.id`,\n ),\n );\n return;\n }\n const missing = TRIGGER_REQUIRED_FIELDS[trigger.kind].filter(\n (field) => (trigger as unknown as Record<string, unknown>)[field] === undefined,\n );\n if (missing.length > 0) {\n out.push(\n err(\n \"agent_trigger_incomplete\",\n `agents.${id}: trigger \"${trigger.id}\" (kind ${trigger.kind}) is not in the asset, so it must declare ${missing.join(\", \")}`,\n at,\n ),\n );\n }\n });\n return out;\n}\n\nfunction checkConnectors(\n id: string,\n instance: AgentInstanceConfig,\n facts: AssetFacts,\n connectorIds: string[],\n): Diagnostic[] {\n const out: Diagnostic[] = [];\n for (const [slot, connectorId] of Object.entries(instance.connectors ?? {})) {\n const at = `agents.${id}.connectors.${slot}`;\n if (!facts.connectorSlots.includes(slot)) {\n const hint = facts.otherSlots.includes(slot)\n ? `\"${slot}\" is a slot of a non-connector item`\n : facts.connectorSlots.length > 0\n ? `the asset's connector slots are: ${facts.connectorSlots.join(\", \")}`\n : \"the asset declares no connector slots\";\n out.push(\n err(\n \"agent_connector_slot_unknown\",\n `agents.${id}: connectors.${slot} is not a connector slot id of the agent asset (${hint})`,\n at,\n ),\n );\n }\n if (!connectorIds.includes(connectorId)) {\n out.push(\n err(\n \"agent_connector_unknown\",\n `agents.${id}: connectors.${slot} points at \"${connectorId}\", which is not in skaile.yaml connectors[]${connectorIds.length > 0 ? ` (has: ${connectorIds.join(\", \")})` : \"\"}`,\n at,\n ),\n );\n }\n }\n return out;\n}\n\n/**\n * Diagnostics for the `agents:` map of a parsed `skaile.yaml`.\n *\n * @param projectDir - Directory of the `skaile.yaml`; local and catalog refs resolve against it.\n * @param parsed - The raw YAML document.\n */\nexport function checkAgentInstances(\n projectDir: string,\n parsed: Record<string, unknown>,\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const instances = normalizeAgentInstances(parsed.agents, diagnostics);\n const agent = isRecord(parsed.agent) ? parsed.agent : undefined;\n diagnostics.push(...agentBlockKeyDiagnostics(parsed.agent));\n if (agent?.subagents !== undefined) {\n diagnostics.push(\n err(\n \"agent_subagents_removed\",\n \"`agent.subagents` was removed — declare each subagent as an agent asset and bind it under `agents:` with `lifecycle: role`\",\n \"agent.subagents\",\n ),\n );\n }\n if (agent?.instances !== undefined) {\n diagnostics.push(\n err(\n \"misplaced_agent_instances\",\n \"`agent.instances` is not a skaile.yaml key — declare instances under root `agents:`\",\n \"agent.instances\",\n ),\n );\n }\n diagnostics.push(\n ...agentInstanceDiagnostics({\n agent: {\n definition: typeof agent?.definition === \"string\" ? agent.definition : undefined,\n instances,\n },\n }),\n );\n if (!instances) return diagnostics;\n\n const connectorIds = (Array.isArray(parsed.connectors) ? parsed.connectors : []).flatMap((c) =>\n isRecord(c) && typeof c.id === \"string\" ? [c.id] : [],\n );\n\n for (const [id, instance] of Object.entries(instances)) {\n const loaded = loadAsset(projectDir, id, instance.ref);\n if (\"diagnostic\" in loaded) {\n // Asset-independent trigger rules still apply when the ref is broken.\n diagnostics.push(loaded.diagnostic, ...checkTriggers(id, instance.triggers ?? [], undefined));\n continue;\n }\n const { facts } = loaded;\n const lifecycle = instance.lifecycle ?? facts.lifecycle ?? \"standing\";\n if (lifecycle === \"role\" && !facts.hasIo) {\n diagnostics.push(\n err(\n \"agent_role_missing_io\",\n `agents.${id}: lifecycle \"role\" needs the agent asset to declare \\`io\\` ({ input, output } JSON Schemas)`,\n `agents.${id}.lifecycle`,\n ),\n );\n }\n diagnostics.push(...checkConnectors(id, instance, facts, connectorIds));\n diagnostics.push(...checkTriggers(id, instance.triggers ?? [], facts.triggerIds));\n }\n return diagnostics;\n}\n","/**\n * Validate asset versions, changelogs, and manifest schemas across asset repos.\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n ASSET_NAME_HINT,\n type ConnectorDeclaration,\n decodeSkaileYaml,\n isInsideProject,\n symlinkEscapeOfProject,\n isValidAssetName,\n isValidPublisher,\n loadSkPublishManifest,\n localConnectorMountDir,\n parseAssetRef,\n resolveRuntimeAssets,\n SKAILE_MANIFEST_FILENAME,\n readAssetBody,\n} from \"@skaile/workspaces/core\";\nimport {\n flowSkillVersionPins,\n loadFlow,\n} from \"@skaile/workspaces/factory-assets/connectors/flow/engine\";\nimport { parseManifestFile } from \"@skaile/workspaces/discovery\";\nimport { isNonAssetPath } from \"@skaile/workspaces/core/publish-manifest\";\nimport {\n assertManifestEditable,\n missingRootAssets,\n scanUnlistedAssets,\n UNLISTED_SCAN_SKIP_DIRS,\n} from \"@skaile/workspaces/library\";\nimport type { IAssetKindRegistry } from \"@skaile/workspaces/plugins\";\nimport type { FlowVersionNode } from \"@skaile/workspaces/resolver\";\nimport { validateFlowVersions } from \"@skaile/workspaces/resolver\";\nimport { Command } from \"commander\";\nimport { parse as parseYaml } from \"yaml\";\nimport { type ComposeRefContext, composeRefContext } from \"../agent-checks.ts\";\nimport { logErr, logInfo, logOk, logWarn } from \"../helpers.ts\";\nimport { getKindRegistry } from \"../open-registry.ts\";\nimport { AI_RESOURCES } from \"../paths.ts\";\nimport {\n checkAsset,\n declaredVersion,\n findAssetManifestFile,\n invalidSemverText,\n} from \"../skill-checks.ts\";\nimport {\n manifestEntryNameProblems,\n invalidPublisherMessage,\n manifestPublisherProblems,\n manifestRootProblems,\n manifestRequiresProblems,\n registeredAssetKeys,\n rejectRemovedDomainOption,\n removedDomainOption,\n reportLibrarySymlinks,\n unresolvedManifestDependencies,\n warnIgnoredDomainFiles,\n warnLegacyBundleFiles,\n} from \"./library-index.ts\";\nimport { assetEntryRef, manifestVersionMismatchMessage } from \"./publish-core.ts\";\nimport { checkAgentInstances } from \"./validate-instances.ts\";\n\n// ---------------------------------------------------------------------------\n// Manifest schema validation (skaile validate [path])\n// ---------------------------------------------------------------------------\n\n/** Per-type regex patterns for deterministic asset discovery. */\nconst MANIFEST_GLOBS: Array<{ pattern: RegExp; kind: string }> = [\n { pattern: /\\/SKILL\\.md$/, kind: \"skill\" },\n { pattern: /\\/agent\\.yaml$/, kind: \"agent\" },\n { pattern: /\\/AGENT\\.md$/, kind: \"agent\" },\n { pattern: /\\/CONTRACT\\.md$/, kind: \"contract\" },\n { pattern: /\\/PERSONA\\.md$/, kind: \"persona\" },\n { pattern: /\\/RULESET\\.md$/, kind: \"ruleset\" },\n { pattern: /\\.flow\\.yaml$/, kind: \"flow\" },\n { pattern: /\\.flow\\.json$/, kind: \"flow\" },\n { pattern: /\\/CONNECTOR\\.md$/, kind: \"connector\" },\n { pattern: /\\.prompt\\.md$/, kind: \"prompt\" },\n { pattern: /\\/MCP\\.md$/, kind: \"mcp-server\" },\n { pattern: /\\/knowledge\\.yaml$/, kind: \"knowledge\" },\n { pattern: /\\/knowledge\\/index\\.yaml$/, kind: \"knowledge\" },\n { pattern: /\\.preset\\.yaml$/, kind: \"preset\" },\n];\n\n/**\n * `.claude`, `.codex` and `.omp` hold the copies `skaile add` deploys for the harnesses (and\n * the harness's own state): a project `validate .` checks what the author owns, not the\n * deployed bytes of an asset published elsewhere (p853).\n */\nconst HARNESS_DIRS: ReadonlySet<string> = new Set([\".claude\", \".codex\", \".omp\"]);\n/** Directories to skip during tree walk. */\nconst SKIP_DIRS = new Set([\n \"node_modules\",\n \"dist\",\n \".git\",\n \".skaile\",\n \"__pycache__\",\n ...HARNESS_DIRS,\n]);\n\ninterface ManifestCandidate {\n filePath: string;\n kind: string;\n}\n\n/** Recursively walk a directory tree and find manifest candidates. */\nfunction findManifestCandidates(rootPath: string): ManifestCandidate[] {\n const candidates: ManifestCandidate[] = [];\n\n function walk(dir: string): void {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n if (!SKIP_DIRS.has(entry.name)) walk(fullPath);\n } else if (entry.isFile()) {\n for (const glob of MANIFEST_GLOBS) {\n if (glob.pattern.test(fullPath)) {\n candidates.push({ filePath: fullPath, kind: glob.kind });\n break;\n }\n }\n }\n }\n }\n\n walk(rootPath);\n return candidates;\n}\n\n/**\n * Parse a single manifest candidate's bytes with the indexer's own parser\n * (`parseManifestFile`), so a manifest `library index` cannot parse — an empty\n * `SKILL.md`, no frontmatter, invalid YAML — is an error here too. On failure\n * the error is already logged; count it.\n */\nfunction parseManifestCandidate(\n c: ManifestCandidate,\n absRoot: string,\n): { kind: \"value\"; parsed: unknown; body?: string } | { kind: \"error\" } {\n const content = fs.readFileSync(c.filePath, \"utf-8\");\n const res = parseManifestFile(c.filePath, content);\n if (!res.ok) {\n logErr(`${path.relative(absRoot, c.filePath)} [${c.kind}] — parse error: ${res.reason}`);\n return { kind: \"error\" };\n }\n return {\n kind: \"value\",\n parsed: res.data,\n body: readAssetBody(c.filePath, content),\n };\n}\n\n/**\n * The library root a validated path belongs to: the nearest directory at or above `absRoot`\n * that holds a `skaile.yaml`, else `absRoot` itself.\n */\nfunction libraryRootOf(absRoot: string): string {\n for (let dir = absRoot; ; dir = path.dirname(dir)) {\n if (fs.existsSync(path.join(dir, SKAILE_MANIFEST_FILENAME))) return dir;\n if (path.dirname(dir) === dir) return absRoot;\n }\n}\n\n/**\n * Validate a single parsed manifest candidate against identity rules + the kind\n * registry. Returns the error/warning deltas this candidate contributes.\n */\nfunction validateManifestCandidate(\n c: ManifestCandidate,\n parsed: unknown,\n body: string | undefined,\n absRoot: string,\n registry: IAssetKindRegistry,\n strictConformance: boolean,\n composeRefs: ComposeRefContext,\n): { errors: number; warnings: number } {\n const relPath = path.relative(absRoot, c.filePath);\n let errors = 0;\n let warnings = 0;\n\n // The shared per-asset checks (also run by `library index` and the publish plan):\n // errors fail validate; advisories are warnings (exit code unchanged) unless\n // --strict-conformance escalates the agentskills.io conformance ones to errors.\n const dirName = path.basename(path.dirname(c.filePath)); // the manifest's folder\n const checked = checkAsset(\n c.kind,\n (parsed ?? {}) as Record<string, unknown>,\n body,\n dirName,\n registry,\n fs.readFileSync(c.filePath, \"utf-8\"),\n path.basename(c.filePath),\n { dir: path.dirname(c.filePath), libraryRoot: libraryRootOf(absRoot), composeRefs },\n );\n for (const f of checked.errors) {\n logErr(`${relPath} [${f.tag}] — ${f.text}`);\n errors++;\n }\n for (const f of checked.advisories) {\n const line = `${relPath} [${f.tag}] — ${f.text}`;\n // An untouched scaffold body is an error: a passing `validate` means the asset can be published.\n if ((f.conformance && strictConformance) || f.scaffoldBody) {\n logErr(line);\n errors++;\n } else {\n logWarn(line);\n warnings++;\n }\n }\n\n return { errors, warnings };\n}\n\n/**\n * The `kind:name` identity of every asset manifest under `root`, read quietly: a manifest\n * that does not parse holds no identity (its own validation reports the error).\n */\nexport function scanIdentities(root: string): Set<string> {\n const identities = new Set<string>();\n for (const c of findManifestCandidates(root)) {\n let parsed: unknown;\n try {\n const res = parseManifestFile(c.filePath, fs.readFileSync(c.filePath, \"utf-8\"));\n if (!res.ok) continue;\n parsed = res.data;\n } catch {\n continue;\n }\n if (parsed === null || typeof parsed !== \"object\") continue;\n const identity = (parsed as Record<string, unknown>)[c.kind === \"flow\" ? \"id\" : \"name\"];\n if (typeof identity === \"string\" && identity.length > 0)\n identities.add(`${c.kind}:${identity}`);\n }\n return identities;\n}\n\n/** Validate all manifest files in a directory tree using the kind registry. */\nexport function validateManifests(\n rootPath: string,\n strictConformance: boolean,\n registeredAssets: ReadonlySet<string> = new Set(),\n): { total: number; errors: number; warnings: number } {\n const absRoot = path.resolve(rootPath);\n if (!fs.existsSync(absRoot)) {\n logErr(`Path does not exist: ${absRoot}`);\n return { total: 0, errors: 1, warnings: 0 };\n }\n\n const registry: IAssetKindRegistry = getKindRegistry();\n const candidates = findManifestCandidates(absRoot);\n // Symlinks are refused with the text `library index` and the publish plan print (p520). In a\n // library (a `skaile.manifest.yaml` at the root) any symlink is refused, as `git add -A`\n // would publish it; elsewhere (a project) only those inside an asset or looping.\n const isLibrary = fs.existsSync(path.join(absRoot, SKAILE_MANIFEST_FILENAME));\n // A project's deployed harness folders (`add --link` makes `.claude/skills/x` a link to the\n // project's own `skills/x`) are not sources: they are skipped here as in the manifest walk.\n let errors = reportLibrarySymlinks(absRoot, {\n wholeTree: isLibrary,\n skipDirs: isLibrary ? undefined : HARNESS_DIRS,\n });\n let warnings = 0;\n\n // kind:name → directory of the first manifest seen; a second directory with the same\n // identity cannot be told apart by `add`/`publish` (and `library index` skips it).\n const seenIdentity = new Map<string, string>();\n // `composes:` refs resolve against the assets of the whole library (the scanned tree plus,\n // when `validate` got a sub-directory, its siblings under the enclosing library root) and the\n // registered libraries of its publisher: a ref no library holds fails `skaile add` (p415).\n const libraryRoot = libraryRootOf(absRoot);\n const composeRefs = composeRefContext(\n scanIdentities(libraryRoot),\n registeredAssets,\n loadSkPublishManifest(libraryRoot)?.publisher,\n );\n for (const c of candidates) {\n const parseResult = parseManifestCandidate(c, absRoot);\n if (parseResult.kind === \"error\") {\n errors++;\n continue;\n }\n\n const delta = validateManifestCandidate(\n c,\n parseResult.parsed,\n parseResult.body,\n absRoot,\n registry,\n strictConformance,\n composeRefs,\n );\n errors += delta.errors;\n warnings += delta.warnings;\n const obj = parseResult.parsed as Record<string, unknown> | null;\n const identity = obj && typeof obj === \"object\" ? obj[c.kind === \"flow\" ? \"id\" : \"name\"] : null;\n if (typeof identity === \"string\" && identity.length > 0) {\n const dir = path.dirname(c.filePath);\n const key = `${c.kind}:${identity}`;\n const first = seenIdentity.get(key);\n if (first === undefined) {\n seenIdentity.set(key, dir);\n } else if (first !== dir) {\n logErr(\n `${path.relative(absRoot, c.filePath)} [${c.kind}] — ${key} is also defined in ${path.relative(absRoot, first) || \".\"}; ` +\n \"two directories cannot share a kind and name (`skaile library index` keeps only the first).\",\n );\n errors++;\n }\n }\n }\n\n return { total: candidates.length, errors, warnings };\n}\n\n/** Recursively find every `skaile.yaml` / `*.skaile.yaml` workspace manifest. */\nfunction findWorkspaceManifests(rootPath: string): string[] {\n const out: string[] = [];\n function walk(dir: string): void {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n if (!SKIP_DIRS.has(entry.name)) walk(full);\n } else if (entry.isFile() && /(^|\\.)skaile\\.yaml$/.test(entry.name)) {\n out.push(full);\n }\n }\n }\n walk(rootPath);\n return out;\n}\n\n/**\n * Validate the dependency refs and asset identities declared in every\n * `skaile.yaml` under a tree. This is the manifest-level mirror of the\n * per-file identity check: it parses each `dependencies[]` /\n * `overrides[].ref` through `parseAssetRef` (the exact code path that produced\n * the original \"publisher required …\" / \"invalid asset name …\" hard error) and\n * checks each `assets[].name` against the canonical name grammar.\n */\n/**\n * Collect every `[field, ref]` pair to validate from a workspace manifest:\n * each string in `dependencies[]` and each `overrides[].ref`.\n */\nfunction collectWorkspaceRefFields(parsed: Record<string, unknown>): Array<[string, string]> {\n const refFields: Array<[string, string]> = [];\n if (Array.isArray(parsed.dependencies)) {\n for (const d of parsed.dependencies) {\n if (typeof d === \"string\") refFields.push([\"dependencies\", d]);\n }\n }\n if (Array.isArray(parsed.overrides)) {\n for (const o of parsed.overrides) {\n const ref = (o as Record<string, unknown>)?.ref;\n if (typeof ref === \"string\") refFields.push([\"overrides.ref\", ref]);\n }\n }\n return refFields;\n}\n\n/** Parse each declared ref through `parseAssetRef`; returns the error count. */\nfunction validateWorkspaceRefs(refFields: Array<[string, string]>, relPath: string): number {\n let errors = 0;\n for (const [field, ref] of refFields) {\n try {\n const parsedRef = parseAssetRef(ref);\n // The library-side slug rule (`library index`, the publish plan) holds for a project's\n // `dependencies:` too: `add` cannot resolve such a ref, so `check` fails on it (p1080).\n const publisher = parsedRef.publisher?.replace(/^@/, \"\");\n if (publisher !== undefined && !isValidPublisher(publisher)) {\n logErr(`${relPath} [${field}] — ${ref}: ${invalidPublisherMessage(publisher)}`);\n errors++;\n }\n } catch (e) {\n logErr(`${relPath} [${field}] — ${e instanceof Error ? e.message : String(e)}`);\n errors++;\n }\n }\n return errors;\n}\n\n/** Validate `assets[].name` against the canonical name/ref grammar. */\nfunction validateWorkspaceAssets(parsed: Record<string, unknown>, relPath: string): number {\n if (!Array.isArray(parsed.assets)) return 0;\n let errors = 0;\n const topPublisher = typeof parsed.publisher === \"string\" ? parsed.publisher : undefined;\n for (const a of parsed.assets) {\n const asset = a as Record<string, unknown>;\n const name = asset?.name;\n const kind = typeof asset?.kind === \"string\" ? asset.kind : \"skill\";\n if (typeof name !== \"string\" || name.length === 0) continue;\n const publisher = typeof asset?.publisher === \"string\" ? asset.publisher : topPublisher;\n if (publisher !== undefined) {\n try {\n parseAssetRef(`${kind}:@${publisher}/${name}`);\n } catch (e) {\n logErr(`${relPath} [assets] — ${e instanceof Error ? e.message : String(e)}`);\n errors++;\n }\n } else if (!isValidAssetName(name)) {\n logErr(`${relPath} [assets] — invalid asset name \"${name}\" — ${ASSET_NAME_HINT}`);\n errors++;\n }\n }\n return errors;\n}\n\n/** `skaile.yaml` connector diagnostics that fail `validate` (the runner cannot mount it right). */\nconst CONNECTOR_ERROR_CODES: readonly string[] = [\n \"connector_missing_driver\",\n \"connector_missing_id\",\n \"connector_duplicate_id\",\n \"connector_invalid_access\",\n];\n\n/**\n * A `local` connector's `mountPath` is mounted read-write as given: one that does not exist\n * fails (`serve` refuses it too), one outside the project is a warning, one that reaches outside\n * through a symlink fails (p833).\n */\nfunction validateLocalConnectorMountPaths(\n projectDir: string,\n relPath: string,\n connectors: ReadonlyArray<ConnectorDeclaration>,\n): number {\n let errors = 0;\n for (const c of connectors) {\n if (c.driver !== \"local\" || c.mount) continue;\n const dir = localConnectorMountDir(c, projectDir);\n if (!dir) continue;\n const escapesTo = symlinkEscapeOfProject(dir, projectDir);\n if (!fs.existsSync(dir)) {\n logErr(\n `${relPath} [connectors] — connector_mount_path_missing: connectors.${c.id}.mountPath: ${dir} does not exist; create the directory or fix the path`,\n );\n errors++;\n } else if (escapesTo !== null) {\n logErr(\n `${relPath} [connectors] — connector_mount_path_symlink: connectors.${c.id}.mountPath: ${dir} is a symlink to ${escapesTo}, outside the project ${projectDir}; point mountPath at the real directory`,\n );\n errors++;\n } else if (!isInsideProject(dir, projectDir)) {\n logWarn(\n `${relPath} [connectors] — connectors.${c.id}.mountPath: ${dir} is outside the project ${projectDir}; the agent reads${c.access === \"read-write\" ? \" and writes\" : \"\"} there`,\n );\n }\n }\n return errors;\n}\n\nasync function validateWorkspaceManifests(rootPath: string): Promise<{\n total: number;\n errors: number;\n}> {\n const absRoot = path.resolve(rootPath);\n const files = findWorkspaceManifests(absRoot);\n let errors = 0;\n\n for (const file of files) {\n const relPath = path.relative(absRoot, file);\n let parsed: Record<string, unknown>;\n try {\n parsed = (parseYaml(fs.readFileSync(file, \"utf-8\")) ?? {}) as Record<string, unknown>;\n } catch (e) {\n logErr(`${relPath} — parse error: ${e instanceof Error ? e.message : String(e)}`);\n errors++;\n continue;\n }\n\n errors += validateWorkspaceRefs(collectWorkspaceRefFields(parsed), relPath);\n errors += validateWorkspaceAssets(parsed, relPath);\n for (const d of checkAgentInstances(path.dirname(file), parsed)) {\n const line = `${relPath} [agents] — ${d.code}: ${d.path ? `${d.path}: ` : \"\"}${d.message}`;\n if (d.severity === \"error\") {\n logErr(line);\n errors++;\n } else {\n logWarn(line);\n }\n }\n // A connector the runner cannot mount or mounts wrongly: no `driver` (or the old `adapter`\n // spelling), no `id`, a duplicate `id`, an `access` that is neither read-only nor read-write.\n const decoded = decodeSkaileYaml(fs.readFileSync(file, \"utf-8\"));\n for (const d of decoded.diagnostics) {\n if (!CONNECTOR_ERROR_CODES.includes(d.code)) continue;\n logErr(`${relPath} [connectors] — ${d.code}: ${d.path ? `${d.path}: ` : \"\"}${d.message}`);\n errors++;\n }\n errors += validateLocalConnectorMountPaths(\n path.dirname(file),\n relPath,\n decoded.config?.connectors ?? [],\n );\n // A `driver` no catalog entry provides: `serve` cannot mount it either. The text is the one\n // `serve` logs as `validation_warning`. An unreachable source (not cloned yet) may hold the\n // driver, so nothing is reported while one is missing.\n if ((decoded.config?.connectors ?? []).length > 0) {\n const assets = await resolveRuntimeAssets(path.dirname(file));\n if (!assets.warnings.some((w) => w.code === \"repo_unavailable\")) {\n for (const w of assets.warnings) {\n if (w.code !== \"missing_driver\" || !w.name) continue;\n logErr(`${relPath} [connectors] — ${w.code}: ${w.message}`);\n errors++;\n }\n }\n }\n }\n\n return { total: files.length, errors };\n}\n\n/**\n * Check the library's publication manifest (`skaile.manifest.yaml` at the\n * validated root): every first-party `root:` must still exist. An entry whose\n * directory was deleted would otherwise stay publishable; the fix is\n * `skaile library index <lib>`, which drops it.\n */\nfunction validatePublishManifestRoots(rootPath: string): number {\n const absRoot = path.resolve(rootPath);\n const manifest = loadSkPublishManifest(absRoot);\n if (!manifest) return 0;\n const missing = missingRootAssets(absRoot, manifest);\n for (const a of missing) {\n logErr(\n `${SKAILE_MANIFEST_FILENAME} [assets] — ${assetEntryRef(a, manifest)}: root \"${a.root}\" does not exist. ` +\n \"Run `skaile library index <library>` to drop the entry, or restore the directory.\",\n );\n }\n return missing.length;\n}\n\n/**\n * An asset directory the library's manifest does not list is an error: `add` refuses it (`not\n * listed in its skaile.manifest.yaml`), the publish plan does not ship it, yet `git add -A`\n * commits its files. The fix is `skaile library index <lib>`, which lists it (p1193). A directory\n * that holds a kind + name the manifest already names elsewhere is the duplicate check's finding.\n */\nasync function validatePublishManifestUnlisted(rootPath: string): Promise<number> {\n const absRoot = path.resolve(rootPath);\n const manifest = loadSkPublishManifest(absRoot);\n if (!manifest) return 0;\n const unlisted = (\n await scanUnlistedAssets(\n absRoot,\n manifest.publisher ?? path.basename(absRoot),\n getKindRegistry(),\n UNLISTED_SCAN_SKIP_DIRS,\n )\n ).filter((u) => !u.registeredAt);\n for (const u of unlisted) {\n logErr(\n `${path.relative(absRoot, u.entry.source)} [${u.entry.kind}] — ${u.entry.kind}:${u.entry.name} is on disk but not in ${SKAILE_MANIFEST_FILENAME}, so it is not published. ` +\n \"Run `skaile library index <library>` to list it, or delete the directory.\",\n );\n }\n return unlisted.length;\n}\n\n/**\n * Check every `assets[].dependencies` entry of the publication manifest with the\n * same syntax rule (and message) `library index` applies, so a malformed ref\n * fails `validate` instead of being silently dropped by the manifest decoder.\n */\nfunction validatePublishManifestRequires(rootPath: string): number {\n const problems = manifestRequiresProblems(path.resolve(rootPath));\n for (const p of problems) {\n logErr(\n `${SKAILE_MANIFEST_FILENAME} [assets] — ${p.asset}: ${p.message}. ` +\n \"Use the `kind:@<publisher>/name[#version]` form.\",\n );\n }\n return problems.length;\n}\n\n/**\n * Check the publisher of the publication manifest (top-level and every\n * `assets[].publisher`) against the one publisher slug rule `library create`, `library\n * index` and the publish plan apply, with the same message.\n */\nfunction validatePublishManifestPublisherSlugs(rootPath: string): number {\n const problems = manifestPublisherProblems(path.resolve(rootPath));\n for (const message of problems) logErr(message);\n return problems.length;\n}\n\n/**\n * Check every first-party `assets[].root` of the publication manifest stays inside the library\n * and crosses no symlink ({@link manifestRootProblems}), the refusal `library index` and the\n * publish plan print too: a root outside the library is never found by `add` (p701).\n */\nfunction validatePublishManifestRootPaths(rootPath: string): number {\n const problems = [\n ...manifestRootProblems(path.resolve(rootPath)),\n ...manifestEntryNameProblems(path.resolve(rootPath)),\n ];\n for (const message of problems) logErr(message);\n return problems.length;\n}\n\n/**\n * Parse the publication manifest the way `library index` and `library publish` open it, so a\n * `skaile.manifest.yaml` that does not parse fails `validate` too, with the file and line.\n * Without the file there is nothing to check.\n */\nfunction validatePublishManifestParses(rootPath: string): number {\n try {\n assertManifestEditable(path.resolve(rootPath));\n return 0;\n } catch (err) {\n logErr(err instanceof Error ? err.message : String(err));\n return 1;\n }\n}\n\n/**\n * Warn when a first-party `assets[].version` of the publication manifest differs\n * from the version in the asset's own manifest file. The file is the source of\n * truth — `skaile library index` rewrites the entry from it — so a hand-edited\n * manifest version is silently overwritten by the next index. Returns the warning count.\n */\nfunction validatePublishManifestVersions(rootPath: string): number {\n const absRoot = path.resolve(rootPath);\n const manifest = loadSkPublishManifest(absRoot);\n if (!manifest || manifest.source) return 0;\n let warnings = 0;\n for (const a of manifest.assets ?? []) {\n if (!a.root || a.source || !a.version) continue;\n const file = findAssetManifestFile(path.join(absRoot, a.root), a.kind, a.name);\n if (!file) continue;\n const res = parseManifestFile(file, fs.readFileSync(file, \"utf-8\"));\n if (!res.ok) continue; // reported by the per-file parse check\n const fileVersion = declaredVersion(res.data);\n if (fileVersion === undefined || fileVersion === a.version) continue;\n logWarn(\n manifestVersionMismatchMessage(\n assetEntryRef(a, manifest),\n a.version,\n toPosix(path.relative(absRoot, file)),\n fileVersion,\n ),\n );\n warnings++;\n }\n return warnings;\n}\n\n/**\n * Warn when a first-party asset file still carries a `metadata.publisher` that\n * differs from the publisher the manifest resolves for it (`assets[].publisher`,\n * else the top-level `publisher`). The manifest is the only source of an\n * asset's publisher; the file value is ignored by every resolver, so a stale\n * one only misleads the reader. Returns the warning count.\n */\nfunction validatePublishManifestPublishers(rootPath: string): number {\n const absRoot = path.resolve(rootPath);\n const manifest = loadSkPublishManifest(absRoot);\n if (!manifest || manifest.source) return 0;\n const bare = (p: string) => p.trim().replace(/^@/, \"\");\n let warnings = 0;\n for (const a of manifest.assets ?? []) {\n const resolved = a.publisher ?? manifest.publisher;\n if (!a.root || a.source || !resolved) continue;\n const file = findAssetManifestFile(path.join(absRoot, a.root), a.kind, a.name);\n if (!file) continue;\n const res = parseManifestFile(file, fs.readFileSync(file, \"utf-8\"));\n if (!res.ok) continue; // reported by the per-file parse check\n const meta = (res.data as Record<string, unknown>).metadata;\n const declared =\n meta !== null && typeof meta === \"object\"\n ? (meta as Record<string, unknown>).publisher\n : null;\n if (typeof declared !== \"string\" || bare(declared) === bare(resolved)) continue;\n logWarn(\n `${toPosix(path.relative(absRoot, file))} [publisher] — metadata.publisher \"${bare(declared)}\" differs from ` +\n `the manifest publisher \"${bare(resolved)}\" for ${assetEntryRef(a, manifest)}. The manifest wins and the ` +\n \"file value is ignored: delete `metadata.publisher` from the file, or set the publisher in \" +\n `${SKAILE_MANIFEST_FILENAME}.`,\n );\n warnings++;\n }\n return warnings;\n}\n\n/** Root-relative path prefixes excluded from version/changelog checks. */\nconst EXCLUDED_PATHS = [\"skaileup-shared/\", \"external/\", \"docs/\"];\n\n/** Normalise to forward slashes so prefix and set comparisons work on any OS. */\nfunction toPosix(p: string): string {\n return p.split(path.sep).join(\"/\");\n}\n\n/** True when a root-relative path sits under one of {@link EXCLUDED_PATHS}. */\nfunction isExcludedPath(relPath: string): boolean {\n const rel = toPosix(relPath);\n return EXCLUDED_PATHS.some((prefix) => rel.startsWith(prefix));\n}\n\ninterface AssetVersion {\n kind: \"skill\" | \"agent\" | \"flow\" | \"prompt\" | \"preset\" | \"contract\";\n name: string;\n version: string;\n filePath: string;\n}\n\n/** Manifest candidates whose kind carries a version `validate versions` checks. */\nconst VERSIONED_KINDS: Record<string, true> = {\n skill: true,\n agent: true,\n flow: true,\n prompt: true,\n preset: true,\n contract: true,\n};\n\n/** Read one manifest candidate's identity and version; unreadable YAML yields an empty version. */\nfunction readAssetVersion(c: ManifestCandidate): AssetVersion {\n const kind = c.kind as AssetVersion[\"kind\"];\n const fileName = path.basename(c.filePath);\n const dirName = path.basename(path.dirname(c.filePath));\n const content = fs.readFileSync(c.filePath, \"utf-8\");\n if (c.filePath.endsWith(\".md\")) {\n // The version `library index` records (top-level `version`, else `metadata.version`).\n const res = parseManifestFile(c.filePath, content);\n const data = res.ok ? (res.data as Record<string, unknown>) : {};\n const stem = fileName.replace(/\\.prompt\\.md$/, \"\");\n return {\n kind,\n name: typeof data.name === \"string\" ? data.name : kind === \"prompt\" ? stem : dirName,\n version: declaredVersion(data) ?? \"\",\n filePath: c.filePath,\n };\n }\n let parsed: Record<string, unknown> | null = null;\n try {\n parsed = parseYaml(content);\n } catch {\n // Reported by the default `skaile validate`; here the asset just has no readable version.\n }\n if (kind === \"flow\") {\n return {\n kind,\n name: String(parsed?.id ?? fileName.replace(\".flow.yaml\", \"\")),\n version: String(parsed?.version ?? \"\"),\n filePath: c.filePath,\n };\n }\n return {\n kind,\n name: String(parsed?.name ?? dirName),\n version: String(parsed?.version ?? \"\"),\n filePath: c.filePath,\n };\n}\n\n/**\n * Walk `root` at any depth and collect the version of every skill, agent, flow, prompt,\n * preset and contract — the same tree walk the default `validate` uses, so a library laid out\n * as `<root>/<asset>/SKILL.md` is covered as well as `skills/<asset>/SKILL.md`.\n */\nfunction collectAssetVersions(root: string): AssetVersion[] {\n if (!fs.existsSync(root)) return [];\n const assets: AssetVersion[] = [];\n for (const c of findManifestCandidates(root)) {\n if (!VERSIONED_KINDS[c.kind]) continue;\n // Only the YAML flow form and `agent.yaml` / `AGENT.md` carry a readable version here.\n if (c.filePath.endsWith(\".flow.json\")) continue;\n if (isExcludedPath(path.relative(root, c.filePath))) continue;\n assets.push(readAssetVersion(c));\n }\n return assets;\n}\n\n/** Root-relative posix location of an asset file, for messages. */\nfunction assetLocation(a: AssetVersion, root: string): string {\n return toPosix(path.relative(root, a.filePath));\n}\n\n/**\n * Nearest ancestor directory of `assetRelPath` (root-relative, posix) that\n * holds a `CHANGELOG.md`, walking up from the asset's own directory to and\n * including `root`, never above it. Returns the changelog's root-relative\n * path, or `null` when no ancestor has one.\n */\nfunction findChangelogUnit(assetRelPath: string, root: string): string | null {\n let dir = path.posix.dirname(toPosix(assetRelPath));\n for (;;) {\n const candidate = dir === \".\" ? \"CHANGELOG.md\" : `${dir}/CHANGELOG.md`;\n if (fs.existsSync(path.join(root, candidate))) return candidate;\n if (dir === \".\") return null;\n dir = path.posix.dirname(dir);\n }\n}\n\n/** Outcome of {@link checkChangelogUnits}. All paths are root-relative posix. */\nexport interface ChangelogCheck {\n /** Changelog units whose `CHANGELOG.md` is among the modified files. */\n updated: string[];\n /** Changelog units covering a modified asset whose `CHANGELOG.md` is not modified. */\n stale: string[];\n /** Modified assets with no `CHANGELOG.md` in any ancestor up to the root. */\n orphans: string[];\n}\n\n/**\n * Group the modified asset files by their nearest-ancestor `CHANGELOG.md` and\n * report which units were updated alongside them. Assets under\n * {@link EXCLUDED_PATHS} are ignored.\n *\n * @param modifiedFiles - Changed paths relative to `root`.\n * @param root - The asset root (`ai-assets/`); the walk up never leaves it.\n */\nexport function checkChangelogUnits(modifiedFiles: string[], root: string): ChangelogCheck {\n const modified = new Set(modifiedFiles.map(toPosix));\n const assetPattern = /(SKILL\\.md|agent\\.yaml|\\.flow\\.yaml|\\.prompt\\.md)$/;\n const units = new Set<string>();\n const orphans: string[] = [];\n for (const f of modified) {\n if (!assetPattern.test(f) || isExcludedPath(f)) continue;\n const unit = findChangelogUnit(f, root);\n if (unit) units.add(unit);\n else orphans.push(f);\n }\n const updated = [...units].filter((u) => modified.has(u));\n const stale = [...units].filter((u) => !modified.has(u));\n return { updated, stale, orphans };\n}\n\n/** Extract version from file content using proper YAML parsing */\nfunction extractVersionFromContent(filePath: string, content: string): string | null {\n if (filePath.endsWith(\".yaml\")) {\n const parsed = parseYaml(content);\n return parsed?.version ?? null;\n }\n // SKILL.md / .prompt.md — YAML frontmatter\n const fmMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!fmMatch) return null;\n const parsed = parseYaml(fmMatch[1]);\n return parsed?.metadata?.version ?? parsed?.version ?? null;\n}\n\n/** Check every asset has a present + semver-valid version. */\nfunction checkAssetVersions(\n assets: AssetVersion[],\n root: string,\n): { errors: number; warnings: number } {\n let errors = 0;\n const warnings = 0;\n for (const a of assets) {\n const location = assetLocation(a, root);\n if (!a.version) {\n logErr(`${a.kind}:${a.name} (${location}) — missing version`);\n errors++;\n continue;\n }\n const invalid = invalidSemverText(a.version);\n if (invalid) {\n logErr(`${a.kind}:${a.name} (${location}) — ${invalid}`);\n errors++;\n }\n }\n return { errors, warnings };\n}\n\n/** In --changed-only mode, warn when a changed asset's version was not bumped. */\nfunction checkVersionBumps(assets: AssetVersion[], root: string): number {\n let warnings = 0;\n for (const a of assets) {\n if (!a.version) continue; // already flagged above\n // `HEAD:./<path>` is relative to `root` (the cwd), not the repository top level.\n const relPath = toPosix(path.relative(root, a.filePath));\n try {\n const headContent = execFileSync(\"git\", [\"show\", `HEAD:./${relPath}`], {\n cwd: root,\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const headVersion = extractVersionFromContent(a.filePath, headContent);\n if (headVersion && headVersion === a.version) {\n logWarn(\n `${a.kind}:${a.name} (${assetLocation(a, root)}) — file changed but version not bumped (${a.version})`,\n );\n warnings++;\n }\n } catch {\n // New file (no HEAD version) — that's fine\n }\n }\n return warnings;\n}\n\n/**\n * Validate flow node skill-version pins against the discovered skill versions.\n *\n * Flows are read through `loadFlow`, which normalizes legacy v1 documents into\n * the strict v2 shape — reading the authored YAML directly would miss every v2\n * pin, since those ride in `run.assets` rather than `node.data.version`.\n */\nfunction checkFlowVersionPins(\n assets: AssetVersion[],\n root: string,\n): { errors: number; warnings: number } {\n const flows = assets.filter((a) => a.kind === \"flow\");\n const skillVersionMap = new Map<string, string>();\n for (const a of assets.filter((a) => a.kind === \"skill\")) {\n skillVersionMap.set(a.name, a.version);\n }\n\n let errors = 0;\n let warnings = 0;\n for (const f of flows) {\n let pins: FlowVersionNode[];\n try {\n pins = flowSkillVersionPins(loadFlow(f.filePath));\n } catch (err) {\n // An unreadable flow is a gap in the check, not an absence of findings.\n // Report the path, not `f.name`: that id comes from a raw-YAML read that\n // falls back to the filename stem exactly when the file is unusable.\n logWarn(\n `flow:${f.name} (${path.relative(root, f.filePath)}) — could not be read: ` +\n `${err instanceof Error ? err.message : err}`,\n );\n warnings++;\n continue;\n }\n\n if (pins.length === 0) continue;\n const checks = validateFlowVersions(pins, skillVersionMap);\n for (const c of checks.filter((c) => !c.satisfied)) {\n logErr(\n `flow:${f.name} node ${c.nodeId} — wants ${c.requested}, found ${c.actual || \"(none)\"}`,\n );\n errors++;\n }\n }\n return { errors, warnings };\n}\n\n/**\n * Root of a `validate versions` / `validate changelog` run: the explicit `[path]`,\n * else the library the shell is in (the nearest directory at or above the cwd\n * that holds `skaile.manifest.yaml`), else the bundled factory assets\n * ({@link AI_RESOURCES}). Returns `null` after printing an error when an explicit\n * path does not exist.\n */\nfunction resolveCheckRoot(pathArg: string | undefined): string | null {\n if (pathArg) {\n const abs = path.resolve(pathArg);\n if (!fs.existsSync(abs)) {\n logErr(`Path does not exist: ${abs}`);\n return null;\n }\n return abs;\n }\n for (let dir = process.cwd(); ; dir = path.dirname(dir)) {\n if (fs.existsSync(path.join(dir, SKAILE_MANIFEST_FILENAME))) return dir;\n if (path.dirname(dir) === dir) return AI_RESOURCES;\n }\n}\n\n/** `true` when `root` lies inside a git work tree. */\nfunction isInGitWorkTree(root: string): boolean {\n try {\n return (\n execFileSync(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], {\n cwd: root,\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim() === \"true\"\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Run `git diff --name-only --relative <ref>` in `root` and return the changed paths\n * (relative to `root`), plus — with `untracked` — the new files git does not track yet.\n * No git work tree prints `<what> needs a git repository`; any other git failure — a bad\n * ref, no `git` — prints one `git diff failed in <root>: <first stderr line>` line. Both\n * return `null`; git's own usage text never reaches the terminal.\n *\n * @param what The command that needs git, for the message (`--changed-only`, `changelog`).\n */\nfunction changedFiles(\n root: string,\n ref: string,\n what: string,\n opts: { untracked?: boolean } = {},\n): string[] | null {\n if (!isInGitWorkTree(root)) {\n logErr(`${what} needs a git repository: ${root} is not inside a git work tree.`);\n return null;\n }\n try {\n const out = execFileSync(\n \"git\",\n [\"diff\", \"--name-only\", \"--relative\", \"--end-of-options\", ref],\n {\n cwd: root,\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n },\n );\n const changed = out.trim().split(\"\\n\").filter(Boolean);\n if (opts.untracked) {\n // New files git does not track yet (`--others` paths are relative to `root`).\n const fresh = execFileSync(\"git\", [\"ls-files\", \"--others\", \"--exclude-standard\"], {\n cwd: root,\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n changed.push(...fresh.trim().split(\"\\n\").filter(Boolean));\n }\n return changed;\n } catch (err) {\n const stderr = err instanceof Error && \"stderr\" in err ? String(err.stderr).trim() : \"\";\n const reason = (stderr || (err instanceof Error ? err.message : String(err))).split(\"\\n\")[0];\n logErr(`git diff failed in ${root}: ${reason}`);\n return null;\n }\n}\n\n/**\n * The directory whose files belong to `a`: the asset's own folder for a skill, agent, contract,\n * or a prompt/flow/preset that sits in a folder named after it — the folder `library create`\n * scaffolds. A single prompt/flow/preset file next to others is its own asset (`null`).\n */\nfunction assetOwnDir(a: AssetVersion): string | null {\n const dir = path.dirname(a.filePath);\n if ([\"skill\", \"agent\", \"contract\"].includes(a.kind) || path.basename(dir) === a.name) return dir;\n return null;\n}\n\n/**\n * `true` when `a` changed: its asset file, or any file under its folder that a deploy ships\n * (the lock hash covers them, minus the deploy ignore list), is among `changedAbs`.\n */\nfunction assetChanged(a: AssetVersion, changedAbs: ReadonlySet<string>): boolean {\n if (changedAbs.has(a.filePath)) return true;\n const dir = assetOwnDir(a);\n if (dir === null) return false;\n for (const f of changedAbs) {\n const rel = path.relative(dir, f);\n if (rel.startsWith(\"..\") || path.isAbsolute(rel)) continue;\n if (!isNonAssetPath(toPosix(rel))) return true;\n }\n return false;\n}\n\n/** Body of `skaile validate versions` — semver + bump + flow-pin checks. */\nfunction runVersionsCheck(\n pathArg: string | undefined,\n opts: { changedOnly?: boolean; strict?: boolean },\n): void {\n const root = resolveCheckRoot(pathArg);\n if (root === null) {\n process.exit(1);\n return;\n }\n let assets = collectAssetVersions(root);\n // A directory with no asset has nothing to check: `Checked 0 assets / All versions valid` would\n // read as a pass, so it fails as `validate` does for a path with no manifests (p1194).\n if (assets.length === 0) {\n logErr(\n `Nothing to check in ${root}: no versioned asset (skill, agent, flow, prompt, contract or preset) found. Pass the library directory.`,\n );\n process.exit(1);\n return;\n }\n\n // Filter to changed files only if requested\n if (opts.changedOnly) {\n const changed = changedFiles(root, \"HEAD\", \"--changed-only\", { untracked: true });\n if (changed === null) {\n process.exit(1);\n return;\n }\n const changedAbs = new Set(changed.map((f) => path.resolve(root, f)));\n assets = assets.filter((a) => assetChanged(a, changedAbs));\n }\n\n logInfo(`Checking versions in ${root}`);\n const versionCheck = checkAssetVersions(assets, root);\n let errors = versionCheck.errors;\n let warnings = versionCheck.warnings;\n\n // In --changed-only mode, check if version was actually bumped\n if (opts.changedOnly) {\n warnings += checkVersionBumps(assets, root);\n }\n\n const pinCheck = checkFlowVersionPins(assets, root);\n errors += pinCheck.errors;\n warnings += pinCheck.warnings;\n\n // Summary\n console.log();\n logInfo(`Checked ${assets.length} assets`);\n if (errors === 0 && warnings === 0) {\n logOk(\"All versions valid\");\n } else {\n if (errors > 0) logErr(`${errors} error(s)`);\n if (warnings > 0) logWarn(`${warnings} warning(s)`);\n }\n\n if (errors > 0 || (opts.strict && warnings > 0)) {\n process.exit(1);\n }\n}\n\n/**\n * Creates the `skaile validate` command group.\n *\n * Validates asset manifests, version fields, and changelogs in an asset\n * repository tree. Subcommands: default `validate [path]` (schema check),\n * `versions` (semver + flow pin validation), `changelog` (modified assets\n * must have an updated nearest-ancestor CHANGELOG.md).\n *\n * @returns Configured {@link Command} ready for `program.addCommand()`.\n * @docLink cli/commands/validate#make-validate-command\n */\nexport function makeValidateCommand(): Command {\n const cmd = new Command(\"validate\").description(\n \"Validate asset manifests, versions, and changelogs\",\n );\n\n // Default action: skaile validate [path]\n cmd\n .argument(\"[path]\", \"Path to asset repo or directory to validate\", \".\")\n .option(\n \"--strict-conformance\",\n \"Treat Agent Skills (agentskills.io) standard findings as errors\",\n )\n .action(async (targetPath: string, opts: { strictConformance?: boolean }) => {\n const absPath = path.resolve(targetPath);\n if (fs.existsSync(absPath) && !fs.statSync(absPath).isDirectory()) {\n logErr(`${absPath} is not a directory: nothing to validate. Pass the library directory.`);\n process.exit(1);\n return;\n }\n logInfo(`Validating manifests in ${absPath}`);\n const { total, errors, warnings } = validateManifests(\n absPath,\n opts.strictConformance ?? false,\n await registeredAssetKeys(libraryRootOf(absPath)),\n );\n const ws = await validateWorkspaceManifests(absPath);\n const rootErrors = validatePublishManifestRoots(absPath);\n const slugErrors = validatePublishManifestPublisherSlugs(absPath);\n const rootPathErrors = validatePublishManifestRootPaths(absPath);\n const parseErrors = validatePublishManifestParses(absPath);\n const requiresErrors = validatePublishManifestRequires(absPath);\n const unlistedErrors = await validatePublishManifestUnlisted(absPath);\n const versionWarnings = validatePublishManifestVersions(absPath);\n const publisherWarnings = validatePublishManifestPublishers(absPath);\n // Advisory and offline: a dependency no registered library holds may live in a\n // library that is not registered on this machine.\n const dependencyProblems = await unresolvedManifestDependencies(absPath);\n for (const w of dependencyProblems) logWarn(w);\n const dependencyWarnings = dependencyProblems.length;\n const totalErrors =\n errors +\n ws.errors +\n rootErrors +\n slugErrors +\n rootPathErrors +\n parseErrors +\n requiresErrors +\n unlistedErrors;\n console.log();\n warnIgnoredDomainFiles(absPath);\n warnLegacyBundleFiles(absPath);\n logInfo(`Scanned ${total} asset manifest(s) and ${ws.total} skaile.yaml file(s)`);\n // Nothing scanned and no library manifest: a directory with nothing in it is not valid,\n // it is not validated (p745).\n if (\n total === 0 &&\n ws.total === 0 &&\n totalErrors === 0 &&\n !fs.existsSync(path.join(absPath, SKAILE_MANIFEST_FILENAME))\n ) {\n logErr(\n `Nothing to validate in ${absPath}: no asset manifest, skaile.yaml or ${SKAILE_MANIFEST_FILENAME} found.`,\n );\n process.exit(1);\n return;\n }\n const totalWarnings = warnings + versionWarnings + publisherWarnings + dependencyWarnings;\n if (totalWarnings > 0) logWarn(`${totalWarnings} warning(s)`);\n if (totalErrors === 0) {\n logOk(\"All manifests valid\");\n } else {\n logErr(`${totalErrors} validation error(s)`);\n process.exit(1);\n }\n });\n\n cmd\n .command(\"versions\")\n .description(\"Check version fields and flow version pins\")\n .argument(\"[path]\", \"Library or asset directory (default: the current library)\")\n .option(\"--changed-only\", \"Only check assets modified since last commit\")\n .option(\"--strict\", \"Exit 1 on warnings (for CI)\")\n .addOption(removedDomainOption())\n .action(\n (\n pathArg: string | undefined,\n opts: { changedOnly?: boolean; strict?: boolean; domain?: string },\n ) => {\n rejectRemovedDomainOption(opts);\n runVersionsCheck(pathArg, opts);\n },\n );\n\n cmd\n .command(\"changelog\")\n .description(\"Check that modified assets have an updated nearest CHANGELOG.md\")\n .argument(\"[path]\", \"Library or asset directory (default: the current library)\")\n .option(\"--base <ref>\", \"Git base ref for diff\", \"HEAD\")\n .action((pathArg: string | undefined, opts: { base: string }) => {\n const root = resolveCheckRoot(pathArg);\n if (root === null) {\n process.exit(1);\n return;\n }\n const modifiedFiles = changedFiles(root, opts.base, \"changelog\");\n if (modifiedFiles === null) {\n process.exit(1);\n return;\n }\n const { updated, stale, orphans } = checkChangelogUnits(modifiedFiles, root);\n\n if (updated.length + stale.length + orphans.length === 0) {\n logOk(\"No modified assets found\");\n return;\n }\n\n for (const unit of updated) logOk(`${unit} updated`);\n for (const unit of stale) logErr(`${unit} not updated (assets were modified)`);\n for (const asset of orphans) {\n logErr(`${asset} — no CHANGELOG.md in any ancestor directory up to the asset root`);\n }\n\n if (stale.length + orphans.length > 0) process.exit(1);\n });\n\n return cmd;\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { getAccessToken, loadStoreAuthConfig, hasStoredAuth } from './chunk-OXUCYHL5.js';
2
- import { globalSettingsPath, mapLegacyFields } from './chunk-PIC23DDE.js';
1
+ import { getAccessToken, loadStoreAuthConfig, hasStoredAuth } from './chunk-RP3FZ2T6.js';
2
+ import { globalSettingsPath, mapLegacyFields } from './chunk-T2TQAH2X.js';
3
3
  import { existsSync, readFileSync } from 'fs';
4
4
 
5
5
  function getStoreConfig() {
@@ -60,5 +60,5 @@ function isStoreAuthenticated() {
60
60
  }
61
61
 
62
62
  export { getStoreConfig, getStoreToken, isStoreAuthenticated, storeFetch };
63
- //# sourceMappingURL=chunk-EYDRONKO.js.map
64
- //# sourceMappingURL=chunk-EYDRONKO.js.map
63
+ //# sourceMappingURL=chunk-V3D4HQMS.js.map
64
+ //# sourceMappingURL=chunk-V3D4HQMS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../cli/src/store-client.ts"],"names":[],"mappings":";;;;AAuBO,SAAS,cAAA,GAA8B;AAC5C,EAAA,MAAM,eAAe,kBAAA,EAAmB;AACxC,EAAA,IAAI,WAAgC,EAAC;AACrC,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,gBAAgB,IAAA,CAAK,KAAA,CAAM,aAAa,YAAA,EAAc,OAAO,CAAC,CAAC,CAAA;AAAA,IAC5E,CAAA,CAAA,MAAQ;AACN,MAAA,QAAA,GAAW,EAAC;AAAA,IACd;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,QAAA,CAAS,QAAA,IAAY,OAAA,CAAQ,IAAI,gBAAA,IAAoB,0BAAA;AAAA,IAC1D,GAAA,EAAK;AAAA,GACP;AACF;AAOO,SAAS,cAAc,IAAA,EAAkC;AAC9D,EAAA,OAAO,cAAA,CAAe,mBAAA,EAAoB,EAAG,IAAI,CAAA;AACnD;AAaA,eAAsB,UAAA,CACpB,MAAA,EACA,IAAA,EACA,IAAA,EAOY;AACZ,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAA,CAAO,GAAG,GAAG,IAAI,CAAA,CAAA;AAC9B,EAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,IAAA,MAAM,EAAA,GAAK,IAAI,eAAA,CAAgB,IAAA,CAAK,MAAM,CAAA;AAC1C,IAAA,GAAA,IAAO,IAAI,EAAE,CAAA,CAAA;AAAA,EACf;AAEA,EAAA,MAAM,OAAA,GAAkC;AAAA,IACtC,cAAA,EAAgB,kBAAA;AAAA,IAChB,MAAA,EAAQ,kBAAA;AAAA,IACR,GAAI,IAAA,EAAM,OAAA,IAAW;AAAC,GACxB;AACA,EAAA,IAAI,OAAO,GAAA,EAAK;AACd,IAAA,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,MAAA,CAAO,GAAG,CAAA,CAAA;AAAA,EAC9C;AAEA,EAAA,MAAM,SAAA,GAAyB;AAAA,IAC7B,MAAA,EAAQ,MAAM,MAAA,IAAU,KAAA;AAAA,IACxB;AAAA,GACF;AACA,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,SAAA,CAAU,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,OAAA,GAAU,WAAW,MAAM,UAAA,CAAW,OAAM,EAAG,IAAA,EAAM,aAAa,IAAK,CAAA;AAC7E,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,GAAG,SAAA,EAAW,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AACxE,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,OAAO,EAAE,KAAA,EAAO,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,IAAG,CAAE,CAAA;AAI3E,MAAA,MAAM,CAAA,GAAI,IAAA;AACV,MAAA,MAAM,IAAI,MAAM,CAAA,CAAE,OAAA,IAAW,EAAE,KAAA,IAAS,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,IAC1E;AACA,IAAA,OAAO,IAAI,IAAA,EAAK;AAAA,EAClB,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,OAAO,CAAA;AAAA,EACtB;AACF;AASO,SAAS,oBAAA,GAAgC;AAC9C,EAAA,OAAO,aAAA,CAAc,qBAAqB,CAAA;AAC5C","file":"chunk-EYDRONKO.js","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\nimport { type AuthDeps, getAccessToken, hasStoredAuth, loadStoreAuthConfig } from \"./store-auth.ts\";\n\n/**\n * Connection configuration for the AI Asset Store API. `jwt` is normally left\n * null here and filled per-call by the caller from {@link getStoreToken} (the\n * device-flow session); it stays on the type for the `{ ...config, jwt }` spread.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n}\n\n/**\n * Read the store API base URL (settings `storeUrl` → `SKAILE_STORE_URL` →\n * default). Auth is not read here — it lives in the device-flow session; see\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function getStoreConfig(): StoreConfig {\n const settingsPath = globalSettingsPath();\n let settings: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n settings = mapLegacyFields(JSON.parse(readFileSync(settingsPath, \"utf-8\")));\n } catch {\n settings = {};\n }\n }\n return {\n url: settings.storeUrl ?? process.env.SKAILE_STORE_URL ?? \"https://api.skaile.store\",\n jwt: null,\n };\n}\n\n/**\n * Return a valid store access token (Keycloak device-flow session, refreshed if\n * needed). Throws a \"run `skaile store login`\" error when there is no session.\n * This is the auth source for every `/api/v1/*` publisher call.\n */\nexport function getStoreToken(deps?: AuthDeps): Promise<string> {\n return getAccessToken(loadStoreAuthConfig(), deps);\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API.\n *\n * @param config - Store connection config (URL + auth token).\n * @param path - API path (e.g. `/api/assets`).\n * @param opts - Optional method, body, query params, extra headers, and\n * `timeoutMs` (default 1500). Publisher calls pass a longer timeout because\n * they trigger server-side clone/sync work.\n * @returns Parsed JSON response body.\n * @docLink cli/dev-guide#store-client\n */\nexport async function storeFetch<T = any>(\n config: StoreConfig,\n path: string,\n opts?: {\n method?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n timeoutMs?: number;\n },\n): Promise<T> {\n let url = `${config.url}${path}`;\n if (opts?.params) {\n const sp = new URLSearchParams(opts.params);\n url += `?${sp}`;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(opts?.headers ?? {}),\n };\n if (config.jwt) {\n headers.Authorization = `Bearer ${config.jwt}`;\n }\n\n const fetchOpts: RequestInit = {\n method: opts?.method ?? \"GET\",\n headers,\n };\n if (opts?.body) {\n fetchOpts.body = JSON.stringify(opts.body);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts?.timeoutMs ?? 1_500);\n try {\n const res = await fetch(url, { ...fetchOpts, signal: controller.signal });\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n // Prefer the store's human-readable `message` (e.g. \"Namespace '@x' is\n // reserved … Sign in with GitHub to claim it\") over the bare `error` code\n // (`UNPROCESSABLE_CONTENT`) — the message is the actionable part.\n const b = body as { message?: string; error?: string };\n throw new Error(b.message ?? b.error ?? `Store API error: ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Return `true` when a store session exists (a Keycloak device-flow token cached\n * at `~/.skaile/auth.json`). Validity/refresh is resolved on use via\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(): boolean {\n return hasStoredAuth(loadStoreAuthConfig());\n}\n"]}
1
+ {"version":3,"sources":["../cli/src/store-client.ts"],"names":[],"mappings":";;;;AAuBO,SAAS,cAAA,GAA8B;AAC5C,EAAA,MAAM,eAAe,kBAAA,EAAmB;AACxC,EAAA,IAAI,WAAgC,EAAC;AACrC,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,gBAAgB,IAAA,CAAK,KAAA,CAAM,aAAa,YAAA,EAAc,OAAO,CAAC,CAAC,CAAA;AAAA,IAC5E,CAAA,CAAA,MAAQ;AACN,MAAA,QAAA,GAAW,EAAC;AAAA,IACd;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,QAAA,CAAS,QAAA,IAAY,OAAA,CAAQ,IAAI,gBAAA,IAAoB,0BAAA;AAAA,IAC1D,GAAA,EAAK;AAAA,GACP;AACF;AAOO,SAAS,cAAc,IAAA,EAAkC;AAC9D,EAAA,OAAO,cAAA,CAAe,mBAAA,EAAoB,EAAG,IAAI,CAAA;AACnD;AAaA,eAAsB,UAAA,CACpB,MAAA,EACA,IAAA,EACA,IAAA,EAOY;AACZ,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAA,CAAO,GAAG,GAAG,IAAI,CAAA,CAAA;AAC9B,EAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,IAAA,MAAM,EAAA,GAAK,IAAI,eAAA,CAAgB,IAAA,CAAK,MAAM,CAAA;AAC1C,IAAA,GAAA,IAAO,IAAI,EAAE,CAAA,CAAA;AAAA,EACf;AAEA,EAAA,MAAM,OAAA,GAAkC;AAAA,IACtC,cAAA,EAAgB,kBAAA;AAAA,IAChB,MAAA,EAAQ,kBAAA;AAAA,IACR,GAAI,IAAA,EAAM,OAAA,IAAW;AAAC,GACxB;AACA,EAAA,IAAI,OAAO,GAAA,EAAK;AACd,IAAA,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,MAAA,CAAO,GAAG,CAAA,CAAA;AAAA,EAC9C;AAEA,EAAA,MAAM,SAAA,GAAyB;AAAA,IAC7B,MAAA,EAAQ,MAAM,MAAA,IAAU,KAAA;AAAA,IACxB;AAAA,GACF;AACA,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,SAAA,CAAU,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,OAAA,GAAU,WAAW,MAAM,UAAA,CAAW,OAAM,EAAG,IAAA,EAAM,aAAa,IAAK,CAAA;AAC7E,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,GAAG,SAAA,EAAW,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AACxE,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,OAAO,EAAE,KAAA,EAAO,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,IAAG,CAAE,CAAA;AAI3E,MAAA,MAAM,CAAA,GAAI,IAAA;AACV,MAAA,MAAM,IAAI,MAAM,CAAA,CAAE,OAAA,IAAW,EAAE,KAAA,IAAS,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,IAC1E;AACA,IAAA,OAAO,IAAI,IAAA,EAAK;AAAA,EAClB,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,OAAO,CAAA;AAAA,EACtB;AACF;AASO,SAAS,oBAAA,GAAgC;AAC9C,EAAA,OAAO,aAAA,CAAc,qBAAqB,CAAA;AAC5C","file":"chunk-V3D4HQMS.js","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\nimport { type AuthDeps, getAccessToken, hasStoredAuth, loadStoreAuthConfig } from \"./store-auth.ts\";\n\n/**\n * Connection configuration for the AI Asset Store API. `jwt` is normally left\n * null here and filled per-call by the caller from {@link getStoreToken} (the\n * device-flow session); it stays on the type for the `{ ...config, jwt }` spread.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n}\n\n/**\n * Read the store API base URL (settings `storeUrl` → `SKAILE_STORE_URL` →\n * default). Auth is not read here — it lives in the device-flow session; see\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function getStoreConfig(): StoreConfig {\n const settingsPath = globalSettingsPath();\n let settings: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n settings = mapLegacyFields(JSON.parse(readFileSync(settingsPath, \"utf-8\")));\n } catch {\n settings = {};\n }\n }\n return {\n url: settings.storeUrl ?? process.env.SKAILE_STORE_URL ?? \"https://api.skaile.store\",\n jwt: null,\n };\n}\n\n/**\n * Return a valid store access token (Keycloak device-flow session, refreshed if\n * needed). Throws a \"run `skaile store login`\" error when there is no session.\n * This is the auth source for every `/api/v1/*` publisher call.\n */\nexport function getStoreToken(deps?: AuthDeps): Promise<string> {\n return getAccessToken(loadStoreAuthConfig(), deps);\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API.\n *\n * @param config - Store connection config (URL + auth token).\n * @param path - API path (e.g. `/api/assets`).\n * @param opts - Optional method, body, query params, extra headers, and\n * `timeoutMs` (default 1500). Publisher calls pass a longer timeout because\n * they trigger server-side clone/sync work.\n * @returns Parsed JSON response body.\n * @docLink cli/dev-guide#store-client\n */\nexport async function storeFetch<T = any>(\n config: StoreConfig,\n path: string,\n opts?: {\n method?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n timeoutMs?: number;\n },\n): Promise<T> {\n let url = `${config.url}${path}`;\n if (opts?.params) {\n const sp = new URLSearchParams(opts.params);\n url += `?${sp}`;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(opts?.headers ?? {}),\n };\n if (config.jwt) {\n headers.Authorization = `Bearer ${config.jwt}`;\n }\n\n const fetchOpts: RequestInit = {\n method: opts?.method ?? \"GET\",\n headers,\n };\n if (opts?.body) {\n fetchOpts.body = JSON.stringify(opts.body);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts?.timeoutMs ?? 1_500);\n try {\n const res = await fetch(url, { ...fetchOpts, signal: controller.signal });\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n // Prefer the store's human-readable `message` (e.g. \"Namespace '@x' is\n // reserved … Sign in with GitHub to claim it\") over the bare `error` code\n // (`UNPROCESSABLE_CONTENT`) — the message is the actionable part.\n const b = body as { message?: string; error?: string };\n throw new Error(b.message ?? b.error ?? `Store API error: ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Return `true` when a store session exists (a Keycloak device-flow token cached\n * at `~/.skaile/auth.json`). Validity/refresh is resolved on use via\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(): boolean {\n return hasStoredAuth(loadStoreAuthConfig());\n}\n"]}