@skaile/workspaces 4.37.0 → 4.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (313) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-KTRFFJYM.js → asset-feeds-UYIFZKKG.js} +16 -16
  4. package/dist/asset-feeds-UYIFZKKG.js.map +1 -0
  5. package/dist/asset-manager/catalog-deployer.js +9 -8
  6. package/dist/asset-manager/index.js +15 -14
  7. package/dist/asset-manager/installer.js +11 -10
  8. package/dist/asset-manager/renderers.js +2 -2
  9. package/dist/asset-manager/src/index.d.ts +77 -18
  10. package/dist/asset-manager/src/index.d.ts.map +1 -1
  11. package/dist/asset-manager/src/installer.d.ts +11 -1
  12. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  13. package/dist/bridge/drivers/claude-sdk.js +14 -13
  14. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  15. package/dist/bridge/drivers/codex.js +11 -10
  16. package/dist/bridge/drivers/codex.js.map +1 -1
  17. package/dist/bridge/drivers/continue.js +12 -11
  18. package/dist/bridge/drivers/continue.js.map +1 -1
  19. package/dist/bridge/drivers/echo.js +3 -3
  20. package/dist/bridge/drivers/gemini.js +6 -6
  21. package/dist/bridge/drivers/goose.js +12 -11
  22. package/dist/bridge/drivers/goose.js.map +1 -1
  23. package/dist/bridge/drivers/omp.js +4 -4
  24. package/dist/bridge/drivers/opencode.js +12 -11
  25. package/dist/bridge/drivers/opencode.js.map +1 -1
  26. package/dist/bridge/drivers/qwen.js +6 -6
  27. package/dist/bridge/index.js +15 -14
  28. package/dist/{chunk-SGMCSVTO.js → chunk-27DN4DZD.js} +8 -8
  29. package/dist/{chunk-SGMCSVTO.js.map → chunk-27DN4DZD.js.map} +1 -1
  30. package/dist/{chunk-VOEBLPXO.js → chunk-2EL2PBRC.js} +3 -3
  31. package/dist/{chunk-VOEBLPXO.js.map → chunk-2EL2PBRC.js.map} +1 -1
  32. package/dist/{chunk-VRFKCF3R.js → chunk-36ML6SFP.js} +4 -4
  33. package/dist/{chunk-VRFKCF3R.js.map → chunk-36ML6SFP.js.map} +1 -1
  34. package/dist/{chunk-UFBURH6K.js → chunk-4WKZEMBD.js} +4 -4
  35. package/dist/{chunk-UFBURH6K.js.map → chunk-4WKZEMBD.js.map} +1 -1
  36. package/dist/{chunk-2D3C4AJP.js → chunk-5CYEWBPB.js} +11 -4
  37. package/dist/chunk-5CYEWBPB.js.map +1 -0
  38. package/dist/{chunk-SQ7IN7KR.js → chunk-5K2VT6E2.js} +3 -3
  39. package/dist/{chunk-SQ7IN7KR.js.map → chunk-5K2VT6E2.js.map} +1 -1
  40. package/dist/{chunk-NTASYPDN.js → chunk-5NYBY6ZE.js} +3 -3
  41. package/dist/{chunk-NTASYPDN.js.map → chunk-5NYBY6ZE.js.map} +1 -1
  42. package/dist/{chunk-SOFPA4S4.js → chunk-6EMF4UZI.js} +8 -8
  43. package/dist/{chunk-SOFPA4S4.js.map → chunk-6EMF4UZI.js.map} +1 -1
  44. package/dist/{chunk-WQULDAH2.js → chunk-6KPQDP7P.js} +2 -2
  45. package/dist/{chunk-WQULDAH2.js.map → chunk-6KPQDP7P.js.map} +1 -1
  46. package/dist/{chunk-OPBGV4DX.js → chunk-6VRZ6M2L.js} +3 -3
  47. package/dist/{chunk-OPBGV4DX.js.map → chunk-6VRZ6M2L.js.map} +1 -1
  48. package/dist/{chunk-KN5Y5BXK.js → chunk-7FZSABQV.js} +5 -5
  49. package/dist/{chunk-KN5Y5BXK.js.map → chunk-7FZSABQV.js.map} +1 -1
  50. package/dist/{chunk-FLGLODDF.js → chunk-7RC37XFW.js} +3 -3
  51. package/dist/{chunk-FLGLODDF.js.map → chunk-7RC37XFW.js.map} +1 -1
  52. package/dist/{chunk-5SGS5SN2.js → chunk-7UL2SQQH.js} +4 -4
  53. package/dist/{chunk-5SGS5SN2.js.map → chunk-7UL2SQQH.js.map} +1 -1
  54. package/dist/{chunk-GEEW6SY2.js → chunk-A5EDMBFG.js} +2 -2
  55. package/dist/{chunk-GEEW6SY2.js.map → chunk-A5EDMBFG.js.map} +1 -1
  56. package/dist/{chunk-QABZZROM.js → chunk-ARUJBGAH.js} +3 -3
  57. package/dist/{chunk-QABZZROM.js.map → chunk-ARUJBGAH.js.map} +1 -1
  58. package/dist/{chunk-ENXE4BKS.js → chunk-BQ3HXZNT.js} +2 -2
  59. package/dist/{chunk-ENXE4BKS.js.map → chunk-BQ3HXZNT.js.map} +1 -1
  60. package/dist/{chunk-U4CNCL7Q.js → chunk-CACCIOQL.js} +12 -12
  61. package/dist/{chunk-U4CNCL7Q.js.map → chunk-CACCIOQL.js.map} +1 -1
  62. package/dist/{chunk-5JAO4MXA.js → chunk-DOVURNRK.js} +3 -3
  63. package/dist/{chunk-5JAO4MXA.js.map → chunk-DOVURNRK.js.map} +1 -1
  64. package/dist/{chunk-P4VHQA4N.js → chunk-DSB6X25D.js} +3 -3
  65. package/dist/{chunk-P4VHQA4N.js.map → chunk-DSB6X25D.js.map} +1 -1
  66. package/dist/{chunk-2QYQOJ2F.js → chunk-DV47JNI4.js} +3 -3
  67. package/dist/{chunk-2QYQOJ2F.js.map → chunk-DV47JNI4.js.map} +1 -1
  68. package/dist/{chunk-FZFCOQTI.js → chunk-EETXMMZS.js} +3 -3
  69. package/dist/{chunk-FZFCOQTI.js.map → chunk-EETXMMZS.js.map} +1 -1
  70. package/dist/{chunk-OEBAXTQ4.js → chunk-EOKAFBJ7.js} +3 -3
  71. package/dist/{chunk-OEBAXTQ4.js.map → chunk-EOKAFBJ7.js.map} +1 -1
  72. package/dist/{chunk-6BEGKO2Q.js → chunk-HUNZYTOS.js} +4 -3
  73. package/dist/chunk-HUNZYTOS.js.map +1 -0
  74. package/dist/{chunk-7YCPY6NC.js → chunk-HXG6IZSF.js} +6 -6
  75. package/dist/{chunk-7YCPY6NC.js.map → chunk-HXG6IZSF.js.map} +1 -1
  76. package/dist/{chunk-L7R52OOV.js → chunk-ILAZDNIA.js} +3 -3
  77. package/dist/{chunk-L7R52OOV.js.map → chunk-ILAZDNIA.js.map} +1 -1
  78. package/dist/{chunk-WTBXGJCD.js → chunk-J5UF3OOS.js} +10 -10
  79. package/dist/{chunk-WTBXGJCD.js.map → chunk-J5UF3OOS.js.map} +1 -1
  80. package/dist/{chunk-QKXDRBLL.js → chunk-JEPSP6XK.js} +11 -80
  81. package/dist/chunk-JEPSP6XK.js.map +1 -0
  82. package/dist/{chunk-KIFJWSNC.js → chunk-KAJH3XPW.js} +7 -3
  83. package/dist/chunk-KAJH3XPW.js.map +1 -0
  84. package/dist/chunk-LOHQTTUV.js +29 -0
  85. package/dist/chunk-LOHQTTUV.js.map +1 -0
  86. package/dist/{chunk-MDBAEEY5.js → chunk-MQ42OYKH.js} +159 -7
  87. package/dist/chunk-MQ42OYKH.js.map +1 -0
  88. package/dist/{chunk-YU433JEL.js → chunk-MS2JK4V7.js} +6 -6
  89. package/dist/{chunk-YU433JEL.js.map → chunk-MS2JK4V7.js.map} +1 -1
  90. package/dist/{chunk-DFZDL62S.js → chunk-OLMNDIAU.js} +14 -9
  91. package/dist/chunk-OLMNDIAU.js.map +1 -0
  92. package/dist/{chunk-3SUWLY3H.js → chunk-OQRB7JUS.js} +3 -3
  93. package/dist/{chunk-3SUWLY3H.js.map → chunk-OQRB7JUS.js.map} +1 -1
  94. package/dist/{chunk-RZXP5ZER.js → chunk-PRCUGFXV.js} +3 -3
  95. package/dist/{chunk-RZXP5ZER.js.map → chunk-PRCUGFXV.js.map} +1 -1
  96. package/dist/{chunk-MRS5YHPI.js → chunk-QBQITQAM.js} +3 -3
  97. package/dist/{chunk-MRS5YHPI.js.map → chunk-QBQITQAM.js.map} +1 -1
  98. package/dist/{chunk-R2SYODNK.js → chunk-QWWDDU5Z.js} +274 -67
  99. package/dist/chunk-QWWDDU5Z.js.map +1 -0
  100. package/dist/{chunk-UTZEHXYT.js → chunk-R2U346ER.js} +3 -3
  101. package/dist/{chunk-UTZEHXYT.js.map → chunk-R2U346ER.js.map} +1 -1
  102. package/dist/{chunk-USJWXEXS.js → chunk-R5ARWJGE.js} +46 -41
  103. package/dist/chunk-R5ARWJGE.js.map +1 -0
  104. package/dist/chunk-TLKM4M47.js +78 -0
  105. package/dist/chunk-TLKM4M47.js.map +1 -0
  106. package/dist/{chunk-NFECHLV6.js → chunk-TNWXGHLD.js} +3 -3
  107. package/dist/{chunk-NFECHLV6.js.map → chunk-TNWXGHLD.js.map} +1 -1
  108. package/dist/{chunk-H3KXUUYQ.js → chunk-VDBP6Y5M.js} +4 -4
  109. package/dist/{chunk-H3KXUUYQ.js.map → chunk-VDBP6Y5M.js.map} +1 -1
  110. package/dist/{chunk-XN7DAZB7.js → chunk-VJNTB4DN.js} +5 -5
  111. package/dist/chunk-VJNTB4DN.js.map +1 -0
  112. package/dist/{chunk-BSIHJZKN.js → chunk-XU7JET5Z.js} +107 -26
  113. package/dist/chunk-XU7JET5Z.js.map +1 -0
  114. package/dist/{chunk-A5RRXBLI.js → chunk-YCJ3PJNB.js} +5 -5
  115. package/dist/{chunk-A5RRXBLI.js.map → chunk-YCJ3PJNB.js.map} +1 -1
  116. package/dist/{chunk-VCLN2IUM.js → chunk-YCMZHL4T.js} +31 -27
  117. package/dist/chunk-YCMZHL4T.js.map +1 -0
  118. package/dist/{chunk-V2OQ3BI6.js → chunk-YNUBJY3L.js} +2 -2
  119. package/dist/chunk-YNUBJY3L.js.map +1 -0
  120. package/dist/{chunk-S63H4HDH.js → chunk-YQEF36D5.js} +4 -4
  121. package/dist/{chunk-S63H4HDH.js.map → chunk-YQEF36D5.js.map} +1 -1
  122. package/dist/{chunk-FJYOQMXT.js → chunk-YV3YI3TA.js} +32 -16
  123. package/dist/chunk-YV3YI3TA.js.map +1 -0
  124. package/dist/cli/index.js +755 -533
  125. package/dist/cli/index.js.map +1 -1
  126. package/dist/cli/src/asset-feeds.d.ts.map +1 -1
  127. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  128. package/dist/cli/src/commands/cache.d.ts.map +1 -1
  129. package/dist/cli/src/commands/catalog.d.ts +28 -3
  130. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  131. package/dist/cli/src/commands/complete-resolvers.d.ts +1 -7
  132. package/dist/cli/src/commands/complete-resolvers.d.ts.map +1 -1
  133. package/dist/cli/src/commands/complete.d.ts.map +1 -1
  134. package/dist/cli/src/commands/diff.d.ts +3 -1
  135. package/dist/cli/src/commands/diff.d.ts.map +1 -1
  136. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  137. package/dist/cli/src/commands/library-index.d.ts +8 -0
  138. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  139. package/dist/cli/src/commands/library-publish.d.ts +7 -2
  140. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  141. package/dist/cli/src/commands/manage.d.ts.map +1 -1
  142. package/dist/cli/src/commands/outdated.d.ts +12 -2
  143. package/dist/cli/src/commands/outdated.d.ts.map +1 -1
  144. package/dist/cli/src/commands/project.d.ts +2 -2
  145. package/dist/cli/src/commands/publish-core.d.ts +21 -0
  146. package/dist/cli/src/commands/publish-core.d.ts.map +1 -1
  147. package/dist/cli/src/commands/skailify-lib.d.ts +18 -1
  148. package/dist/cli/src/commands/skailify-lib.d.ts.map +1 -1
  149. package/dist/cli/src/commands/source-manifest-publish.d.ts.map +1 -1
  150. package/dist/cli/src/commands/store.d.ts.map +1 -1
  151. package/dist/cli/src/commands/update.d.ts.map +1 -1
  152. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  153. package/dist/cli/src/paths.d.ts +1 -1
  154. package/dist/cli/src/paths.d.ts.map +1 -1
  155. package/dist/cli/src/store-auth.d.ts.map +1 -1
  156. package/dist/connectors/config.js +6 -5
  157. package/dist/connectors/index.js +19 -18
  158. package/dist/connectors-shared/index.js +2 -2
  159. package/dist/core/index.js +8 -7
  160. package/dist/core/manifest.js +2 -2
  161. package/dist/core/models.js +1 -1
  162. package/dist/core/publish-manifest.js +2 -2
  163. package/dist/core/ref.js +1 -1
  164. package/dist/core/runtime-assets.js +6 -5
  165. package/dist/core/src/asset-roots.d.ts +2 -12
  166. package/dist/core/src/asset-roots.d.ts.map +1 -1
  167. package/dist/core/src/cache-paths.d.ts +7 -3
  168. package/dist/core/src/cache-paths.d.ts.map +1 -1
  169. package/dist/core/src/index.d.ts +3 -3
  170. package/dist/core/src/index.d.ts.map +1 -1
  171. package/dist/core/src/lock.d.ts +27 -4
  172. package/dist/core/src/lock.d.ts.map +1 -1
  173. package/dist/core/src/models.d.ts +26 -6
  174. package/dist/core/src/models.d.ts.map +1 -1
  175. package/dist/core/src/repo-manager.d.ts.map +1 -1
  176. package/dist/core/src/settings.d.ts +2 -1
  177. package/dist/core/src/settings.d.ts.map +1 -1
  178. package/dist/core/src/store.d.ts.map +1 -1
  179. package/dist/core/src/workspace-config.d.ts.map +1 -1
  180. package/dist/core/store.js +2 -1
  181. package/dist/core/workspace-config.js +5 -4
  182. package/dist/deploy/index.js +8 -7
  183. package/dist/deploy/index.js.map +1 -1
  184. package/dist/discovery/index.js +5 -5
  185. package/dist/discovery/src/domains.d.ts +6 -1
  186. package/dist/discovery/src/domains.d.ts.map +1 -1
  187. package/dist/discovery/src/index.d.ts +1 -1
  188. package/dist/discovery/src/index.d.ts.map +1 -1
  189. package/dist/{ensure-sources-IGU65O72.js → ensure-sources-VX63EKY7.js} +18 -17
  190. package/dist/ensure-sources-VX63EKY7.js.map +1 -0
  191. package/dist/factory-assets/connectors/box.js +19 -18
  192. package/dist/factory-assets/connectors/deploy.js +19 -18
  193. package/dist/factory-assets/connectors/devserver.js +19 -18
  194. package/dist/factory-assets/connectors/flow/adapter.js +19 -18
  195. package/dist/factory-assets/connectors/flow/engine.js +9 -8
  196. package/dist/factory-assets/connectors/flow/run-flow.js +21 -20
  197. package/dist/factory-assets/connectors/flow.js +19 -18
  198. package/dist/factory-assets/connectors/git.js +19 -18
  199. package/dist/factory-assets/connectors/gmail.js +19 -18
  200. package/dist/factory-assets/connectors/googledrive.js +19 -18
  201. package/dist/factory-assets/connectors/local.js +19 -18
  202. package/dist/factory-assets/connectors/mattermost.js +19 -18
  203. package/dist/factory-assets/connectors/memory.js +19 -18
  204. package/dist/factory-assets/connectors/minio.js +19 -18
  205. package/dist/factory-assets/connectors/postgres.js +19 -18
  206. package/dist/factory-assets/connectors/s3.js +19 -18
  207. package/dist/factory-assets/connectors/sharepoint.js +19 -18
  208. package/dist/factory-assets/connectors/sqlite.js +19 -18
  209. package/dist/factory-assets/connectors/static-server.js +19 -18
  210. package/dist/factory-assets/connectors/tunnel.js +19 -18
  211. package/dist/factory-assets/connectors/webdav.js +19 -18
  212. package/dist/factory-assets/connectors/xstate-store.js +19 -18
  213. package/dist/factory-assets/connectors/xstate.js +19 -18
  214. package/dist/flows-PX53XFV7.js +25 -0
  215. package/dist/{flows-6MDMBQUZ.js.map → flows-PX53XFV7.js.map} +1 -1
  216. package/dist/{helpers-IELIL4YR.js → helpers-DF55G2YC.js} +18 -17
  217. package/dist/{helpers-IELIL4YR.js.map → helpers-DF55G2YC.js.map} +1 -1
  218. package/dist/library/index.js +12 -11
  219. package/dist/library/install.js +2 -2
  220. package/dist/library/src/config.d.ts +11 -9
  221. package/dist/library/src/config.d.ts.map +1 -1
  222. package/dist/library/src/index.d.ts +2 -2
  223. package/dist/library/src/index.d.ts.map +1 -1
  224. package/dist/library/src/local/db.d.ts.map +1 -1
  225. package/dist/library/src/local/library-manager.d.ts +7 -0
  226. package/dist/library/src/local/library-manager.d.ts.map +1 -1
  227. package/dist/library/src/local/library.d.ts +5 -4
  228. package/dist/library/src/local/library.d.ts.map +1 -1
  229. package/dist/library/src/local/schema.d.ts +2 -0
  230. package/dist/library/src/local/schema.d.ts.map +1 -1
  231. package/dist/library/src/local/sidecar-paths.d.ts.map +1 -1
  232. package/dist/library/src/local/store-paths.d.ts.map +1 -1
  233. package/dist/library/src/remote/cache.d.ts.map +1 -1
  234. package/dist/library/src/sync/git-driver.d.ts +34 -0
  235. package/dist/library/src/sync/git-driver.d.ts.map +1 -1
  236. package/dist/{library-publish-YKBYHZ43.js → library-publish-2PNWJJOY.js} +95 -41
  237. package/dist/library-publish-2PNWJJOY.js.map +1 -0
  238. package/dist/open-library-SUVOMIWZ.js +38 -0
  239. package/dist/{open-library-ULRYWTEA.js.map → open-library-SUVOMIWZ.js.map} +1 -1
  240. package/dist/paths-W4LDORQQ.js +21 -0
  241. package/dist/{paths-4MTICP3T.js.map → paths-W4LDORQQ.js.map} +1 -1
  242. package/dist/{plugin-store-GQ4WQZJ2.js → plugin-store-D45CREMJ.js} +10 -9
  243. package/dist/plugin-store-D45CREMJ.js.map +1 -0
  244. package/dist/project-RTLVOXUU.js +34 -0
  245. package/dist/{project-VKYNDEB6.js.map → project-RTLVOXUU.js.map} +1 -1
  246. package/dist/resolver/index.js +9 -8
  247. package/dist/runner/index.js +28 -27
  248. package/dist/runner/src/composition/bootstrap.d.ts +1 -1
  249. package/dist/runner/src/composition/bootstrap.d.ts.map +1 -1
  250. package/dist/runner/src/runtime-session-emit.d.ts +2 -1
  251. package/dist/runner/src/runtime-session-emit.d.ts.map +1 -1
  252. package/dist/runner/src/serve.d.ts.map +1 -1
  253. package/dist/sdk/asset-manager.js +15 -14
  254. package/dist/sdk/bridge.js +15 -14
  255. package/dist/sdk/core.js +8 -7
  256. package/dist/sdk/flow.js +9 -8
  257. package/dist/sdk/index.js +28 -27
  258. package/dist/sdk/index.js.map +1 -1
  259. package/dist/sdk/resolver.js +9 -8
  260. package/dist/sdk/runner.js +28 -27
  261. package/dist/sdk/session.js +2 -2
  262. package/dist/sdk/types.js +1 -1
  263. package/dist/secrets/index.js +18 -1
  264. package/dist/secrets/src/providers/local.d.ts.map +1 -1
  265. package/dist/session/index.js +2 -2
  266. package/dist/{setup-INJFK3VJ.js → setup-ZA7VZL72.js} +25 -24
  267. package/dist/setup-ZA7VZL72.js.map +1 -0
  268. package/dist/skills-R3RPIPWP.js +25 -0
  269. package/dist/{skills-JHUY4DFE.js.map → skills-R3RPIPWP.js.map} +1 -1
  270. package/dist/{source-IZXICUBU.js → source-Y5YQ7M53.js} +21 -20
  271. package/dist/{source-IZXICUBU.js.map → source-Y5YQ7M53.js.map} +1 -1
  272. package/dist/{source-manifest-publish-4JHOT4PA.js → source-manifest-publish-RZIJNRIW.js} +24 -25
  273. package/dist/source-manifest-publish-RZIJNRIW.js.map +1 -0
  274. package/dist/tui/index.js +28 -27
  275. package/dist/tui/index.js.map +1 -1
  276. package/dist/types/index.js +1 -1
  277. package/dist/types/manifests.js +1 -1
  278. package/dist/types/src/events.d.ts +4 -2
  279. package/dist/types/src/events.d.ts.map +1 -1
  280. package/dist/types/src/manifests/index.d.ts +1 -1
  281. package/dist/types/src/manifests/index.d.ts.map +1 -1
  282. package/dist/types/src/manifests/skill.d.ts +10 -0
  283. package/dist/types/src/manifests/skill.d.ts.map +1 -1
  284. package/dist/workspace-plugin/adapters/mcp.js +15 -14
  285. package/dist/workspace-plugin/adapters/omp.js +7 -7
  286. package/dist/workspace-plugin/index.js +1 -1
  287. package/package.json +1 -1
  288. package/dist/asset-feeds-KTRFFJYM.js.map +0 -1
  289. package/dist/chunk-2D3C4AJP.js.map +0 -1
  290. package/dist/chunk-6BEGKO2Q.js.map +0 -1
  291. package/dist/chunk-BSIHJZKN.js.map +0 -1
  292. package/dist/chunk-DFZDL62S.js.map +0 -1
  293. package/dist/chunk-FJYOQMXT.js.map +0 -1
  294. package/dist/chunk-KIFJWSNC.js.map +0 -1
  295. package/dist/chunk-MDBAEEY5.js.map +0 -1
  296. package/dist/chunk-MIRWAK5C.js +0 -158
  297. package/dist/chunk-MIRWAK5C.js.map +0 -1
  298. package/dist/chunk-QKXDRBLL.js.map +0 -1
  299. package/dist/chunk-R2SYODNK.js.map +0 -1
  300. package/dist/chunk-USJWXEXS.js.map +0 -1
  301. package/dist/chunk-V2OQ3BI6.js.map +0 -1
  302. package/dist/chunk-VCLN2IUM.js.map +0 -1
  303. package/dist/chunk-XN7DAZB7.js.map +0 -1
  304. package/dist/ensure-sources-IGU65O72.js.map +0 -1
  305. package/dist/flows-6MDMBQUZ.js +0 -24
  306. package/dist/library-publish-YKBYHZ43.js.map +0 -1
  307. package/dist/open-library-ULRYWTEA.js +0 -37
  308. package/dist/paths-4MTICP3T.js +0 -20
  309. package/dist/plugin-store-GQ4WQZJ2.js.map +0 -1
  310. package/dist/project-VKYNDEB6.js +0 -33
  311. package/dist/setup-INJFK3VJ.js.map +0 -1
  312. package/dist/skills-JHUY4DFE.js +0 -24
  313. package/dist/source-manifest-publish-4JHOT4PA.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../types/src/events.ts","../types/src/mentions.ts","../types/src/protocol.ts","../types/src/reactions.ts","../types/src/capabilities.ts","../types/src/tool-activity.ts","../types/src/version.ts"],"names":[],"mappings":"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","file":"chunk-V2OQ3BI6.js","sourcesContent":["/**\n * Agent Events — the unified event stream.\n *\n * These are the real-time events emitted by agent drivers (bridge, vm-agent)\n * and consumed by runners, gateways, and frontends. Persistent events are\n * wrapped in a {@link Message} envelope by the host's persistence layer.\n */\n\nimport type {\n CapabilityDeregisterEvent,\n CapabilityInvokedEvent,\n CapabilityRegisterEvent,\n RenderInvokedEvent,\n} from \"./capabilities.js\";\nimport type {\n IncompatibleProtocolEvent,\n ProtocolInfoEvent,\n SessionInitAckEvent,\n SessionInitMismatchEvent,\n} from \"./lifecycle.js\";\nimport type { ContextUsageSnapshot } from \"./context-usage.js\";\nimport type { LogEntry } from \"./logging.js\";\n\n// ---------------------------------------------------------------------------\n// Agent event — discriminated union of all event types\n// ---------------------------------------------------------------------------\n\n/**\n * Discriminated union of every event the Skaile agent runtime can emit.\n *\n * Persistent events are wrapped in a `MessageV2` envelope by the host's persistence\n * layer. Transient events are forwarded over the transport but not appended to the\n * message store. Narrow via `event.type` or a `switch` statement.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type AgentEvent =\n | TextEvent\n | TextRetractEvent\n | ToolCallEvent\n | ToolResultEvent\n | QuestionEvent\n | QuestionReplyEvent\n | ErrorEvent\n | StatusEvent\n | DevServerEvent\n | FileChangeEvent\n | SubagentEvent\n | FinishedEvent\n | A2AMessageEvent\n | StateChangedEvent\n | HandoffEvent\n | ConnectorResponseEvent\n | ConnectorQueryResponseEvent\n | ConnectorMutateResponseEvent\n | PromptAckEvent\n | QueuedPromptsDroppedEvent\n | ConnectorsAvailableEvent\n | LifecycleCompleteEvent\n | TypingEvent\n | UserMessageEvent\n | SyncStatusEvent\n | SecretsReadyEvent\n | ConfiguredEvent\n | MountMountedEvent\n | MountUnmountedEvent\n | MountChangedEvent\n | MountSyncStatusEvent\n | DebugResultEvent\n | LogEntryEvent\n | ValidationWarningEvent\n | SkillsChangedEvent\n | CommandsAvailableEvent\n | FlowBreadcrumbEvent\n | FlowPromptEvent\n | SessionInfoEvent\n | ReactionAddedEvent\n | ReactionRemovedEvent\n | ResourceStatusEvent\n | ConnectorStatusEvent\n | CustomMessageEvent\n | SnapshotEvent\n | CompactionAttemptEvent\n | RuntimeSessionEvent\n | ResumeAttemptedEvent\n | ResumeFailedEvent\n // Protocol v2 capability + lifecycle events\n | CapabilityRegisterEvent\n | CapabilityDeregisterEvent\n | CapabilityInvokedEvent\n | RenderInvokedEvent\n | ProtocolInfoEvent\n | IncompatibleProtocolEvent\n // Protocol v3 session_init lifecycle events\n | SessionInitAckEvent\n | SessionInitMismatchEvent\n // Agent prompt composition (system_prompt_composed)\n | SystemPromptComposedEvent\n // Context window breakdown (context_usage)\n | ContextUsageEvent\n // Live AI-provider health telemetry (401 / 429 attribution)\n | ProviderResponseSeenEvent\n // Live AI-provider quota-window readings\n | ProviderQuotaObservedEvent;\n\n/**\n * A text message from the agent to the user.\n *\n * The most common event type, containing plain-text content generated by the agent.\n *\n * @docLink packages/types/events#text-event\n */\nexport type TextEvent = {\n type: \"text\";\n content: string;\n};\n\n/**\n * Takes back text the agent already streamed as {@link TextEvent}s.\n *\n * Sent when the driver abandons an attempt mid-message and replays the prompt\n * (a lost-transcript resume, an auth refresh, a seat failover): the replay\n * streams the reply afresh, so the half-message the failed attempt left behind\n * would otherwise sit in front of it. `content` is exactly the text to remove\n * and is always a suffix of what the consumer has accumulated since the last\n * boundary it committed. A consumer that already committed that text (or holds\n * something else) should leave it alone rather than cut unrelated prose.\n *\n * Only unfinished text is ever retracted — a message the model completed is\n * part of the transcript the replay resumes from and stays.\n *\n * @since protocol 4.3.0\n * @docLink packages/types/events#text-retract-event\n */\nexport type TextRetractEvent = {\n type: \"text_retract\";\n content: string;\n};\n\n/**\n * A tool call request from the agent.\n *\n * Indicates the agent wants to invoke a tool with the given name and input arguments.\n * The platform should execute the tool and return the result via {@link ToolResultEvent}.\n *\n * @property tool - The name of the tool to invoke (must match a registered tool)\n * @property input - The input arguments to pass to the tool (structure depends on the tool)\n * @property summary - Short technical summary of the tool call (e.g. `$ git status`)\n * @property label - Plain-language description of the call for non-technical\n * users: the agent's own `activity_label` (Bash: `description`), else a\n * derived phrase for built-in tools. Absent when neither is available.\n *\n * @see {@link TextEvent} for plain text messages\n * @see {@link ToolResultEvent} for tool execution results\n * @category Events\n * @since 1.0.0\n * @docLink packages/types/events#tool-call-event\n */\nexport type ToolCallEvent = {\n type: \"tool_call\";\n tool: string;\n input: unknown;\n summary: string;\n /** @since 3.24.0 */\n label?: string;\n /**\n * The tool use that runs the subagent which made this call. Absent on the\n * main thread. Such a call runs concurrently with the main reply, so it\n * does not split that reply's text.\n * @since protocol 4.5.0\n */\n parentToolUseId?: string;\n};\n\n/**\n * The result of a tool execution.\n *\n * Contains the output returned by a tool after it has been executed.\n * This event is typically sent by the platform in response to a {@link ToolCallEvent}.\n *\n * @property tool - The name of the tool that was executed\n * @property output - The result data returned by the tool (structure depends on the tool)\n * @property summary - Short human-readable summary of the result\n *\n * @see {@link ToolCallEvent} for the corresponding tool invocation\n * @category Events\n * @since 1.0.0\n * @docLink packages/types/events#tool-result-event\n */\nexport type ToolResultEvent = {\n type: \"tool_result\";\n tool: string;\n output: unknown;\n summary: string;\n /**\n * The tool use that runs the subagent this result belongs to. Absent on the main thread.\n * @since protocol 4.5.0\n */\n parentToolUseId?: string;\n};\n\n/**\n * A question posed by the agent to the user.\n *\n * Used when the agent needs clarification or input from the user to proceed.\n * The question may include multiple-choice options to guide the user's response.\n *\n * @property question - The question text to display to the user\n * @property options - Optional array of suggested answers (when provided, user should select one)\n *\n * @see {@link QuestionReplyEvent} for the user's response\n * @category Events\n * @since 1.0.0\n * @docLink packages/types/events#question-event\n */\n/** Durable native approval presentation, never tool identity or permission authority. */\nexport type NativeApprovalDescription = {\n kind: \"command\" | \"file\" | \"permissions\" | \"mcp\";\n details: string[];\n};\n\nexport type QuestionEvent = {\n /** Opaque correlated request identity; managed replies must echo it unchanged. */\n requestId?: string;\n /** Fixed Approve once/Deny card; clients must preserve this request's exact identity. */\n approval?: NativeApprovalDescription;\n type: \"question\";\n question: string;\n options?: string[];\n};\n\n/**\n * A question was answered.\n *\n * The runner emits it to every attached client once the paused turn accepted a\n * `reply`, so clients that did not send the reply can drop their question card.\n * It echoes the reply's own `question` / `requestId` when the reply carried\n * them, so a client can tell which of several open questions was answered.\n *\n * @property answer - The user's response text\n * @property question - The sub-question answered, verbatim, when the reply named one (protocol 4.8.0)\n * @property requestId - The answered request's identity, when the reply carried one (protocol 4.8.0)\n *\n * @see {@link QuestionEvent} for the original question\n * @category Events\n * @since 1.0.0\n * @docLink packages/types/events#question-event\n */\nexport type QuestionReplyEvent = {\n type: \"question_reply\";\n answer: string;\n question?: string;\n requestId?: string;\n};\n\n/**\n * An error condition encountered during agent execution.\n *\n * Indicates something went wrong during the agent's operation.\n * The severity determines whether execution can continue.\n *\n * @property message - Human-readable description of the error\n * @property fatal - When true, indicates the error is unrecoverable and execution should stop\n *\n * @category Events\n * @since 1.0.0\n * @docLink packages/types/events#error-event\n */\n\nexport type ErrorEvent = {\n type: \"error\";\n message: string;\n fatal: boolean;\n category?: ErrorCategory;\n /**\n * Short actionable advice for display to the user. Set by the bridge's\n * error classifier when it recognises the upstream failure mode (e.g.\n * \"Quota exhausted on the configured Anthropic account — try again\n * after the rate-limit window resets\"). Optional.\n */\n hint?: string;\n /**\n * Usage of the turn that ended in this error, present only when the error\n * is a turn result (`error_max_turns`, `error_during_execution`, …) and the\n * driver tracked usage. The provider bills the turn either way; a consumer\n * that ledgers `finished` should ledger these too. Same fields and meaning\n * as on {@link FinishedEvent}. Absent on errors that are not a turn result.\n * Added in 3.12.0.\n */\n costUsd?: number;\n /** Main-thread token usage of the failed turn. See {@link FinishedEvent.tokens}. Added in 3.12.0. */\n tokens?: TokenUsage;\n /** Per-model usage of the failed turn. See {@link FinishedEvent.modelUsage}. Added in 3.12.0. */\n modelUsage?: Record<string, ModelTokenUsage>;\n /** Context fill of the failed turn. See {@link FinishedEvent.contextTokens}. Added in 3.12.0. */\n contextTokens?: number;\n /** Context window of the main model. See {@link FinishedEvent.contextWindow}. Added in 3.12.0. */\n contextWindow?: number;\n /**\n * `true` when the driver is about to replay the same prompt in place, with no\n * `status: idle` / `finished` in between. Such an error does NOT end the turn:\n * the replayed attempt is the same turn, with the same starter, and it ends\n * with its own `finished` or `error`. Always sent with `fatal: false`; absent\n * on every other error. A 4.9 runner never sets it. Added in 4.10.0.\n */\n retrying?: boolean;\n /** Why the prompt is replayed; present only with `retrying`. Added in 4.10.0. */\n retryReason?: ErrorRetryReason;\n};\n\n/**\n * Why the driver replays a prompt in place after an {@link ErrorEvent}:\n * - `stale_resume`: the resumed transcript was lost; the prompt runs again on\n * a fresh session (a `resume_failed { jsonl_lost }` precedes it driver-side).\n * - `poison_scrub`: the resumed transcript held a block the API rejects; it was\n * repaired on disk and the same session is resumed again.\n *\n * Consumers must accept unknown values: new retry paths add members.\n *\n * @category Events\n * @since 4.10.0\n */\nexport type ErrorRetryReason = \"stale_resume\" | \"poison_scrub\";\n\n/**\n * A status change notification for the agent.\n *\n * Emitted when the agent's execution phase changes (e.g., thinking → working → idle).\n *\n * @see {@link AgentPhase} for available phase values\n * @category Events\n * @since 1.0.0\n * @docLink packages/types/events#supporting-types\n */\nexport type StatusEvent = {\n type: \"status\";\n phase: AgentPhase;\n};\n\n/**\n * Emitted when a dev server (e.g. Vite, Next.js) starts, becomes ready, or crashes.\n *\n * The platform uses this to surface a preview URL in the session UI.\n *\n * @category Events\n * @since 1.0.0\n * @docLink packages/types/events#agent-event\n */\nexport type DevServerEvent = {\n type: \"dev_server\";\n url: string;\n status: \"starting\" | \"ready\" | \"crashed\";\n};\n\n/**\n * A file system change event.\n *\n * Emitted when files are created, edited, deleted, or conflicted.\n *\n * @property type - Always \"file_changed\"\n * @property path - The file path that changed\n * @property action - What happened: create, edit, delete, or conflict\n * @property mountId - Which mount triggered the change, if any\n *\n * @category Events\n * @since 1.0.0\n * @docLink packages/types/events#file-change-event\n */\n\nexport type FileChangeEvent = {\n type: \"file_changed\";\n path: string;\n action: \"create\" | \"edit\" | \"delete\" | \"conflict\";\n /** Which mount triggered the change, if any. */\n mountId?: string;\n};\n\n/**\n * Status update for a subagent dispatched by the primary agent.\n *\n * Emitted when a named subagent starts or finishes execution. On \"finished\",\n * carries structured output with a summary, changed files, and concerns.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type SubagentEvent = {\n type: \"subagent\";\n name: string;\n status: \"started\" | \"finished\";\n description: string;\n /** Flow node this subagent is executing (set by orchestrator) */\n nodeId?: string;\n /** Structured output from the subagent (set on \"finished\") */\n output?: {\n summary: string;\n filesChanged: string[];\n status: string;\n concerns: string[];\n };\n};\n\n/**\n * Per-turn token usage reported by a driver.\n *\n * All fields are optional so the type can represent partial data — different\n * providers expose different subsets:\n *\n * | Provider | input | output | cacheRead | cacheCreation | reasoning |\n * |-----------|-------|--------|-----------|---------------|-----------|\n * | Anthropic | y | y | y | y | - |\n * | OpenAI | y* | y | y | - | y |\n *\n * `*` Anthropic's `inputTokens` excludes cached/cache-creation reads (they\n * are reported separately). OpenAI's `inputTokens` is the *total* including\n * cached tokens — consumers that want a strict \"fresh input\" count must\n * subtract `cacheReadTokens` themselves.\n *\n * @category Cost\n * @since 3.1.0\n * @docLink packages/types/events#token-usage\n */\nexport type TokenUsage = {\n /** Input/prompt tokens consumed by the turn (provider-specific semantics — see type docstring). */\n inputTokens?: number;\n /** Output/completion tokens generated by the model. */\n outputTokens?: number;\n /** Tokens served from the provider's prompt cache (Anthropic: cache_read_input_tokens; OpenAI: cached_input_tokens). */\n cacheReadTokens?: number;\n /** Tokens written to the prompt cache for future reads (Anthropic-only — OpenAI does not expose this). */\n cacheCreationTokens?: number;\n /** Reasoning tokens consumed by OpenAI reasoning models (o1, o3, ...). */\n reasoningTokens?: number;\n /** Total tokens for the turn when the provider supplies one. */\n totalTokens?: number;\n};\n\n/**\n * One model's share of a turn, including calls the turn-level `tokens` omit.\n *\n * `TokenUsage` on a `FinishedEvent` describes the main thread only: Claude\n * Code's result `usage` skips every request a Task subagent made, while its\n * reported cost includes them. `FinishedEvent.modelUsage` fills that gap,\n * keyed by model id, so consumers can attribute the whole bill and derive the\n * subagent share as `sum(modelUsage[*]) − tokens`. Field semantics follow\n * `TokenUsage` (Anthropic: disjoint prompt slices). Drivers emit per-turn\n * figures here even when the provider reports run-cumulative counters.\n *\n * @category Cost\n * @since 3.11.0\n */\nexport type ModelTokenUsage = Pick<\n TokenUsage,\n \"inputTokens\" | \"outputTokens\" | \"cacheReadTokens\" | \"cacheCreationTokens\"\n> & {\n /** Provider-reported cost of this model's calls in the turn, in USD. */\n costUsd?: number;\n /** Context window of this model, in tokens. */\n contextWindow?: number;\n};\n\n/**\n * Emitted when the agent completes a turn.\n *\n * Carries cost / usage data and optionally a custom message payload for dynamic\n * rendering via the v2 capability registry (`customType` + `customData` fields).\n *\n * `costUsd` semantics: this is per-turn cost in USD. Some providers report a\n * run-cumulative figure instead of a per-turn one — the driver is responsible\n * for normalizing it into a per-turn delta before emitting it here. Drivers\n * that don't surface provider-reported cost emit `0`; consumers distinguishing\n * \"free\" from \"not reported\" should pair `costUsd === 0` with `tokens` being\n * present/absent.\n *\n * @docLink packages/types/events#finished-event\n */\nexport type FinishedEvent = {\n type: \"finished\";\n summary: string;\n costUsd: number;\n /**\n * Per-turn token usage when the driver tracks it. Absent for drivers\n * that do not surface usage (e.g. omp RPC today). Added in 3.1.0.\n */\n tokens?: TokenUsage;\n /**\n * Per-model usage for the turn, subagent calls included, when the driver\n * reports it. See {@link ModelTokenUsage}. Added in 3.11.0.\n */\n modelUsage?: Record<string, ModelTokenUsage>;\n /**\n * Prompt size of the turn's last main-thread API call — the real context\n * fill — when the driver tracks it. `tokens` cannot answer this: it sums\n * every call in the turn. Added in 3.11.0.\n */\n contextTokens?: number;\n /** Context window of the main model, in tokens, when known. Added in 3.11.0. */\n contextWindow?: number;\n /** True when the response was cancelled by the user (partial content). */\n cancelled?: boolean;\n /** Custom message type (e.g. \"gif\") — clients render via a registered dynamic component. */\n customType?: string;\n /** Structured data for custom message types — used as component props. */\n customData?: Record<string, unknown>;\n};\n\n/**\n * An agent-to-agent (A2A) message exchanged between two linked sessions.\n *\n * Persisted as a `Message` row in BOTH the caller and target session\n * conversations — each side stores its own copy with the matching\n * `direction`. `inbound` is the copy in the receiving session's\n * conversation; `outbound` is the copy in the initiating session's\n * conversation. The two copies share the same `exchangeId`.\n *\n * Hosts (the Skaile platform) write this event into `Message.payload`\n * alongside the dedicated `a2aExchangeId` / `peerSessionId` / `a2aDirection`\n * columns. The chat UI's Network / All views render it as a badged A2A card.\n *\n * @docLink packages/types/events#a2a-message-event\n */\nexport type A2AMessageEvent = {\n type: \"a2a_message\";\n /** `inbound` = this session received it; `outbound` = this session sent it. */\n direction: \"inbound\" | \"outbound\";\n /** The other end of the exchange — the peer session's id. */\n peerSessionId: string;\n /** Human-readable name of the peer session, for UI display. */\n peerName: string;\n /** The A2A exchange this message belongs to (`A2AExchange.id`). */\n exchangeId: string;\n /** The message body — the question, answer, or async message text. */\n text: string;\n};\n\n/**\n * Emitted when a shared state store's snapshot changes.\n *\n * Carries the full serialized state snapshot for the named store (e.g. \"flow\", \"session\").\n * Frontends and the platform gateway subscribe to build reactive state views.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type StateChangedEvent = {\n type: \"state_changed\";\n /** Store identifier, e.g. \"flow\", \"session\" */\n store: string;\n /** Serialized state snapshot */\n state: Record<string, unknown>;\n};\n\n/**\n * Emitted when the orchestrator hands execution off to a specific flow node and skill.\n *\n * Carries the context sources and approximate context size used to curate\n * the handoff prompt so operators can diagnose context-window decisions.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type HandoffEvent = {\n type: \"handoff\";\n /** Flow node being handed off to */\n nodeId: string;\n /** Skill being executed */\n skillId: string;\n /** Node IDs that contributed context to this handoff */\n contextSources: string[];\n /** Approximate size of curated context in characters */\n contextSize: number;\n};\n\n/**\n * Response to a `ConnectorRequestCommand` (wire type: `\"resource_response\"`).\n *\n * Correlates to the originating request via `requestId` and carries the\n * operation result or an error string. The wire `type:` string stays as\n * `\"resource_response\"` for protocol stability.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type ConnectorResponseEvent = {\n type: \"resource_response\";\n /** Correlates to the originating resource_request. */\n requestId: string;\n /** Which connector handled the request. */\n resourceId: string;\n /** Which operation was performed. */\n operation: ConnectorOperation;\n /** Result data — shape depends on the operation. */\n data?: unknown;\n /** Error message if the operation failed. */\n error?: string;\n /** Machine-readable failure class, when the runner knows one. Since protocol 4.2.0. */\n code?: ConnectorResponseFailureCode;\n};\n\n/**\n * Response to a `ConnectorQueryCommand`. Carries the JSON-encoded result of\n * a `ConnectorManager.executeOp` call, correlated by `requestId`.\n *\n * Persistence: transient. Hosts that want to record the query side effects\n * should rely on the runner's structured log stream, not on this event.\n *\n * @docLink packages/types/events#connector-query-response-event\n * @since 2.2.0\n */\nexport type ConnectorQueryResponseEvent = {\n type: \"connector_query_response\";\n /** Correlates to the originating ConnectorQueryCommand. */\n requestId: string;\n /** Whether the underlying executeOp resolved without throwing. */\n ok: boolean;\n /** JSON-encoded executeOp result, when `ok === true`. */\n result?: string;\n /** Error message when `ok === false`. */\n error?: string;\n};\n\n/**\n * Machine-readable failure class carried by {@link ConnectorMutateResponseEvent}.\n * Present iff `ok === false`. Hosts branch on this rather than on the free-text\n * `error` string, which is a runner/adapter message and may change.\n *\n * @category Protocol\n * @since 3.7.0\n * @docLink packages/types/events#connector-mutate-response-event\n */\nexport type ConnectorMutateFailureCode =\n /** The target connector never became available within the readiness wait. */\n | \"connector_unavailable\"\n /** `planFlowMutate` rejected the op (malformed or conflicting payload). */\n | \"rejected\"\n /** The adapter threw — illegal transition, unknown node, read-only violation. */\n | \"op_failed\"\n /** `sessionReady` rejected: the session build failed, the container is unusable. */\n | \"session_unavailable\";\n\n/**\n * Outcome of replaying `payload.pendingDecisions` during a flow `hydrate`.\n *\n * Invariant: every supplied entry that carried a string `nodeId` appears in\n * exactly one of `applied` / `skipped`. A skip is a deliberate structural\n * decision, never a failure — the hydrate itself has already succeeded by the\n * time reconciliation runs. Gotcha: the skip entry deliberately carries only\n * `nodeId` + `reason`; the decision payload is user content and is never echoed.\n *\n * @category Protocol\n * @since 3.7.0\n * @docLink packages/types/events#connector-mutate-response-event\n */\nexport type FlowHydrateReconciliation = {\n /** nodeIds whose pending decision was applied during this hydrate. */\n applied: string[];\n /** nodeIds whose pending decision was deliberately not applied. */\n skipped: Array<{\n nodeId: string;\n reason: \"not_parked\" | \"already_decided\" | \"unknown_node\" | \"payload_invalid\";\n }>;\n};\n\n/**\n * Response to a `ConnectorMutateCommand` that carried a `requestId`.\n *\n * Emission invariant: **exactly one** per command that set `requestId`, on every\n * terminal path (including the paths that previously only logged), and **never**\n * for a command without one — that opt-in is the whole 3.6 back-compat story.\n *\n * Persistence: transient. Like `connector_query_response` this is system RPC,\n * not chat; hosts must keep it out of the message store.\n *\n * @category Protocol\n * @since 3.7.0\n * @docLink packages/types/events#connector-mutate-response-event\n */\nexport type ConnectorMutateResponseEvent = {\n type: \"connector_mutate_response\";\n /** Correlates to the originating ConnectorMutateCommand.requestId. */\n requestId: string;\n /** Whether the mutation was applied. */\n ok: boolean;\n /** JSON-encoded executeOp result, when ok === true and the op returned one. */\n result?: string;\n /** Human-readable failure message when ok === false. */\n error?: string;\n /** Machine-readable failure class. Present iff ok === false. */\n code?: ConnectorMutateFailureCode;\n /**\n * Outcome of `payload.pendingDecisions` reconciliation. Present only for\n * `op === \"hydrate\"` on the flow connector, and only when the host supplied\n * pending decisions. Absent is NOT \"nothing applied\" — it is \"not attempted\".\n */\n reconciled?: FlowHydrateReconciliation;\n};\n\n/**\n * Receipt acknowledgement for a `prompt` command that carried a `messageId`.\n *\n * Emission invariant: **exactly one** per prompt that set `messageId`, emitted\n * as the runner's first act — before the session-readiness gate, the secrets\n * check, and the driver start, each of which can otherwise drop the prompt with\n * no trace. It says \"the frame arrived and was decoded\", nothing about the turn\n * ever running; turn-level supervision is a separate concern.\n *\n * Persistence: transient. System RPC, not chat.\n *\n * @category Protocol\n * @since 3.8.0\n */\nexport type PromptAckEvent = {\n type: \"prompt_ack\";\n /** Echoes the originating `prompt` command's `messageId` verbatim. */\n messageId: string;\n};\n\n/**\n * Chat prompts a `cancel` removed from the runner's prompt queue before they\n * ran. Sent only for a `cancel` that named its `senderId`, and only when at\n * least one prompt was dropped.\n *\n * Only prompts of that sender that were still waiting are dropped. The\n * running turn is aborted, not dropped, and other senders' prompts stay\n * queued and run. Hosts mark the listed prompts \"not sent\".\n *\n * Persistence: transient. Broadcast to every client of the session.\n *\n * @category Protocol\n * @since 4.14.0\n */\nexport type QueuedPromptsDroppedEvent = {\n type: \"queued_prompts_dropped\";\n /** The `cancel` command's `senderId`: the user whose prompts were dropped. */\n senderId: string;\n /** `messageId` of each dropped prompt that carried one, in queue order. */\n messageIds: string[];\n /** Number of dropped prompts, including those without a `messageId`. */\n count: number;\n};\n\n/**\n * Emitted after session boot listing all connected mounts and connectors.\n *\n * Consumers use this event to populate the resource explorer and build initial\n * connector status maps. The wire type is `\"resources_available\"`.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type ConnectorsAvailableEvent = {\n type: \"resources_available\";\n /** All connected mounts with their metadata. */\n mounts: MountInfo[];\n /** All connected connectors with their metadata. */\n connectors: ConnectorInfo[];\n /** All runner-managed MCP servers with their metadata. */\n mcp_servers: McpServerInfo[];\n /**\n * `true` when the runner accepts `resource_request` writes and deletes\n * addressed to `SESSION_ROOT_CONNECTOR_ID` (`\"@session\"`), which resolve against the\n * session's own root instead of a mount. Absent on older runners: a host\n * must then keep delivering through the workspace mount.\n */\n sessionRoot?: boolean;\n};\n\n/**\n * Emitted whenever a connector's connection state changes.\n *\n * Transient — not persisted to the message store. Consumed exclusively by\n * `ResourceClient._handleEvent()` in `@skaile/workspaces/store` to maintain the\n * reactive `connectorStatus` map.\n *\n * @docLink packages/types/events#connector-status-event\n */\nexport interface ConnectorStatusEvent {\n type: \"connector_status\";\n /** Matches ConnectorDeclaration.id. */\n connectorId: string;\n /** Current connection state. */\n status: \"connecting\" | \"connected\" | \"error\" | \"disconnected\";\n /** Present when status === \"error\". */\n error?: string;\n /**\n * What kind of failure `error` is, when the runner could tell — present only\n * with status === \"error\". Absent means unclassified, not \"none of the\n * kinds\": most drivers throw plain errors, and older runners never send it.\n */\n errorKind?: ConnectorErrorKind;\n /** Round-trip latency in milliseconds from the last health check. */\n latencyMs?: number;\n}\n\n/**\n * Where a connector connect failure can be fixed.\n *\n * - `credential` — the credential is missing, refused or unusable; reconnecting\n * the account (or re-provisioning the secret) is the fix.\n * - `repo-state` — the on-disk checkout is in a state the connect cannot work\n * with (e.g. a live `.git/index.lock`); a new credential changes nothing.\n * - `config` — the declaration itself is missing or invalid (no source URL, a\n * bad branch name, a required field that resolves to nothing).\n *\n * Senders set a kind only when the thrown error identifies it structurally;\n * receivers must treat an absent or unknown value as unclassified.\n */\nexport type ConnectorErrorKind = (typeof CONNECTOR_ERROR_KINDS)[number];\n\n/** Every {@link ConnectorErrorKind}, for receivers that validate the wire field. */\nexport const CONNECTOR_ERROR_KINDS = [\"credential\", \"repo-state\", \"config\"] as const;\n\n/**\n * Emitted when a lifecycle phase (hibernate, close, compact) completes across all resources.\n *\n * Carries per-resource results so the platform can surface which resources failed\n * during the phase. The `phase` field identifies which lifecycle stage completed.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type LifecycleCompleteEvent = {\n type: \"lifecycle_complete\";\n /** Which lifecycle phase completed. */\n phase: LifecyclePhase;\n /** Per-resource results. */\n results: LifecycleResult[];\n};\n\n/**\n * Transient — broadcast when a user or agent adds an emoji reaction to a message.\n *\n * Not persisted as a message. Consumed by frontends to update the reaction display in real time.\n *\n * @docLink packages/types/events#reaction-events\n */\nexport type ReactionAddedEvent = {\n type: \"reaction_added\";\n /** ID of the message being reacted to. */\n messageId: string;\n /** Sequence number of the target message (for efficient frontend lookup). */\n messageSeq: number;\n emoji: string;\n userId: string;\n userName: string;\n};\n\n/**\n * Transient — broadcast when a user removes a reaction from a message.\n *\n * Not persisted as a message. Consumed by frontends to update the reaction display in real time.\n *\n * @docLink packages/types/events#reaction-events\n */\nexport type ReactionRemovedEvent = {\n type: \"reaction_removed\";\n messageId: string;\n messageSeq: number;\n emoji: string;\n userId: string;\n};\n\n/**\n * Transient typing indicator — not persisted.\n *\n * Broadcast to all session subscribers when a participant starts or stops typing.\n * Frontends use this to render the \"X is typing...\" indicator.\n *\n * @docLink packages/types/events#typing-user-message-secrets-ready-configured-events\n */\nexport type TypingEvent = {\n type: \"typing\";\n userId: string;\n userName: string;\n isTyping: boolean;\n};\n\n/**\n * Transient echo of a user message broadcast to all session subscribers — not persisted.\n *\n * Carries reply-threading fields so clients can detect parent-message relationships\n * and route mention-style notifications.\n *\n * @docLink packages/types/events#typing-user-message-secrets-ready-configured-events\n */\nexport type UserMessageEvent = {\n type: \"user_message\";\n senderId: string;\n senderName: string;\n content: string;\n /** Set when this user message is a reply to a previous message. */\n parentMessageId?: string;\n /** Sender id of the parent message — lets clients detect \"reply to me\". */\n parentSenderId?: string;\n /** When true, clients should treat this reply as a mention-style notification target. */\n notifyParent?: boolean;\n\n // ---------------------------------------------------------------------------\n // Platform extension fields (multi-user privacy / recipient routing).\n // Added with @skaile/workspaces/types 3.2.0 for platform F-23 (mention recipient\n // suffixes). Framework consumers that don't run multi-user sessions can\n // ignore these — single-user forge apps leave them undefined and the\n // event behaves identically to pre-3.2 envelopes.\n // ---------------------------------------------------------------------------\n\n /**\n * Routing mode of the message envelope.\n * - `\"Public\"` (default when omitted) — broadcast to every session\n * subscriber (humans + agent).\n * - `\"Private\"` — visible only to the sender plus everyone listed in\n * `privateRecipientIds`.\n * - `\"HumansOnly\"` — visible to all human subscribers; the agent is\n * excluded from broadcast and notifications.\n *\n * **Invariant (NOT enforced by the type system):** producers MUST populate\n * a non-empty `privateRecipientIds` whenever this is `\"Private\"`. The\n * shape is intentionally flat (rather than a discriminated union) to\n * keep wire compat with older consumers, but this means TypeScript will\n * not catch violations at the call site. **Persistence-layer\n * implementations MUST validate this invariant on intake** and reject /\n * downgrade / log a violation rather than persist a Private message\n * with no recipients (which would be visible to nobody and effectively\n * lost).\n *\n * Reference platform implementation: `PlatformMessageStore.append`\n * throws on `Private + empty recipientIds` to fail fast.\n */\n visibilityMode?: \"Public\" | \"Private\" | \"HumansOnly\";\n\n /**\n * Recipient list for `visibilityMode: \"Private\"`. Each entry is either a\n * user id (matching the platform's user-id shape) or the sentinel\n * `\"__agent__\"` when the agent itself is an explicit recipient (i.e. the\n * sender wrote `@agent_`).\n *\n * MUST be non-empty when `visibilityMode === \"Private\"` — see the\n * invariant note on `visibilityMode` above.\n *\n * Empty / absent for `Public` and `HumansOnly` — recipient sets in those\n * modes are implicit (everyone / everyone-except-agent).\n */\n privateRecipientIds?: string[];\n};\n\n/**\n * Transient signal that provisioned secrets have been stored and resources initialized.\n *\n * The platform waits for this event after sending a `SecretProvisionCommand` before\n * allowing further session interaction.\n *\n * @docLink packages/types/events#typing-user-message-secrets-ready-configured-events\n */\nexport type SecretsReadyEvent = {\n type: \"secrets_ready\";\n};\n\n/**\n * Transient ACK emitted once the agent has finished processing a `configure`\n * command (shared state stores registered, MCP tools rebuilt, active flows\n * rehydrated). Backends await this before releasing the session so prompts\n * can't race the configure handler and start the driver with stale tools.\n *\n * @docLink packages/types/events#typing-user-message-secrets-ready-configured-events\n */\nexport type ConfiguredEvent = {\n type: \"configured\";\n};\n\n/**\n * Emitted when a mount is successfully attached to the workspace.\n *\n * Carries the mount id, filesystem path, driver name, and access level.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type MountMountedEvent = {\n type: \"mount_mounted\";\n id: string;\n mountPath: string;\n driver: string;\n access: string;\n};\n\n/**\n * Emitted when a mount is detached from the workspace.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type MountUnmountedEvent = {\n type: \"mount_unmounted\";\n id: string;\n};\n\n/**\n * Emitted when a file changes within a mounted source.\n *\n * Similar to `FileChangeEvent` but scoped to a specific mount by `id`.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type MountChangedEvent = {\n type: \"mount_changed\";\n id: string;\n path: string;\n action: \"create\" | \"edit\" | \"delete\" | \"conflict\";\n};\n\n/**\n * Progress update for a mount's initial synchronization phase.\n *\n * Emitted repeatedly during the sync lifecycle (enumerating, stubs_ready,\n * downloading, initial_sync_complete). Carries file counts for progress display.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type MountSyncStatusEvent = {\n type: \"mount_sync_status\";\n id: string;\n phase: SyncStatusPhase;\n totalFiles: number;\n downloadedFiles: number;\n stubFiles: number;\n message: string;\n};\n\n/**\n * Persisted chat event summarizing a flow lifecycle milestone.\n *\n * The gateway diffs each incoming flow state_changed event against the\n * previous snapshot and emits breadcrumbs for user-meaningful transitions\n * — flow start/end, approval requests, input requests, and node failures.\n * Per-node traffic (running/complete/skipped) is NOT emitted as a\n * breadcrumb to keep the chat stream readable; that detail lives on the\n * flow execution panel.\n *\n * Breadcrumbs are persisted via the dispatcher's normal message store path\n * and rendered on the frontend as collapsed cards that expand inline.\n *\n * @docLink packages/types/events#flow-breadcrumb-event\n */\nexport type FlowBreadcrumbEvent = {\n type: \"flow_breadcrumb\";\n kind:\n | \"flow_started\"\n | \"flow_finished\"\n | \"flow_failed\"\n | \"flow_cancelled\"\n | \"approval_pending\"\n | \"input_pending\"\n | \"approval_resolved\"\n | \"input_resolved\"\n | \"node_failed\";\n runId: string;\n flowId: string;\n flowName: string;\n /** Node that triggered this breadcrumb, if the kind is node-scoped. */\n nodeId?: string;\n /** Human-readable node label (from flow definition `data.label`). */\n nodeName?: string;\n /** User ID of the actor that caused the transition (if applicable). */\n actorUserId?: string;\n /** One-line summary for the collapsed card rendering. */\n summary?: string;\n};\n\n/**\n * Persisted chat event carrying the orchestrator prompt for one flow turn.\n *\n * The flow runner reassembles the full `# Flow Execution Context` prompt on\n * every turn and hands it to the agent driver. Without this event a host\n * consuming the stream sees the agent replying to input it cannot read, so the\n * runner emits the prompt verbatim immediately before delivering it — the\n * event therefore always precedes that turn's reply events in the stream.\n *\n * `prompt` is byte-identical to the string given to the driver: never\n * redacted, truncated, or re-rendered. Everything the agent saw — user text,\n * node input, stimulus paragraph — is already inside it, which is why the\n * stimulus is carried only as its kind plus the node it concerns.\n *\n * Emitted for main-agent turns and inline sub-flow turns alike; a sub-flow turn\n * carries the **child** flow's `flowId`/`flowName`. Subprompt nodes run on their\n * own isolated driver and emit nothing here.\n *\n * Persisted via the dispatcher's normal message store path.\n *\n * @docLink packages/types/events#flow-prompt-event\n */\nexport type FlowPromptEvent = {\n type: \"flow_prompt\";\n /** Flow run this turn belongs to. */\n runId: string;\n /** Flow definition id. */\n flowId: string;\n /** Human-readable flow name from the definition, which always carries one. */\n flowName: string;\n /**\n * Why the runner drove this turn. Mirrors the runner's `TurnStimulus[\"kind\"]`,\n * re-declared here because this package must not depend on `factory-assets`.\n */\n stimulus:\n | \"flow_started\"\n | \"approval_received\"\n | \"input_received\"\n | \"retry_requested\"\n | \"user_message\"\n | \"resumed_after_hibernation\"\n | \"cancelled\"\n | \"state_changed\";\n /** Compact stimulus label for logs/telemetry, e.g. `approval_received:review:approved`. */\n stimulusLabel: string;\n /** Node the stimulus concerns, when the stimulus is node-scoped. */\n nodeId?: string;\n /** The verbatim orchestrator prompt handed to the agent driver. */\n prompt: string;\n};\n\n/**\n * The session lifecycle phase being executed. Carried in `LifecycleCompleteEvent.phase`\n * and the `lifecycle` command's `phase` field.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type LifecyclePhase = \"hibernate\" | \"close\" | \"compact\";\n\n/**\n * Per-resource result of a lifecycle phase, carried in `LifecycleCompleteEvent.results`.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type LifecycleResult = {\n id: string;\n ok: boolean;\n error?: string;\n /** Human-readable detail (e.g. commit SHA, branch name). */\n detail?: string;\n /**\n * What the connector can prove about its working copy after the hook ran.\n * Set by the git connector on `hibernate`; absent for other connectors, a\n * fleet-managed git mount, and a hook that threw.\n */\n pushState?: ConnectorPushState;\n};\n\n/**\n * What a connector can prove about its working copy after a lifecycle hook, so\n * a host can decide whether deleting the workspace loses anything. Every doubt\n * answers in the \"keep it\" direction. Carries no URL or credential.\n *\n * Deleting is safe only when `clean` and `onRemote` are both `true`, and the\n * host accepts losing the files `ignoredFiles` reports.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type ConnectorPushState = {\n /**\n * No uncommitted changes, tracked or untracked, after the hook ran. Files a\n * `.gitignore` or `info/exclude` ignores do not count; see `ignoredFiles`.\n */\n clean: boolean;\n /**\n * Every commit reachable from a local branch, a local tag, `HEAD`\n * (detached too) or the stash is reachable from some branch head on the remote. Asked of the remote\n * (`ls-remote`, 10 s bound), never read from local `origin/*` refs. `false`\n * whenever the repo has an initialised submodule. `null` = the remote could\n * not be asked (network, auth, timeout): \"cannot tell\", never \"yes\". A remote\n * reached only through ambient global/system git config (credential helper,\n * ssh or CA settings) always reads `null`: the probe switches that config off.\n * Only the newest stash entry is walked (any stash already makes it `false`),\n * and the HEADs of other linked worktrees (`git worktree add`) are not walked.\n */\n onRemote: boolean | null;\n /**\n * The working tree holds ignored files (build output, `node_modules`, a local\n * `.env`). Deleting the workspace loses them; the host decides whether that\n * matters. `null` when the check failed.\n */\n ignoredFiles: boolean | null;\n /** Full HEAD commit sha, or `null` when the repo has no commit or HEAD is unreadable. */\n head: string | null;\n /** The branch checked out, or `null` when HEAD is detached. */\n branch: string | null;\n};\n\n// ---------------------------------------------------------------------------\n// Mount types\n// ---------------------------------------------------------------------------\n\n/**\n * Metadata for a mounted filesystem source, carried in `ConnectorsAvailableEvent.mounts`.\n *\n * Re-declared here to avoid a dependency on `@skaile/workspaces/connectors`; mirrors the\n * connector package's `MountInfo` type.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type MountInfo = {\n id: string;\n driver: string;\n /** Human-readable connection name; the resource-explorer tab renders this over `id`/`driver` when present. */\n label?: string;\n access: \"read-only\" | \"read-write\";\n mountPath: string;\n mounted: boolean;\n source: string;\n};\n\n// ---------------------------------------------------------------------------\n// Connector types (re-declared here to avoid depending on @skaile/workspaces/connectors)\n// ---------------------------------------------------------------------------\n\n/**\n * Metadata for a runner-managed MCP server, carried in `ConnectorsAvailableEvent.mcp_servers`.\n *\n * `live` indicates whether the active driver session already picked up the server's tools\n * without requiring a restart — false means the tools are registered but not yet active.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type McpServerInfo = {\n id: string;\n transport: \"stdio\" | \"sse\" | \"http\";\n live: boolean;\n toolCount: number;\n};\n\n/**\n * Operations a connector can perform. Used in `ConnectorRequestCommand.operation`\n * and `ConnectorResponseEvent.operation`.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type ConnectorOperation =\n | \"list\"\n | \"read\"\n | \"write\"\n | \"delete\"\n | \"search\"\n /** Create one empty directory on a filesystem mount. Since protocol 4.2.0. */\n | \"mkdir\"\n /** Describe one path on a filesystem mount ({@link ConnectorStat}). Since protocol 4.2.0. */\n | \"stat\";\n\n/**\n * Machine-readable failure class on a {@link ConnectorResponseEvent}. Hosts\n * branch on this rather than on the free-text `error`.\n *\n * A runner older than protocol 4.2.0 never sets it: it answers an operation it\n * does not know with an `error` starting `Unsupported operation`, so a host\n * feature-detecting a new operation must accept both forms.\n *\n * @category Protocol\n * @since 4.2.0\n * @docLink packages/types/events#supporting-types\n */\nexport type ConnectorResponseFailureCode =\n /** The target (mount, connector or session root) does not serve this operation. */\n | \"unsupported_operation\"\n /** `mkdir` found something already at the path. */\n | \"already_exists\"\n /** A ranged `read` carried an `offset` or `length` that is not a non-negative safe integer. Since 4.12.0. */\n | \"invalid_range\";\n\n/**\n * Options for a filesystem-mount `stat` operation.\n *\n * @category Protocol\n * @since 4.2.0\n * @docLink packages/types/events#supporting-types\n */\nexport type StatOptions = {\n /**\n * For a directory, walk everything below it and report\n * {@link ConnectorStat.totals}. The walk is capped (entries, time, depth); a\n * capped walk answers with `totals.partial: true` instead of failing.\n */\n recursive?: boolean;\n /** Count dotfiles and dot-directories in `totals`. Off by default, like `list`. */\n includeHidden?: boolean;\n /** Lower the runner's entry cap for this walk. Values above the runner's cap are ignored. */\n maxEntries?: number;\n /** Lower the runner's time budget (ms) for this walk. Values above the runner's budget are ignored. */\n timeoutMs?: number;\n};\n\n/**\n * Options for a filesystem-mount `read` operation.\n *\n * A runner older than protocol 4.6.0 ignores them and classifies as usual, so\n * a host asking for `binary` must still treat a `utf-8` answer carrying U+FFFD\n * as lossy rather than re-encode it.\n *\n * @category Protocol\n * @since 4.6.0\n * @docLink packages/types/events#supporting-types\n */\nexport type ReadOptions = {\n /**\n * `\"binary\"` answers base64 for every file instead of decoding text the\n * first 8 KiB of which hold no NUL byte. A text file still loses its\n * trailing NUL pad (see the runner's NUL-tail rule).\n */\n encoding?: \"binary\";\n /**\n * First byte to read. Setting `offset` or `length` makes this a ranged read:\n * the runner reads only that range, never the whole file, answers base64\n * (`encoding: \"binary\"`, no text classification, no NUL-tail strip) and sets\n * {@link ConnectorContent.range}. A non-negative safe integer; an offset at or\n * past the end answers an empty chunk. Because a chunk keeps every byte, a\n * text file reassembled from chunks still carries the trailing NUL pad a\n * whole-file read strips; a host that wants the old result strips the\n * trailing NUL run itself. Since protocol 4.12.0.\n */\n offset?: number;\n /**\n * Bytes to read from `offset`, at most `MOUNT_READ_MAX_CHUNK_BYTES` (8 MiB):\n * a larger value is clamped, and an absent one means that maximum. The answer\n * says how many bytes it holds in `range.length`. Since protocol 4.12.0.\n *\n * A runner older than 4.12.0 ignores both fields and sends the whole file in\n * one frame, so a host must gate ranged reads on the protocol version, and an\n * answer without `range` means the range was not honored.\n */\n length?: number;\n};\n\n/**\n * Where a ranged `read` chunk sits in its file. Present only when the request\n * carried `ReadOptions.offset` or `ReadOptions.length`.\n *\n * @category Protocol\n * @since 4.12.0\n * @docLink packages/types/events#supporting-types\n */\nexport type ConnectorContentRange = {\n /** First byte of the chunk (the requested offset). */\n offset: number;\n /**\n * Bytes in the chunk. Less than requested only at the end of the file; `0`\n * when `offset` is at or past the end, or when the request asked for\n * `length: 0` (a size probe). A chunked reader must ask for a positive length.\n */\n length: number;\n /** Size of the whole file in bytes; the caller is done when `offset + length >= size`. */\n size: number;\n /**\n * The file's modification time (ISO 8601) when this chunk was read. Each\n * chunk opens the file anew, so a caller that sees it change between chunks\n * (or `size` change) knows the file was replaced mid-transfer and should\n * start over. Absent when the filesystem reports no time.\n */\n modifiedAt?: string;\n};\n\n/**\n * Recursive totals for a directory, from a `stat` with `recursive: true`.\n *\n * When `partial` is true the counts are lower bounds (\"at least N files\"):\n * part of the tree was not seen.\n *\n * @category Protocol\n * @since 4.2.0\n * @docLink packages/types/events#supporting-types\n */\nexport type ConnectorStatTotals = {\n /** Files below the directory, at any depth. Symlinks count as files and are not followed. */\n files: number;\n /** Directories below the directory, at any depth, not counting itself. */\n directories: number;\n /** Sum of the counted files' sizes in bytes. */\n bytes: number;\n /** Whether any part of the tree went uncounted: a cap was reached or a folder was unreadable. */\n partial: boolean;\n /**\n * The cap that cut the totals short. `entries` and `time` end the walk and\n * take precedence; `depth` only leaves out the folders below it. Absent when\n * nothing but unreadable folders made the totals partial.\n */\n stoppedBy?: \"entries\" | \"time\" | \"depth\";\n /** Subfolders that could not be read (e.g. permission denied) and were skipped. */\n unreadable?: number;\n};\n\n/**\n * Result of a filesystem-mount `stat` operation.\n *\n * @category Protocol\n * @since 4.2.0\n * @docLink packages/types/events#supporting-types\n */\nexport type ConnectorStat = {\n /** Last path segment; empty for the mount root. */\n name: string;\n /** The requested path, relative to the mount root. */\n path: string;\n type: \"file\" | \"directory\";\n /** File size in bytes. Absent for directories — see `totals`. */\n size?: number;\n /** Last modification time, ISO 8601. */\n modifiedAt?: string;\n /** Creation time, ISO 8601, when the filesystem records one. */\n createdAt?: string;\n /** Present for a directory stat'ed with `recursive: true`. */\n totals?: ConnectorStatTotals;\n};\n\n/**\n * A single entry in a connector directory listing (result of a `list` operation).\n *\n * Re-declared here to avoid a dependency on `@skaile/workspaces/connectors`.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type ConnectorEntry = {\n name: string;\n path: string;\n type: \"file\" | \"directory\" | \"key\" | \"row\" | \"message\";\n size?: number;\n modifiedAt?: string;\n};\n\n/**\n * File or key content returned by a connector `read` operation.\n *\n * Re-declared here to avoid a dependency on `@skaile/workspaces/connectors`.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type ConnectorContent = {\n data: string;\n encoding?: \"utf-8\" | \"binary\";\n contentType?: string;\n metadata?: Record<string, unknown>;\n /** Set on a ranged `read` only (see {@link ReadOptions.offset}). Since protocol 4.12.0. */\n range?: ConnectorContentRange;\n};\n\n/**\n * Metadata for a connected connector, carried in `ConnectorsAvailableEvent.connectors`.\n *\n * Re-declared here to avoid a dependency on `@skaile/workspaces/connectors`; mirrors\n * the connector package's `ConnectorInfo` type.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type ConnectorInfo = {\n id: string;\n driver: string;\n /** Human-readable connection name; the resource-explorer tab renders this over `id`/`driver` when present. */\n label?: string;\n access: \"read-only\" | \"read-write\";\n operations: string[];\n};\n\n/**\n * Options for a connector `list` operation.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type ListOptions = {\n recursive?: boolean;\n glob?: string;\n limit?: number;\n /**\n * Include entries whose name starts with `.`. Off by default: a browsing\n * listing hides dotfiles. A caller materialising a build context from a\n * mount (where `.env.example`, `.npmrc`, ... must survive) opts in.\n *\n * Honored only by the runner's filesystem-mount `list`; connector drivers\n * (tool-face `list`) ignore it. It is not a security boundary: `read`\n * serves any path regardless. With `recursive` it also walks `.git`, whose\n * entries count against the listing cap, so a caller staging a tree should\n * list one directory at a time and prune before descending.\n */\n includeHidden?: boolean;\n};\n\n/**\n * Options for a connector `search` operation.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type SearchOptions = {\n regex?: boolean;\n caseSensitive?: boolean;\n maxResults?: number;\n};\n\n/**\n * Persistent — a custom-typed message emitted by the agent via a capability\n * tool invocation (`platform.custom_message`). The runner's serve layer\n * forwards these so the platform can persist and render them via the\n * dynamic component pipeline.\n *\n * @category Events\n * @since 2.0.0\n * @docLink packages/types/events#agent-event\n */\nexport type CustomMessageEvent = {\n type: \"custom_message\";\n /** Plain-text summary (e.g. \"[gif: funny cat]\"). */\n content: string;\n /** Custom message type identifier (e.g. \"gif\"). */\n customType: string;\n /** Structured data — used as component props. */\n customData: Record<string, unknown>;\n};\n\n/**\n * Trigger source for a session compaction. Carried in `SnapshotEvent.trigger`\n * and `CompactionAttemptEvent.trigger`.\n *\n * @docLink packages/types/events#snapshot-event\n */\nexport type CompactionTrigger = \"threshold\" | \"hibernate\" | \"manual\";\n\n/**\n * Persistent — a compacted conversation snapshot produced by the LLM.\n * On session restore, only the last snapshot + subsequent messages are replayed.\n *\n * @docLink packages/types/events#snapshot-event\n */\nexport type SnapshotEvent = {\n type: \"snapshot\";\n /** LLM-generated structured summary of the conversation. */\n summary: string;\n /** What triggered this compaction. */\n trigger: CompactionTrigger;\n /** Seq of previous snapshot (0 if first compaction). */\n coversFromSeq: number;\n /** Last seq this snapshot covers. */\n coversToSeq: number;\n /** Estimated context token count before compaction. */\n tokensBefore: number;\n /** Token count of the summary. */\n tokensAfter: number;\n};\n\n/**\n * Persistent -- emitted on EVERY compaction attempt, success or failure.\n *\n * Replaces the in-process circuit breaker in `CompactionOrchestrator` with\n * an observable, owner-controllable record. The platform gateway listens\n * for this event and inserts a `Compaction` row plus updates the\n * `Session.lastCompactionStatus` companion field.\n *\n * `SnapshotEvent` continues to fire on success-only paths (back-compat\n * until Phase 4); both events ride alongside each other through Phase 4.\n *\n * Spec: `_devlog/specs/2026-05-05-session-resume-restart-design.md`\n *\n * @category Compaction\n * @since 3.1.0\n * @docLink packages/types/events#compaction-attempt-event\n */\nexport type CompactionAttemptEvent = {\n type: \"compaction_attempt\";\n /**\n * Outcome of the attempt:\n * - `success`: completed and validated; eligible for tier-2 resume\n * - `failed`: compaction call returned an error or output failed validation\n * - `partial`: reserved (e.g. streaming compaction emitting partial output)\n * - `dirty`: was success at write time but later flagged\n */\n status: \"success\" | \"failed\" | \"partial\" | \"dirty\";\n /**\n * When `status !== 'success'`, a stable identifier for the failure mode.\n * Standard codes:\n * - `rate_limit | auth | account | timeout | parse_error` (from bridge error classifier)\n * - `empty | too_short | poor_ratio` (from validateCompactionOutput)\n *\n * Note: `auth` covers both real credential failures AND payment-blocked\n * OAuth subscriptions that Anthropic mislabels as auth errors. `account`\n * covers a 401 that recurs after a successful credential refresh (hidden-tier\n * rate limit, billing block, anti-abuse throttle) — the credential is fine.\n * Owners investigate further when a Compaction row shows `auth` or `account`.\n *\n * Read alongside {@link CompactionAttemptEvent.elapsedMs}: `empty` at a\n * near-zero elapsed time is an infrastructure failure, not a model one.\n *\n * `null` on success.\n */\n errorCode: string | null;\n /**\n * Wall-clock ms spent inside the compaction `prompt()` call. An `empty`\n * failure at ~0 ms means the turn was settled by a stale consumer rather\n * than by the model. Optional — absent on events from older runners.\n */\n elapsedMs?: number;\n /**\n * Truncated diagnostic text for a failed attempt — the driver error the\n * classifier saw, or which validation check rejected the output. Absent on\n * success and on events from older runners.\n *\n * The same text is mirrored into {@link CompactionAttemptEvent.summary} so a\n * consumer that only persists `summary` still explains the failure. That is\n * safe because a failed attempt is never restored into a session: restoration\n * requires `status: 'success'` with `validatedAt` set.\n */\n errorMessage?: string;\n /** What triggered this attempt. */\n trigger: CompactionTrigger;\n /** LLM-generated summary text. Empty string on failure. */\n summary: string;\n /** Model name used for the call (e.g. \"claude-sonnet-4\"). null when unknown. */\n model: string | null;\n /** Provider id used for the call (e.g. \"anthropic\"). null when unknown. */\n provider: string | null;\n /** Estimated context size before the compaction call — the whole prompt, cached tokens included (= tokensBefore). */\n inputTokens: number;\n /** Output token count of the summary or 0 on failure (= tokensAfter). */\n outputTokens: number;\n /** Seq of previous successful snapshot (0 if first compaction). */\n coversFromSeq: number;\n /** Last seq this attempt covers (current message seq). */\n coversToSeq: number;\n /**\n * Driver session id at the time of the call (for tier-1 native SDK resume).\n * Captured from `driver.runtimeSessionId`. null when the driver does not\n * expose one (e.g. echo, codex).\n */\n driverSessionIdAtCompaction: string | null;\n /**\n * Model name at compaction time. Distinct from `model` (which records what\n * was used for THIS compaction call). For tier-1 resume, the wake-time\n * comparison is against the driver's CURRENT model — if mismatch, falls\n * through to tier 2.\n */\n modelAtCompaction: string | null;\n /**\n * Capability registry signature at compaction time. null in Phase 1\n * (the `computeCapabilitySignature` helper ships in Phase 3).\n */\n capabilitySignatureAtCompaction: string | null;\n /**\n * ISO timestamp set when `validateCompactionOutput` passed.\n * `null` when the attempt failed validation OR produced an error.\n */\n validatedAt: string | null;\n};\n\n// ---------------------------------------------------------------------------\n// Resume cascade events (Phase 3 — tier-1 native SDK resume)\n// ---------------------------------------------------------------------------\n\n/**\n * Transient — emitted by the runner when it honors a\n * `AgentReconfigureOptions.resumeSessionId` in a configure command.\n *\n * The runner emits this once it has decided to recreate the driver with\n * the platform-supplied session id (after capability signature validation\n * passes, if `expectedCapabilitySignature` was provided). The platform\n * gateway records the attempt on the {@link Session} so the UI can show\n * \"Resumed via SDK session\" when wake completes.\n *\n * Spec: `_devlog/specs/2026-05-05-session-resume-restart-design.md`\n * § \"Tier 1: native resume plumbing\".\n *\n * @category Resume\n * @since 3.2.0\n * @docLink packages/types/events#resume-attempted-event\n */\nexport type ResumeAttemptedEvent = {\n type: \"resume_attempted\";\n /** Driver session id the runner is resuming. */\n resumeSessionId: string;\n /** Capability signature computed at attempt time (advisory). */\n capabilitySignature: string;\n};\n\n/**\n * Transient — emitted by the runner or driver when a tier-1 native resume\n * could not be honored.\n *\n * Reasons:\n * - `signature_mismatch`: the runner's current capability signature differs\n * from {@link AgentReconfigureOptions.expectedCapabilitySignature}; the\n * runner dropped the {@link AgentReconfigureOptions.resumeSessionId} hint\n * before driver creation.\n * - `model_mismatch`: reserved — wake-time model comparison happens on the\n * platform side; runner does not currently emit this code, but it is\n * reserved for future driver-level checks.\n * - `jsonl_lost`: emitted by the runner when its pre-ack transcript probe\n * found no transcript (it then drops the hint), or by the claude-sdk driver\n * after the SDK reported \"No conversation found with session ID …\" (as a\n * thrown error or an `is_error` result); the driver replays the prompt on a\n * fresh session so the turn still completes.\n * - `jsonl_poisoned`: emitted by the claude-sdk driver after a replayed\n * resume hit a `400 invalid_request_error` from a transcript image block\n * with a wrong `media_type`. The driver repaired the on-disk JSONL\n * transcript in place (correcting media types, stubbing unprocessable\n * images) and retried the resume — conversation context is preserved.\n *\n * - `native_state_unavailable`: managed Codex positively classified unavailable\n * versioned state and completed one fresh same-binding initialization; the host\n * may restore DB history. Unknown native/auth/policy/transport errors are fatal.\n *\n * @category Resume\n * @since 3.2.0\n * @docLink packages/types/events#resume-failed-event\n */\nexport type ResumeFailedEvent = {\n type: \"resume_failed\";\n /** Driver session id the runner attempted to resume (and dropped). */\n resumeSessionId: string;\n /** Stable reason code; see TSDoc above for the enumeration. */\n reason:\n | \"signature_mismatch\"\n | \"model_mismatch\"\n | \"jsonl_lost\"\n | \"jsonl_poisoned\"\n | \"native_state_unavailable\";\n};\n\n/**\n * Emitted by the runner when the driver's SDK session id first becomes known\n * (after the first turn) and whenever it changes thereafter. Carries the\n * tier-1 native-resume token so the platform can persist it on the Session\n * itself — independently of compaction. Without this the resume token is\n * captured ONLY as a side effect of a compaction (see\n * {@link CompactionAttemptEvent}'s `driverSessionIdAtCompaction`), so a\n * session that never compacts and only auto-hibernates has no stored token\n * and falls through to lossy raw-tail resume on wake even though its JSONL\n * survives on the persistent `.claude` mount.\n *\n * Low frequency: emitted on first-known + change, not per turn. Consumers\n * that do not care ignore it (additive to the union).\n *\n * Spec: platform `_devlog/specs/2026-06-25-tier1-resume-without-compaction.md`.\n *\n * @category Resume\n * @since 3.3.0\n */\nexport type RuntimeSessionEvent = {\n type: \"runtime_session\";\n /** Driver SDK session id, usable as a native `--resume` token. */\n driverSessionId: string;\n /**\n * Model in effect at emit time. The wake-time tier-1 guard compares this\n * against the driver's current model; mismatch forces tier 2. null when\n * the driver does not expose a model.\n */\n model: string | null;\n /** Capability registry signature at emit time (wake-time signature validation). */\n capabilitySignature: string;\n};\n\n// ---------------------------------------------------------------------------\n// Resource lifecycle events (Phase 2 — dynamic resource management)\n// ---------------------------------------------------------------------------\n\n/**\n * Transient ACK emitted by the runner after processing an add_resource or\n * remove_resource command. The gateway awaits this to confirm the operation\n * completed (or failed) before returning to the caller.\n *\n * @docLink packages/types/events#resource-status-event\n */\nexport type ResourceStatusEvent = {\n type: \"resource_status\";\n resourceId: string;\n status: \"mounting\" | \"active\" | \"error\" | \"removed\";\n mountPath?: string;\n error?: string;\n};\n\n// ---------------------------------------------------------------------------\n// Supporting types\n// ---------------------------------------------------------------------------\n\n/**\n * String union of all `AgentEvent[\"type\"]` discriminators.\n *\n * Useful for declaring event type constants or exhaustive switch coverage checks.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type AgentEventType = AgentEvent[\"type\"];\n\n/**\n * The current execution phase of the agent, carried in `StatusEvent.phase`.\n *\n * `\"cancelling\"` is store-local (never sent by the backend as a `StatusEvent.phase`\n * value): `AgentStore.cancel()` sets it optimistically, and only a later,\n * genuine `status` event carries the phase on to `\"idle\"`.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type AgentPhase = \"thinking\" | \"working\" | \"idle\" | \"compacting\" | \"cancelling\";\n\n/**\n * Classification of an agent error, carried in `ErrorEvent.category`.\n *\n * The bridge's error classifier maps upstream errors to these categories so\n * consumers can apply per-category retry and display policies.\n *\n * @docLink packages/types/events#error-event\n */\nexport type ErrorCategory =\n | \"auth\"\n | \"account\"\n | \"rate_limit\"\n | \"model\"\n | \"network\"\n | \"config\"\n | \"process\"\n | \"validation\"\n | \"unknown\";\n\n/**\n * Structured error object used internally when classifying driver errors.\n *\n * Carries the error category, an optional HTTP status code, a retryability flag,\n * and an optional actionable hint for the user.\n *\n * @docLink packages/types/events#error-event\n */\nexport type AgentError = {\n message: string;\n category: ErrorCategory;\n statusCode?: number;\n retryable: boolean;\n hint?: string;\n};\n\n// ── Sync status (transient -- not persisted) ────────────────────────────────\n\n/**\n * Lifecycle phases of a mount's initial sync operation.\n *\n * Carried in `MountSyncStatusEvent.phase` and `SyncStatusEvent.phase`.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type SyncStatusPhase =\n | \"enumerating\"\n | \"stubs_ready\"\n | \"downloading\"\n | \"initial_sync_complete\"\n | \"error\";\n\n/**\n * Legacy alias for `MountSyncStatusEvent` — progress update for a mount sync operation.\n *\n * Carries the mount id, lifecycle phase, and file counts. Prefer `MountSyncStatusEvent`\n * for new code.\n *\n * @docLink packages/types/events#supporting-types\n */\nexport type SyncStatusEvent = {\n type: \"sync_status\";\n mountId: string;\n phase: SyncStatusPhase;\n totalFiles: number;\n downloadedFiles: number;\n stubFiles: number;\n message: string;\n};\n\n/**\n * Transient response to a `DebugCommand` — not persisted.\n *\n * Carries the original query string and the raw diagnostic data returned\n * by the runner's debug handler.\n *\n * @docLink packages/types/events#debug-result-event\n */\nexport type DebugResultEvent = {\n type: \"debug_result\";\n query: string;\n data: unknown;\n};\n\n/**\n * Transient — a single structured log entry from the in-container LogStore.\n * Forwarded by the runner's WsLogSink over the agent transport. The gateway\n * caches a fixed-size ring of these per session for late panel openers.\n * NEVER persisted to the message store — historical reads go through SQLite.\n *\n * @docLink packages/types/events#log-entry-event\n */\nexport type LogEntryEvent = {\n type: \"log_entry\";\n entry: LogEntry;\n};\n\n// ── Asset catalog events (transient — not persisted) ─────────────────────────\n\n/**\n * Transient — emitted when an asset fails schema validation during discovery.\n *\n * Carries the asset name, reason, and an optional suggestion for fixing the issue.\n * Not persisted.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type ValidationWarningEvent = {\n type: \"validation_warning\";\n asset: string;\n reason: string;\n suggestion?: string;\n};\n\n/**\n * Transient — emitted when the skills catalog changes during a session.\n *\n * Carries the list of skills that were added or removed. Not persisted.\n *\n * @docLink packages/types/events#agent-event\n */\nexport type SkillsChangedEvent = {\n type: \"skills_changed\";\n skills: Array<{ name: string; action: string }>;\n};\n\n/**\n * Transient event carrying the agent's discovered slash commands — not persisted.\n *\n * Emitted after the runner discovers the available commands from skills and MCP servers.\n * Frontends use this to populate the slash-command picker.\n *\n * @docLink packages/types/events#commands-available-event\n */\nexport type CommandsAvailableEvent = {\n type: \"commands_available\";\n commands: Array<{\n name: string;\n description: string;\n argumentHint?: string;\n }>;\n};\n\n/**\n * Transient event emitted by the OMP driver after each turn completes.\n * Carries the OMP session ID that can be passed as `resumeSessionId` on the\n * next spawn so OMP restores its full conversation context natively — without\n * needing injected `<conversation_history>` blocks. Not persisted.\n *\n * @docLink packages/types/events#session-info-event\n */\nexport type SessionInfoEvent = {\n type: \"session_info\";\n /** The OMP session identifier (from `get_state` RPC response). */\n driverSessionId: string;\n /** Absolute path to the JSONL session file written by OMP, if known. */\n sessionFile?: string;\n};\n\n// ---------------------------------------------------------------------------\n// System prompt composition (transient — not persisted)\n// ---------------------------------------------------------------------------\n\n/**\n * One labeled section of the assembled system prompt, as broken down by\n * the runner's session-builder. Single-entry labels (`context`, `prompt`,\n * `home`, `environment`, `resources`) appear once; multi-entry labels\n * (`prompt-extensions`, `composition`, `additional`) appear once per\n * source.\n *\n * @since 2026-05\n */\nexport type SystemPromptSection = {\n label:\n | \"context\"\n | \"prompt\"\n | \"home\"\n | \"environment\"\n | \"resources\"\n | \"mcp-guidance\"\n | \"tool-activity\"\n | \"prompt-extensions\"\n | \"composition\"\n | \"additional\";\n value: string;\n /** File path, block id, or descriptor — present for multi-entry labels. */\n source?: string;\n};\n\n/**\n * Emitted by the runner after every `createAgentSession` call (initial\n * configure + every re-build path: `add_resource`, `remove_resource`,\n * `configure`). Carries the labeled section breakdown of the system\n * prompt the agent will receive. Transient — not persisted.\n *\n * @since 2026-05\n */\nexport type SystemPromptComposedEvent = {\n type: \"system_prompt_composed\";\n sections: SystemPromptSection[];\n /** ISO timestamp when the breakdown was produced. */\n composedAt: string;\n};\n\n/**\n * Transient — a breakdown of what occupies the session's context window.\n *\n * Emitted automatically after every turn (`trigger: \"turn-end\"`) and after a\n * successful compaction (`\"compaction\"`), and exactly once in answer to each\n * `get_context_usage` command, carrying that command's `requestId`\n * (`\"request\"`). Automatic snapshots never ask the provider to count tokens;\n * they reuse the last measured breakdown where one exists and estimate the\n * rest, so every bucket carries its own fidelity.\n *\n * @since protocol 4.7.0\n * @docLink packages/types/events#context-usage-event\n */\nexport type ContextUsageEvent = {\n type: \"context_usage\";\n snapshot: ContextUsageSnapshot;\n /** Correlates to the originating `get_context_usage` command; absent on automatic emissions. */\n requestId?: string;\n /**\n * Set when a requested measurement failed and the snapshot fell back to the\n * estimate-only path. The snapshot is still valid; this only explains its fidelities.\n */\n error?: string;\n};\n\n/**\n * Transient — the runner saw the AI provider reject a live request with a 401\n * (credential) or a 429 / subscription-limit rejection, attributed to the AI\n * provider config the session is pinned to.\n *\n * Exists because the platform's per-config health counters were fed only by a\n * slow sampled cron probe: a seat could be exhausted in live traffic and still\n * read as healthy, because the probe checks auth, not capacity. This is the\n * live signal (skaile-ai/workspaces#368, skaile-ai/platform#3539).\n *\n * Fire-and-forget: the runner never waits for it and never retries it, and a\n * platform with no handler for it broadcasts it harmlessly. Every field beyond\n * `status` is optional, and consumers MUST ignore fields they do not know — the\n * two halves of this signal ship independently.\n *\n * @category Events\n * @since 3.9.0\n */\nexport type ProviderResponseSeenEvent = {\n type: \"provider_response_seen\";\n /** 401 — the credential was rejected. 429 — an upstream rate/session limit. */\n status: 401 | 429;\n /** Platform `AIProviderConfig.id` the session is pinned to, when known. */\n configId?: string;\n /** Upstream limit window (`five_hour`, `seven_day`, …) when reported. */\n limitType?: string;\n /** Fraction of the limit window consumed (0–1) when reported. */\n utilization?: number;\n /** Epoch seconds at which the limit window resets, when reported. */\n resetsAt?: number;\n /**\n * What the 429 was, when the runner recognised something narrower than a\n * usage limit. `long-context-entitlement`: the account may not use a long\n * (1M) context window, so the seat is not out of quota. Diagnostic only:\n * the runner still fails over and counts the 429 as before. Consumers must\n * ignore values they do not know. Added in 4.11.0.\n */\n cause?: string;\n /** ISO-8601 timestamp of the observation. */\n observedAt: string;\n};\n\n/**\n * Transient — one upstream quota-window reading (claude-sdk `rate_limit_event`),\n * attributed to the AI provider config the session is pinned to. Emitted for\n * every status, not only rejections, and only when the reading changed since\n * the last one the runner sent for that `(configId, window)`.\n *\n * Exists because a `claude setup-token` seat's token cannot read the OAuth\n * usage endpoint, so live traffic is the only place its quota is visible. The\n * upstream reports `utilization` on warnings and rejections only; an `allowed`\n * reading carries the window and its reset, not a percentage.\n *\n * Fire-and-forget, like {@link ProviderResponseSeenEvent}: consumers MUST\n * ignore fields they do not know, and treat `window` / `status` as open sets.\n *\n * @category Events\n * @since 4.1.0\n */\nexport type ProviderQuotaObservedEvent = {\n type: \"provider_quota_observed\";\n /** Platform `AIProviderConfig.id` the session is pinned to, when known. */\n configId?: string;\n /** Upstream window, verbatim: `five_hour`, `seven_day`, or a future value. */\n window: string;\n /** Upstream status, verbatim: `allowed`, `allowed_warning`, `rejected`, or a future value. */\n status: string;\n /** Fraction of the window consumed (0–1), only when the upstream reported it. */\n utilization?: number;\n /** Epoch seconds at which the window resets, only when reported. */\n resetsAt?: number;\n /** ISO-8601 timestamp of the observation. */\n observedAt: string;\n};\n","/**\n * Mentions — types for @-mention support in session messages.\n *\n * A Mention records who was addressed in a message, whether a specific user\n * or a well-known group. Group mentions carry a resolved array of user IDs\n * so consumers can perform membership checks without the resolver.\n */\n\n// ---------------------------------------------------------------------------\n// Groups\n// ---------------------------------------------------------------------------\n\n/**\n * Well-known group mention targets as a `const` array.\n *\n * Use this for validation or exhaustive checks against `MentionGroup`.\n *\n * @docLink packages/types/messages#mention\n */\nexport const MENTION_GROUPS = [\"agent\", \"humans\", \"humans_here\", \"here\", \"all\"] as const;\n\n/**\n * A well-known group that can be `@`-mentioned: `'agent' | 'humans' | 'humans_here' | 'here' | 'all'`.\n *\n * @docLink packages/types/messages#mention\n */\nexport type MentionGroup = (typeof MENTION_GROUPS)[number];\n\n// ---------------------------------------------------------------------------\n// Mention discriminated union\n// ---------------------------------------------------------------------------\n\n/**\n * A parsed `@`-mention in a session message. Records who was addressed — either a\n * specific user or a well-known group — along with the source text position.\n *\n * Group mentions carry a resolved array of user IDs so consumers can perform\n * membership checks without needing the resolver.\n *\n * @docLink packages/types/messages#mention\n */\nexport type Mention =\n | {\n type: \"user\";\n userId: string;\n name: string;\n /** Position of the `@` character in the source text. */\n offset: number;\n /** Length of the full `@token` string including the `@`. */\n length: number;\n }\n | {\n type: \"group\";\n group: MentionGroup;\n /** User IDs resolved at parse time (e.g. all online users for `@here`). */\n resolved: string[];\n /** Position of the `@` character in the source text. */\n offset: number;\n /** Length of the full `@token` string including the `@`. */\n length: number;\n }\n | {\n type: \"custom\";\n /** Consumer-defined mention kind, e.g. \"assistant\". */\n kind: string;\n /** User IDs this mention resolves to (so isMentioned works); may be empty. */\n resolved: string[];\n /** Optional consumer payload, e.g. { sessionId, ownerId }. */\n data?: Record<string, unknown>;\n /** Position of the `@` character in the source text. */\n offset: number;\n /** Length of the full `@token` string including the `@`. */\n length: number;\n };\n","/**\n * Agent Protocol — messages exchanged between agent client and server.\n *\n * AgentCommand: sent toward the agent (client → server)\n * AgentEvent: sent from the agent (server → client) — defined in events.ts\n *\n * Protocol v3 (since `@skaile/workspaces/types@4.0.0`, shipped 2026-05-10) removed\n * the following commands from the {@link AgentCommand} union: `configure` /\n * `ConfigureCommandV2`, `provision_secrets`, `request_access_token`,\n * `add_resource`, `remove_resource`, `set_log_level`, `state_action`,\n * `lifecycle`, `remount_mount`, `compact`, `reconfigure_agent`. Their\n * semantics ride on:\n * - {@link SessionInitCommand} (one deterministic envelope at session\n * start that delivers identity, resolved config, pre-minted credentials,\n * secrets, capabilities, shared state, active flows, resume hints, and\n * logging config), and\n * - `host.*` / `runner.*` capability invocations (bidirectional\n * capability registry).\n *\n * Spec: `_devlog/specs/2026-05-10-deterministic-session-bootstrap.md`.\n */\n\nimport type {\n CapabilityApproveCommand,\n CapabilityDeregisterCommand,\n CapabilityRegisterCommand,\n CapabilityResultCommand,\n} from \"./capabilities.js\";\nimport type {\n ConnectorContent,\n ConnectorOperation,\n ListOptions,\n ReadOptions,\n SearchOptions,\n StatOptions,\n} from \"./events.js\";\nimport type { ReplyRef } from \"./messaging.js\";\n\n/** Text and scoped attachments; unsupported drivers must reject attachments explicitly. */\nexport interface AgentPromptInput {\n text: string;\n attachments?: Array<\n | { type: \"image\"; path: string }\n | { type: \"file\"; path: string; name: string }\n | { type: \"skill\"; path: string; name: string }\n >;\n}\n\n/**\n * Discriminated union of all commands sent from client to agent server.\n *\n * Narrow via `command.type` or a `switch` statement.\n *\n * @docLink packages/types/protocol-v3#agent-command\n */\nexport type AgentCommand =\n // `messageId` is an opt-in receipt-correlation token (Protocol 3.8). When\n // present the runner MUST emit exactly one `prompt_ack` carrying it back,\n // as the first act of handling the prompt — before any readiness gate that\n // could swallow it. Absent, the prompt is fire-and-forget as in 3.7.\n // `senderId` (4.14) is the user who sent it, the same id as\n // `MessageMeta.senderId`; a `cancel` from that user drops it while it waits.\n | {\n type: \"prompt\";\n prompt: string;\n attachments?: AgentPromptInput[\"attachments\"];\n replyTo?: ReplyRef;\n messageId?: string;\n senderId?: string;\n }\n // `question` binds the answer to the sub-question it belongs to, verbatim from\n // the `question` event that asked it. Omit it and the answer fills the next\n // unanswered slot in order — correct only while the host answers top-down.\n | { type: \"reply\"; answer: string; question?: string; requestId?: string }\n // `senderId` (4.14) is the user who pressed Stop. With it the runner also\n // drops that user's queued prompts and reports them in\n // `queued_prompts_dropped`; without it only the running turn is aborted.\n | { type: \"cancel\"; senderId?: string }\n | { type: \"shutdown\" }\n | ConnectorRequestCommand\n | DebugCommand\n | ConnectorMutateCommand\n | ConnectorQueryCommand\n | ConnectorConfigCommand\n | StateUpdateCommand\n | CustomMessageCommand\n | GetContextUsageCommand\n // Protocol v2 capability commands.\n | CapabilityRegisterCommand\n | CapabilityDeregisterCommand\n | CapabilityResultCommand\n | CapabilityApproveCommand;\n\n// ---------------------------------------------------------------------------\n// Resource declaration types (retained for capability inputs)\n// ---------------------------------------------------------------------------\n\n/**\n * A resource declaration carried by `runner.add_mount` / `runner.add_connector`\n * capability invocations. Mirrors the `skaile.yaml` mount/connector schema\n * but flattened for transport.\n *\n * Used by:\n * - {@link ResolvedSkaileConfig.mounts} / `.connectors` (lifecycle.ts)\n * - `runner.add_mount.input.declaration` / `runner.add_connector.input.declaration`\n *\n * @docLink packages/types/protocol-v3#resource-declaration\n */\nexport type ResourceDeclaration = {\n id: string;\n driver: string;\n source: string;\n target?: string;\n access: \"read-only\" | \"read-write\";\n auth?: string;\n /**\n * Identifier of the `ProviderLink` this resource is bound to when\n * `auth: 'backend'`. Read by the platform credential mediator to dispatch\n * the mint (and re-read by the runner when an `exposeAccessToken` git\n * mount needs to surface a managed-gitconfig credential helper). Optional\n * because not every backend-auth driver is provider-linked, and not every\n * resource uses backend auth.\n */\n providerLinkId?: string;\n options?: Record<string, unknown>;\n};\n\n/**\n * Migration strategy carried by `runner.add_mount.input.migration` when\n * replacing the workspace mount of an empty project.\n *\n * @docLink packages/types/protocol-v3#resource-migration\n */\nexport type ResourceMigration =\n | { strategy: \"replace-workspace\"; targetFolder?: string | null }\n | { strategy: \"none\" };\n\n// ---------------------------------------------------------------------------\n// Generic connector mutation / query (Protocol 2.2 — kept in v3)\n// ---------------------------------------------------------------------------\n//\n// Phase 4 of the flow-connector extraction removed the 6 typed flow commands\n// (`start_flow`, `approve_flow_node`, `provide_flow_input`, `cancel_flow`,\n// `set_flow_autonomous_mode`, `retry_flow_node`) plus the implicit\n// `configure.activeFlows` rehydration. Every removed command is reachable\n// via `connector_mutate` against the `flow` connector — see\n// `MIGRATION-flow-connector.md` for the per-op mapping table.\n\n/**\n * Generic connector mutation. Routes to ConnectorManager.executeOp(id, op, payload).\n * Replaces the typed flow commands in Protocol 2.2 — see\n * MIGRATION-flow-connector.md for the per-op mapping table.\n *\n * @docLink packages/types/protocol-v3#connector-mutate-command\n * @since 2.2.0\n */\nexport type ConnectorMutateCommand = {\n type: \"connector_mutate\";\n /** Target connector id (matches `connectors[].id` in skaile.yaml). */\n id: string;\n /** Operation name as declared by the adapter's describeOperations(). */\n op: string;\n /** Operation arguments. Adapter-specific shape. Optional for nullary ops. */\n payload?: Record<string, unknown>;\n /**\n * Opt-in acknowledgement correlation (Protocol 3.7). When present the runner\n * MUST emit exactly one `connector_mutate_response` carrying this `requestId`.\n * When absent the command is fire-and-forget, byte-identical to 3.6 behaviour.\n */\n requestId?: string;\n};\n\n/**\n * Generic connector read. Same dispatch as connector_mutate but the result\n * is returned to the caller as a `connector_query_response` event correlated\n * by `requestId`. Use for read-only queries that should not kick a turn.\n *\n * @since 2.2.0\n */\nexport type ConnectorQueryCommand = {\n type: \"connector_query\";\n requestId: string;\n id: string;\n op: string;\n payload?: Record<string, unknown>;\n};\n\n/**\n * Ask the runner for a breakdown of the session's context window.\n *\n * Answered by exactly one `context_usage` event carrying the same `requestId`,\n * whatever happens — a failed measurement falls back to an estimate and says so\n * in the event's `error`. `detail: \"measured\"` (the default) asks the driver to\n * count natively where it can; for claude-sdk that includes a `count_tokens`\n * round-trip that uploads the whole conversation, so hosts should request it\n * on demand rather than on a timer. `\"estimated\"` makes no provider call: the\n * driver answers from local estimates (or not at all) and the runner fills the\n * rest. A runner below protocol 4.7 ignores the command.\n *\n * @docLink packages/types/protocol-v3#get-context-usage-command\n * @since 4.7.0\n */\nexport type GetContextUsageCommand = {\n type: \"get_context_usage\";\n requestId: string;\n detail?: \"measured\" | \"estimated\";\n};\n\n/**\n * Query the internal state of a running agent server for diagnostics.\n *\n * @docLink packages/types/protocol-v3#debug-command\n */\nexport type DebugCommand = {\n type: \"debug\";\n query: \"tools\" | \"connectors\" | \"mcp\" | \"config\" | \"state\" | \"commands\";\n args?: Record<string, unknown>;\n};\n\n/**\n * Reserved `ConnectorRequestCommand.connectorId` that addresses the session's\n * own root directory (the runner's project dir, `/skaile` in a container)\n * rather than a mount. Only `write` and `delete` are served, and only for\n * `skaile.yaml`, `.skaile/assets/**` and `.skaile/chat-files/**`. It is never\n * registered as a connector, so the agent's prompt and the\n * `resources_available` lists do not show it. The runner routes this id\n * before any connector lookup, so a connector declared with it is unreachable\n * through `resource_request`.\n */\nexport const SESSION_ROOT_CONNECTOR_ID = \"@session\";\n\n/**\n * Browse or modify connectors from the frontend.\n *\n * The wire `type:` string is `\"resource_request\"` for protocol stability.\n * The server responds with a `ConnectorResponseEvent` correlated by `requestId`.\n *\n * @docLink packages/types/protocol-v3#connector-request-command\n */\nexport type ConnectorRequestCommand = {\n type: \"resource_request\";\n /** UUID for request/response correlation. */\n requestId: string;\n /** Connector ID (e.g. \"docs\", \"project-db\"). */\n connectorId: string;\n /** Operation to perform. */\n operation: ConnectorOperation;\n /** Target path (directory, file, key, etc.). */\n path?: string;\n /** Operation-specific options (ListOptions, SearchOptions, StatOptions, ReadOptions). */\n options?: ListOptions | SearchOptions | StatOptions | ReadOptions;\n /** Content payload for write operations. */\n content?: ConnectorContent;\n};\n\n/**\n * Sent by the frontend to add, remove, or refresh connectors at runtime without a session restart.\n *\n * @docLink packages/types/protocol-v3#connector-config-command\n */\nexport interface ConnectorConfigCommand {\n type: \"connector_config\";\n action: \"add\" | \"remove\" | \"refresh\";\n /** Required when action === \"add\". */\n declaration?: {\n id: string;\n driver: string;\n access?: \"read-only\" | \"read-write\";\n options?: Record<string, unknown>;\n };\n /** Required when action === \"remove\". */\n connectorId?: string;\n}\n\n/**\n * Client/component writes shared state to the runtime.\n *\n * Store namespace must start with `\"app\"` or `\"component:\"` when sent from the client.\n *\n * @docLink packages/types/protocol-v3#state-update-command\n */\nexport type StateUpdateCommand = {\n type: \"state_update\";\n /** Store namespace — must start with \"app\" or \"component:\" from client. */\n store: string;\n /** Full state snapshot (replaces previous). */\n state: Record<string, unknown>;\n};\n\n/**\n * User-originated message with a custom type (from input extensions).\n *\n * Unlike a plain `prompt`, a custom message carries structured data\n * (`customType` + `customData`) alongside the text content. The agent\n * receives these on the `finished` event as `customType`/`customData`\n * fields. On the frontend, the custom message is rendered by the\n * matching dynamic component (or its fallback template).\n *\n * @docLink packages/types/protocol-v3#custom-message-command\n */\nexport type CustomMessageCommand = {\n type: \"custom_message\";\n /** Plain-text content (backward-compatible summary). */\n content: string;\n /** Custom message type identifier (e.g. \"gif\"). */\n customType: string;\n /** Structured data for the custom message type. */\n customData: Record<string, unknown>;\n};\n","/**\n * Reactions -- emoji reactions on session messages.\n *\n * Any session participant (user or agent) can react to any message.\n * Reactions are persisted in a dedicated DB model and broadcast as\n * transient events for real-time updates.\n */\n\n/**\n * A single emoji reaction on a message, set by any session participant (user or agent).\n *\n * Reactions are persisted in a dedicated DB model and broadcast as transient events\n * for real-time updates.\n *\n * @docLink packages/types/messages#reaction\n */\nexport type Reaction = {\n /** Unicode emoji character (e.g. \"thumbs up\", not \":thumbsup:\"). */\n emoji: string;\n /** ID of the user (or \"agent\" for agent reactions). */\n userId: string;\n /** Display name at reaction time (avoids extra lookups for tooltip rendering). */\n userName: string;\n /** Unix epoch milliseconds. */\n timestamp: number;\n};\n\n/**\n * Quick-access emojis shown in the reaction bar picker.\n *\n * An `as const` array of eight Unicode emoji characters in display order.\n *\n * @docLink packages/types/messages#reaction\n */\nexport const QUICK_REACTIONS = [\n \"\\u{1F44D}\",\n \"\\u{1F440}\",\n \"\\u2705\",\n \"\\u2764\\uFE0F\",\n \"\\u{1F914}\",\n \"\\u{1FAE1}\",\n \"\\u{1F44F}\",\n \"\\u{1F389}\",\n] as const;\n","/**\n * Capability layer — Protocol v2's unified registry of LLM-invokable entry points.\n *\n * A {@link Capability} is a named, schema-typed entry point that the LLM can call\n * during a session. Capabilities are registered into a per-session\n * registry by either side (host platform via `side: 'client'` or runtime via\n * `side: 'agent'`) and routed by the bridge at invocation time.\n *\n * This module defines the wire types only; the runtime registry, the\n * `defineCapability` helper, and the per-handler logger live in\n * `@skaile/workspaces/runner`.\n *\n * @see {@link MessageV2} envelope that carries capability commands and events\n * @see {@link ProtocolVersion} for the version contract\n *\n * @category Capabilities\n * @since 2.0.0\n */\n\n// ---------------------------------------------------------------------------\n// Capability shape\n// ---------------------------------------------------------------------------\n\n/**\n * Visibility scope for a capability. Determines which surfaces the capability\n * appears on and which callers can invoke it.\n *\n * - `'llm'`: registered as an LLM tool, surfaced in the `<CAPABILITIES>` system\n * prompt section. The agent driver can invoke it.\n * - `'user'`: appears in user-facing surfaces — the command palette (cmdK),\n * debug menus, capability lists.\n * - `'runtime'`: invocable only by trusted runner / platform code paths. Never\n * reaches the LLM tool list. Never reaches the command palette. Used for\n * host RPCs (`host.refresh_credential`, `host.audit`, `host.notify_user`,\n * `host.persist_compaction_attempt`) and runner RPCs (`runner.add_mount`,\n * `runner.set_log_level`, `runner.lifecycle`, ...).\n *\n * Multiple audiences are allowed (e.g. `['llm', 'user']`). The default when\n * {@link Capability.audience} is omitted is `['llm', 'user']`, preserving the\n * v2.x default visibility for capabilities that haven't migrated yet.\n *\n * @category Capabilities\n * @since 3.0.0\n * @docLink packages/types/capabilities#capability-audience\n */\nexport type CapabilityAudience = \"llm\" | \"user\" | \"runtime\";\n\n/**\n * Source of truth for who registered a capability. Used for trust enforcement\n * (the bridge rejects mismatches between registering side and origin kind)\n * and for the `capability:<origin>:<name>` log taxonomy.\n *\n * Variants:\n * - `framework`: built-in (e.g. `__capabilities.list`)\n * - `client`: host platform (e.g. `platform.react`)\n * - `agent`: self-registered by the agent runtime\n * - `flow`: injected by an active flow execution\n * - `skill`: from a skill's MCP surface\n * - `mcp`: from a generic MCP server\n * - `connector`: from a connector (e.g. `postgres.query`)\n * - `mount`: surfaced by a filesystem mount\n * - `app`: from an embedded, agent-controllable app (carries the originating\n * `appId`). Handlers run in the app itself — see {@link Capability.side} `'app'`.\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#capability-origin\n */\nexport type CapabilityOrigin =\n | { kind: \"framework\" }\n | { kind: \"client\" }\n | { kind: \"agent\" }\n | { kind: \"flow\"; flowId: string }\n | { kind: \"skill\"; skillId: string }\n | { kind: \"mcp\"; serverId: string }\n | { kind: \"connector\"; connectorId: string }\n | { kind: \"mount\"; mountId: string }\n | { kind: \"app\"; appId: string };\n\n/**\n * Render contract for a capability that produces a UI surface when invoked.\n *\n * When the LLM invokes a capability whose `render` is set, the bridge emits\n * a {@link RenderInvokedEvent} carrying the capability name and props. The\n * client renders the configured `source` at the chosen `target`. Clients\n * without a render layer can fall back to the markdown `fallback` template.\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#render-spec\n */\nexport type RenderSpec = {\n /** Where the rendered component lives. */\n source: { kind: \"web-component\"; url: string; tagName: string } | { kind: \"iframe\"; url: string };\n /** Render placements supported by the component. */\n targets: (\"chat\" | \"preview\" | \"modal\" | \"input-extension\")[];\n /** Markdown template with `{{prop}}` placeholders for clients without a render layer. */\n fallback?: string;\n /** True when props may be partial during streaming. */\n streaming?: boolean;\n /** Interaction names the rendered component may fire back as state events. */\n interactions?: string[];\n};\n\n/**\n * A named, schema-typed entry point that the LLM can invoke during a session.\n *\n * Capabilities can be declared statically (via `ConfigureCommand.capabilities`)\n * or dynamically (via {@link CapabilityRegisterCommand} /\n * {@link CapabilityRegisterEvent}). They are cached for replay across\n * subscriber reconnects and session hibernation.\n *\n * @example Defining a client-side fire-and-forget tool (uses the runner's\n * `defineCapability` helper, which serializes a {@link Capability} to the wire):\n * ```ts\n * const reactTool = defineCapability({\n * name: 'platform.react',\n * description: 'Acknowledge a user message with a Unicode emoji.',\n * side: 'client',\n * origin: { kind: 'client' },\n * fireAndForget: true,\n * input: z.object({ emoji: z.string(), targetSeq: z.number().optional() }),\n * handler: async ({ emoji, targetSeq }, ctx) => { ... },\n * });\n * ```\n *\n * @see {@link RenderCapability} for capabilities that render UI components\n * @see {@link CapabilityOrigin} for who-registered-it metadata\n * @see {@link isRenderCapability} for the type-guard\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#capability\n */\nexport type Capability = {\n /** Unique within a session. Convention: namespaced as `<origin>.<name>` (e.g. `platform.react`, `ui.gif`). */\n name: string;\n /**\n * Human-readable label for user-facing surfaces (cmdK action palette,\n * capability menus, debug panels). Falls back to {@link Capability.name}\n * when omitted. Pure presentation — the LLM sees `name`, not `displayName`.\n */\n displayName?: string;\n /** Human/LLM-readable summary. Shown to the LLM as part of tool registration. */\n description: string;\n /** JSON Schema validating the invocation arguments. Authored as Zod, converted at register time. */\n inputSchema: Record<string, unknown>;\n /** Optional return shape. Omit for fire-and-forget effects. */\n outputSchema?: Record<string, unknown>;\n /** Where the handler runs. `client` = host platform, `agent` = runtime/skill/connector, `app` = embedded app. */\n side: \"client\" | \"agent\" | \"app\";\n /** Discriminated tag identifying who registered the capability. Used for trust enforcement and audit. */\n origin: CapabilityOrigin;\n /** Lifetime: `session` survives the whole session, `turn` is dropped at end-of-turn. */\n scope?: \"session\" | \"turn\";\n /** When true, the bridge auto-resolves with `{}` immediately and runs the handler in the background. */\n fireAndForget?: boolean;\n /** When true, the platform shows a confirm UI before dispatch and waits for {@link CapabilityApproveCommand}. */\n requiresApproval?: boolean;\n /** Documentation hint (not enforced) describing whether this is a side-effect, render, or pure query. */\n kind?: \"effect\" | \"render\" | \"query\";\n /**\n * Whether this capability should be exposed in user-facing surfaces (cmdK\n * action palette, capability menus). When omitted, the consumer applies a\n * default per-origin via {@link isUserInvokable}.\n *\n * - `true`: surface in cmdK and capability menus.\n * - `false`: hide from user surfaces (LLM-only or low-level).\n * - `undefined`: defer to {@link isUserInvokable}'s inference rules.\n *\n * @deprecated Set {@link Capability.audience} instead. `userInvokable` is\n * kept as a read-only shim for v2.x consumers and is honoured by\n * {@link isUserInvokable} when {@link Capability.audience} is absent.\n */\n userInvokable?: boolean;\n /**\n * Audience scoping for this capability. See {@link CapabilityAudience} for\n * the meaning of each value and combinations.\n *\n * When omitted, consumers treat the capability as `['llm', 'user']` (the\n * v2.x default). Host RPCs and runner RPCs MUST set this to `['runtime']`\n * so they never leak to the LLM tool list or the user-facing surfaces.\n *\n * @category Capabilities\n * @since 3.0.0\n */\n audience?: CapabilityAudience[];\n /** Appended to the system prompt's `<CAPABILITIES>` section. Use for usage hints the LLM should always see. */\n promptFragment?: string;\n /**\n * Per-capability override for how long the runner waits on the\n * `capability_result` round-trip before timing out. When omitted the\n * runner applies its default (`DEFAULT_CAPABILITY_CALL_TIMEOUT_MS`, 60s).\n *\n * Set this for capabilities that legitimately block far longer than a\n * normal tool call — e.g. `platform.ask_session` suspends the caller's\n * turn until a peer session answers, which can take minutes.\n *\n * @category Capabilities\n * @since 3.3.0\n */\n callTimeoutMs?: number;\n /** Present iff this is a render capability — see {@link RenderCapability}. */\n render?: RenderSpec;\n};\n\n/**\n * A {@link Capability} that produces a UI surface when invoked. The narrowed\n * type guarantees `render` is set, which simplifies frontend lookup.\n *\n * @see {@link isRenderCapability}\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#render-capability\n */\nexport type RenderCapability = Capability & { render: NonNullable<Capability[\"render\"]> };\n\n/**\n * Type-guard for {@link RenderCapability}. Use after {@link Capability}\n * lookup to narrow the type before reading `render`.\n *\n * @example\n * ```ts\n * for (const cap of registry.list()) {\n * if (isRenderCapability(cap)) console.log(cap.render.targets);\n * }\n * ```\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#is-render-capability\n */\nexport function isRenderCapability(cap: Capability): cap is RenderCapability {\n return cap.render !== undefined;\n}\n\n/**\n * Decide whether a capability should be surfaced in user-facing actions\n * (cmdK action palette, capability menus).\n *\n * Resolution order (first match wins):\n *\n * 1. {@link Capability.audience} is set — return `audience.includes('user')`.\n * Capabilities scoped to `'runtime'` only never appear in user surfaces.\n * 2. {@link Capability.userInvokable} is set (v2.x shim) — return that value.\n * 3. Default per-origin inference table below.\n *\n * Default-inference rules (when both `audience` and `userInvokable` are\n * omitted):\n * | Origin | Default |\n * | ------------ | ---------------------------------------------------------------------- |\n * | `framework` | `false` (LLM discovery surfaces, e.g. `__capabilities.list`) |\n * | `client` | `false` (platform ack tools — `platform.react`, `platform.pass`) |\n * | `agent` | `false` (agent-defined; assume internal unless flagged) |\n * | `flow` | `false` (per-cap opt-in) |\n * | `connector` | `false` (low-level FS / data ops) |\n * | `mount` | `false` (low-level FS ops) |\n * | `app` | `false` (LLM-only; app authors opt in via `audience: ['llm','user']`) |\n * | `mcp` | `true` if `kind === 'effect'`, else `false` |\n * | `skill` | `true` if `kind` ∈ {`effect`, `render`}, else `false` |\n *\n * @example\n * ```ts\n * for (const cap of capabilities.values()) {\n * if (isUserInvokable(cap)) registerCommandPaletteAction(cap);\n * }\n * ```\n *\n * @category Capabilities\n * @since 2.1.0\n * @docLink packages/types/capabilities#is-user-invokable\n */\nexport function isUserInvokable(cap: Capability): boolean {\n if (cap.audience !== undefined) {\n return cap.audience.includes(\"user\");\n }\n if (cap.userInvokable !== undefined) {\n return cap.userInvokable;\n }\n switch (cap.origin.kind) {\n case \"framework\":\n case \"client\":\n case \"agent\":\n case \"flow\":\n case \"connector\":\n case \"mount\":\n case \"app\":\n return false;\n case \"mcp\":\n return cap.kind === \"effect\";\n case \"skill\":\n return cap.kind === \"effect\" || cap.kind === \"render\";\n default:\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Capability commands (client → agent)\n// ---------------------------------------------------------------------------\n\n/**\n * Register one or more capabilities mid-session (client → agent).\n *\n * The platform sends this when a new client-side tool becomes available\n * after `configure` has already returned (e.g. a user installs a new\n * extension during the session).\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#capability-register-command\n */\nexport type CapabilityRegisterCommand = {\n type: \"capability_register\";\n capabilities: Capability[];\n};\n\n/**\n * Deregister capabilities by name (client → agent). Names that are not\n * currently registered are ignored silently.\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#capability-deregister-command\n */\nexport type CapabilityDeregisterCommand = {\n type: \"capability_deregister\";\n names: string[];\n};\n\n/**\n * Return the result of a previously {@link CapabilityInvokedEvent | invoked} client-side\n * capability (client → agent). Bridges that registered the capability with\n * `fireAndForget: true` MAY skip this command; the bridge auto-resolves with `{}`.\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#capability-result-command\n */\nexport type CapabilityResultCommand = {\n type: \"capability_result\";\n /** Correlation token matching the {@link CapabilityInvokedEvent.callId}. */\n callId: string;\n /** Successful result payload, or an error envelope. */\n result: unknown | { error: string };\n};\n\n/**\n * Invoke an **agent-side** capability (client → agent). The host names the\n * capability and supplies its input; the runner answers with a matching\n * {@link CapabilityResultEvent}. The mirror of {@link CapabilityInvokedEvent},\n * which reports the LLM invoking a client-side capability in the opposite\n * direction and shares this discriminant.\n *\n * @category Capabilities\n * @since 3.23.0\n * @docLink packages/types/capabilities#capability-invoke-command\n */\nexport type CapabilityInvokeCommand = {\n type: \"capability_invoked\";\n /** Correlation token the answering {@link CapabilityResultEvent} echoes. */\n callId: string;\n /** Name of the {@link Capability} to invoke. */\n name: string;\n /** Input payload, validated against the capability's schema by the registry. */\n input: unknown;\n};\n\n/**\n * Return the result of a platform-invoked **agent-side** capability\n * (agent → client). The mirror of {@link CapabilityResultCommand}, which\n * carries the same shape in the opposite direction for client-side\n * capabilities; `runner.attach_instance` and its `runner.*` siblings answer\n * with this one.\n *\n * Both directions share the `capability_result` discriminant, so the sender\n * decides which type applies — they are never both valid on one hop.\n *\n * @category Capabilities\n * @since 3.23.0\n * @docLink packages/types/capabilities#capability-result-event\n */\nexport type CapabilityResultEvent = {\n type: \"capability_result\";\n /** Correlation token matching the invoking call. */\n callId: string;\n /** Successful result payload, or an error envelope. */\n result: unknown | { error: string };\n};\n\n/**\n * Approve or reject a capability call that was invoked with\n * `requiresApproval: true` (client → agent). The platform shows a confirm\n * UI and forwards the user's decision via this command.\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#capability-approve-command\n */\nexport type CapabilityApproveCommand = {\n type: \"capability_approve\";\n /** Correlation token matching the {@link CapabilityInvokedEvent.callId}. */\n callId: string;\n /** User's decision. */\n decision: \"approved\" | \"rejected\";\n /** Optional rationale stored alongside the decision for audit. */\n feedback?: string;\n /** User ID of the decider (informational — framework enforces no policy). */\n decidedBy: string;\n};\n\n// ---------------------------------------------------------------------------\n// Capability events (agent → client)\n// ---------------------------------------------------------------------------\n\n/**\n * Register one or more capabilities mid-session (agent → client). Mirrors\n * {@link CapabilityRegisterCommand} for the agent-initiated direction; used\n * when the runtime adds a capability after `configure` (e.g. when a flow\n * starts and injects flow-scoped tools).\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#capability-register-event\n */\nexport type CapabilityRegisterEvent = {\n type: \"capability_register\";\n capabilities: Capability[];\n};\n\n/**\n * Deregister capabilities by name (agent → client).\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#capability-deregister-event\n */\nexport type CapabilityDeregisterEvent = {\n type: \"capability_deregister\";\n names: string[];\n};\n\n/**\n * Notify the client that a capability has been invoked by the LLM (agent →\n * client). For client-side capabilities the platform's handler runs in\n * response to this event and replies with {@link CapabilityResultCommand}.\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#capability-invoked-event\n */\nexport type CapabilityInvokedEvent = {\n type: \"capability_invoked\";\n /** Correlation token for the eventual {@link CapabilityResultCommand}. */\n callId: string;\n /** Name of the invoked {@link Capability}. */\n name: string;\n /** Validated input payload (already conforms to the capability's `inputSchema`). */\n input: unknown;\n /** In v2.0.0 the LLM is the only invoker. */\n invokedBy: \"agent\";\n};\n\n/**\n * Notify the client that a render capability should be drawn (agent →\n * client). Emitted alongside {@link CapabilityInvokedEvent} when the\n * invoked capability's `render` block is populated.\n *\n * Clients without a render layer can fall back to the capability's\n * `render.fallback` markdown template.\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/types/capabilities#render-invoked-event\n */\nexport type RenderInvokedEvent = {\n type: \"render_invoked\";\n /** Name of the invoked render capability. */\n capabilityName: string;\n /** Props passed to the rendered component (already conforms to `inputSchema`). */\n props: unknown;\n /** Correlation token shared with the matching {@link CapabilityInvokedEvent}. */\n callId: string;\n};\n","/**\n * Agent-authored tool-call activity labels.\n *\n * Every tool the runtime advertises to the model carries one extra optional\n * string parameter, {@link TOOL_ACTIVITY_LABEL_PARAM}, in which the agent\n * describes the call in plain language (\"Reading the Q3 budget spreadsheet\").\n * The normalizer surfaces it as `ToolCallEvent.label` so the chat can show it\n * instead of the raw tool name and arguments.\n *\n * The parameter is added at the ADVERTISE layer only and stripped before the\n * real handler runs. It never enters a capability's registered `inputSchema`,\n * because that schema is hashed into the resume signature.\n *\n * Zod is passed in rather than imported: the Claude SDK and the bridge each\n * bring their own zod instance, and the schema must be built with the one the\n * SDK validates against.\n *\n * @category Tools\n * @since 3.24.0\n */\n\n/** Name of the optional parameter injected into every advertised tool schema. */\nexport const TOOL_ACTIVITY_LABEL_PARAM = \"activity_label\";\n\n/** Longest label the normalizer passes on; longer text is truncated with an ellipsis. */\nexport const TOOL_ACTIVITY_LABEL_MAX_CHARS = 120;\n\n/** LLM-facing description of {@link TOOL_ACTIVITY_LABEL_PARAM}. */\nexport const TOOL_ACTIVITY_LABEL_DESCRIPTION =\n \"Short plain-language description (under ~12 words, present tense) of what this call does, \" +\n \"shown to the user while it runs, e.g. 'Reading the Q3 budget spreadsheet'. \" +\n \"Never include secrets.\";\n\n/** System-prompt guidance telling the agent to fill the label on every call. */\nexport const TOOL_ACTIVITY_PROMPT_SECTION = [\n \"## Tool-call activity labels\",\n \"\",\n `Whenever a tool offers an \\`${TOOL_ACTIVITY_LABEL_PARAM}\\` parameter, always fill it. For the Bash tool, always fill its \\`description\\` parameter.`,\n \"The text is shown to the user while the call runs, in place of the tool's technical details, so write it for a non-technical reader:\",\n \"under ~12 words, present tense, naming the thing being worked on (e.g. 'Reading the Q3 budget spreadsheet', 'Checking which invoices are overdue').\",\n \"Never put secrets, tokens or raw file contents in it.\",\n].join(\"\\n\");\n\n/**\n * Add {@link TOOL_ACTIVITY_LABEL_PARAM} to a zod raw shape (a record of zod\n * fields, as `createSdkMcpServer` accepts). Returns the shape unchanged when\n * the tool already declares a property of that name.\n */\nexport function withActivityLabelShape(\n shape: Record<string, unknown>,\n z: any,\n): Record<string, unknown> {\n if (Object.hasOwn(shape, TOOL_ACTIVITY_LABEL_PARAM)) return shape;\n return {\n ...shape,\n [TOOL_ACTIVITY_LABEL_PARAM]: z.string().optional().describe(TOOL_ACTIVITY_LABEL_DESCRIPTION),\n };\n}\n\n/**\n * Add {@link TOOL_ACTIVITY_LABEL_PARAM} to a JSON Schema object's top-level\n * `properties`. Returns the schema unchanged when it already declares the\n * property.\n */\nexport function withActivityLabelJsonSchema(\n schema: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const base = schema ?? {};\n if (declaresActivityLabel(base)) return base;\n const props = (base.properties ?? {}) as Record<string, unknown>;\n return {\n ...base,\n properties: {\n ...props,\n [TOOL_ACTIVITY_LABEL_PARAM]: { type: \"string\", description: TOOL_ACTIVITY_LABEL_DESCRIPTION },\n },\n };\n}\n\n/** True when a JSON Schema object itself declares {@link TOOL_ACTIVITY_LABEL_PARAM}. */\nexport function declaresActivityLabel(schema: unknown): boolean {\n if (!schema || typeof schema !== \"object\") return false;\n const props = (schema as Record<string, unknown>).properties;\n return !!props && typeof props === \"object\" && Object.hasOwn(props, TOOL_ACTIVITY_LABEL_PARAM);\n}\n\n/**\n * Remove {@link TOOL_ACTIVITY_LABEL_PARAM} from a tool input before it reaches\n * the handler. Returns a shallow copy; non-object inputs and inputs without\n * the key are returned as-is.\n */\nexport function stripActivityLabel<T>(input: T): T {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return input;\n if (!Object.hasOwn(input, TOOL_ACTIVITY_LABEL_PARAM)) return input;\n const { [TOOL_ACTIVITY_LABEL_PARAM]: _label, ...rest } = input as Record<string, unknown>;\n return rest as T;\n}\n\n/**\n * Wrap in-process SDK tool defs: advertise {@link TOOL_ACTIVITY_LABEL_PARAM}\n * and strip it before each handler runs. A def that already declares the\n * property is returned untouched — the value is then the tool's own argument.\n */\nexport function withActivityLabelDefs<\n T extends { inputSchema: Record<string, unknown>; handler: (args: any) => unknown },\n>(defs: T[], z: any): T[] {\n return defs.map((def) => {\n if (Object.hasOwn(def.inputSchema, TOOL_ACTIVITY_LABEL_PARAM)) return def;\n return {\n ...def,\n inputSchema: withActivityLabelShape(def.inputSchema, z),\n // Forward the SDK's trailing args (`extra`) untouched.\n handler: (args: unknown, ...rest: unknown[]) =>\n (def.handler as (a: unknown, ...r: unknown[]) => unknown)(\n stripActivityLabel(args),\n ...rest,\n ),\n };\n });\n}\n","/**\n * Protocol versioning primitives for Skaile Agent Protocol v2.\n *\n * The protocol is versioned by a structured {@link ProtocolVersion} record\n * (`major.minor.patch`). The compatibility rule applied at handshake is\n * **major-equality**: a runner emits {@link IncompatibleProtocolEvent} and\n * shuts down when its declared major does not match the platform's announced\n * major. Minor and patch differences ride through transparently because\n * unknown fields are preserved on round-trip (see `MessageMeta` round-trip\n * contract in `messaging.ts`).\n *\n * @category Protocol\n * @since 2.0.0\n */\n\n/**\n * Structured semantic version triple for the agent protocol.\n *\n * @example\n * ```ts\n * const v: ProtocolVersion = { major: 2, minor: 0, patch: 0 };\n * ```\n *\n * @category Protocol\n * @since 2.0.0\n * @docLink packages/types/protocol-v2#protocol-version\n */\nexport type ProtocolVersion = {\n /** Incremented on breaking wire-format changes (field removed, semantics changed, required field added). */\n major: number;\n /** Incremented on additive wire-format changes (new optional fields, new event types). */\n minor: number;\n /** Incremented on bug-fix or doc-only changes that do not affect the wire. */\n patch: number;\n};\n\n/**\n * The protocol version the framework currently speaks. Runners and platforms\n * compare this against the peer's announced version at session boot via\n * `SessionInitCommand.protocolVersion`.\n *\n * @example\n * ```ts\n * import { PROTOCOL_VERSION } from '@skaile/workspaces/types';\n * if (cmd.protocolVersion.major !== PROTOCOL_VERSION.major) {\n * emit({ type: 'incompatible_protocol', agentVersion: PROTOCOL_VERSION, platformVersion: cmd.protocolVersion });\n * }\n * ```\n *\n * @category Protocol\n * @since 3.0.0\n *\n * Changed in 4.14.0:\n * `prompt` and `cancel` take an optional `senderId`, the user id of\n * `MessageMeta.senderId`. A `cancel` with a `senderId` aborts the running turn\n * as before and also drops that sender's prompts still waiting in the runner's\n * prompt queue; the runner reports them in the new `queued_prompts_dropped`\n * event. Other senders' queued prompts stay queued, and a prompt without a\n * `senderId` is never dropped. A `cancel` without one keeps 4.13 behaviour. A\n * 4.13 runner ignores both fields and runs every queued prompt after a\n * cancel, so a host must feature-detect on `major === 4 && minor >= 14` before\n * it marks prompts as not sent from anything but the event itself.\n *\n * Changed in 4.13.0:\n * `runner.lifecycle` with `phase: \"compact\"` takes an optional `trigger`\n * (`\"manual\"` | `\"hibernate\"`, default `\"manual\"`). `\"hibernate\"` compacts\n * without resetting the driver and without the snapshot turn (\"Continue from\n * where we left off\") that a manual compaction runs, so a pre-hibernate\n * compaction never starts agent work. The input is a strict object, so a 4.12\n * runner refuses the field: a host must feature-detect on\n * `major === 4 && minor >= 13` before sending it.\n *\n * Changed in 4.12.0:\n * A filesystem-mount `read` takes optional `ReadOptions.offset` / `length` for\n * a ranged read: the runner reads only that range (at most 8 MiB, a larger\n * `length` is clamped), answers it base64, and sets `ConnectorContent.range`\n * (`offset`, `length`, total `size`, optional `modifiedAt`). A bad offset or length fails with\n * `code: \"invalid_range\"`. A 4.11 runner ignores both fields and sends the\n * whole file in one frame, so a host must feature-detect on\n * `major === 4 && minor >= 12` before asking for a range, and must treat an\n * answer without `range` as the whole file.\n *\n * Changed in 4.11.0:\n * `provider_response_seen` gains optional `cause`. `long-context-entitlement`\n * marks a 429 that says the account may not use a long (1M) context window,\n * so the seat is not out of quota. Diagnostic only: the runner fails over and\n * reports the 429 exactly as before. A 4.10 runner never sets it; a host must\n * ignore values it does not know.\n *\n * Changed in 4.10.0:\n * `error` gains optional `retrying` and `retryReason` (`stale_resume` |\n * `poison_scrub`). `retrying: true` (always with `fatal: false`) means the\n * driver replays the same prompt in place, with no `status: idle` in between,\n * so the error does not end the turn and the replay keeps the turn's starter.\n * A 4.9 runner sends such an error unmarked; a host that reads every `error`\n * as a turn end must keep doing so for it.\n *\n * Changed in 4.9.0:\n * New runtime capability `runner.reconfigure` (`{ model?, thinking?, effort? }`,\n * at least one) changes the running agent's model, thinking mode or effort\n * from the next turn, without a restart. It answers `{ ok: true, model }`, or\n * `{ ok: false, code }` with `no_driver` / `not_supported` when the change\n * cannot apply live. A 4.8 runner has no such capability, so a host keeps its\n * apply-on-restart path for it.\n *\n * Changed in 4.8.0:\n * The runner emits `question_reply` to every attached client when a paused\n * turn accepts a `reply`, and the event gains optional `question` and\n * `requestId` echoed from that reply. A 4.7 runner never emits it, so a host\n * must keep clearing a question card on its own `reply` and on `finished`.\n *\n * Changed in 4.7.0:\n * New `get_context_usage` command and `context_usage` event: a provider-neutral\n * breakdown of the context window, emitted after every turn and on request. A\n * 4.6 runner ignores the command and never emits the event, so a host must\n * treat a missing answer as \"unsupported\", not wait on it.\n *\n * Changed in 4.6.0:\n * A filesystem-mount `read` takes optional `ReadOptions`; `encoding: \"binary\"`\n * answers base64 for every file instead of decoding a NUL-free head as text.\n * A 4.5 runner ignores the option, so a host must still refuse a `utf-8`\n * answer carrying U+FFFD rather than re-encode it.\n *\n * Changed in 4.5.0:\n * `tool_call` and `tool_result` gain optional `parentToolUseId`, set when a\n * subagent made the call. Such a call runs alongside the main reply, so a host\n * that treats a tool call as a break in the reply's text should skip tagged\n * ones. A 4.4 runner never sets it and cannot be told apart from a turn with no\n * subagent; feature-detect on `major === 4 && minor >= 5`.\n *\n * Changed in 4.4.0:\n * `SystemPromptSection.label` gains `\"home\"`, the `agent.home` block that the\n * runner builds from workspace files. A host that switches exhaustively over the\n * label gains one member; a 4.3 runner never emits it.\n *\n * Changed in 4.3.0:\n * Additive `text_retract` event: the runner takes back the unfinished text of\n * an attempt it is about to replay, as the exact suffix of the `text` it\n * already streamed. A host that buffers or persists streamed text must cut\n * that suffix rather than treat the event as an unknown non-text event (which\n * would commit the fragment). A 4.2 runner never sends it.\n *\n * Changed in 4.2.0:\n * Two additive `resource_request` operations for filesystem mounts: `mkdir`\n * (create one empty directory, parents included; something already at the path\n * fails with `code: \"already_exists\"`) and `stat` (type, size, modified and\n * created time, and with `options.recursive` capped recursive `totals` that\n * report `partial` instead of failing). `resource_response` gains an optional\n * `code` (`ConnectorResponseFailureCode`). A 4.1 runner answers either op with\n * an `error` starting `Unsupported operation` and no `code`; a host must\n * feature-detect on `major === 4 && minor >= 2` or accept that error form.\n *\n * Changed in 4.1.0:\n * Additive `provider_quota_observed` event: one upstream quota-window reading\n * (window, status, optional utilization and reset) per change, attributed to\n * the pinned `AIProviderConfig`. A host with no handler broadcasts it\n * harmlessly. A 4.1 host against a 4.0 runner sees none and must not read\n * that as \"no quota used\" (feature-detect on `major === 4 && minor >= 1`).\n *\n * Changed in 4.0.0 (breaking):\n * The AI provider registry is the only provider surface on the wire.\n * `ResolvedAgentConfig` **loses** `provider`, `cloud` and `cloudConfig`; what\n * remains is `registry?` (the merged AI provider registry — `id → entry`, or\n * the merged view with registry order and merge provenance) and `modelRef?`\n * (`\"<providerId>/<modelId>\"`, a bare model id, or `\"@role\"`). Registry\n * entries never carry a literal secret: a control-plane-injected credential\n * is named by a `credential.ref` of the form `platform:<configId>` and\n * resolved against the sibling `secrets` map, which the platform keys by the\n * bare config id. A `session_init` whose `resolvedConfig.agentConfig` still\n * carries one of the removed fields is **rejected** with a fatal `error`\n * naming the replacement — silently ignoring them would run the session\n * against a different endpoint than the control plane resolved. Peers\n * negotiate on `major`, so a 3.x platform and a 4.x runner refuse each other\n * at boot rather than degrading.\n *\n * Changed in 3.15.0:\n * Classifier nodes. A new runtime-audience capability, `host.classify`\n * (`HostClassifyInput` → `HostClassifyResult`), which the runner invokes for a\n * classifier-shaped subprompt node, and an optional `classification` on\n * `NodeOutput`. A host without `host.classify` makes every classifier node run on\n * the generative fallback; older peers ignore the new output field.\n *\n * Changed in 3.14.0:\n * Optional `sessionRoot` flag on `resources_available`, advertising the\n * reserved `SESSION_ROOT_CONNECTOR_ID` write target for session-owned files.\n * Older peers ignore the flag and never send the reserved id.\n *\n * Changed in 3.13.0:\n * Optional agent-authored `label` on the `tool_call` event, and a new\n * `\"tool-activity\"` member of `SystemPromptSection.label`. Older peers ignore\n * both; a host that renders `label` can feature-detect it by this minor.\n *\n * Changed in 3.12.0:\n * Optional structured prompt attachments and question/reply requestId correlation.\n * Older peers retain text prompts and ignore unknown optional fields. Managed\n * question hosts must echo requestId; this minor does not advertise or admit the\n * separately gated codex-app-server-v1 runtime.\n *\n * Changed in 3.10.0:\n * Additive rejection cause on the AI-credential refresh input. The\n * `host.refresh_credential` `ai-credentials` input gains an optional\n * `rejection?: CredentialRejection` (`'auth' | 'usage-limit'`), sent only\n * alongside `reason: 'retry-401'` and only from the two runner call sites that\n * genuinely classified the failure — the driver's auth self-heal (`'auth'`) and\n * its usage-limit failover (`'usage-limit'`). `reason: 'retry-401'` collapsed\n * both, so a limit-blocked session on a config that is not opted into\n * `autoActivate` never re-resolved; the field is what lets the platform tell\n * them apart. `auth` asserts only that the rejection was auth-shaped, never\n * that capacity is fine (Anthropic mislabels OAuth quota exhaustion as\n * `authentication_error`); only `usage-limit` is a positive assertion. The\n * connector and MCP refresh paths classify nothing and keep emitting exactly\n * today's bytes. There is no peer-version gate, so a 3.9 peer does receive the\n * key on those two inputs; it is unaffected because nothing was removed or\n * reshaped and it must ignore an unknown key — and an unrecognised value —\n * rather than reject the input, which is also what allows a third rejection\n * later without a major bump. A 3.10 host against a 3.9 runner never sees the\n * field and must not read its absence as \"not a limit\" (feature-detect on\n * `major === 3 && minor >= 10`).\n * Spec: skaile-ai/platform#3562.\n *\n * Changed in 3.9.0:\n * Additive live AI-provider-seat signals, all optional under the\n * major-equality rule:\n * - `AgentEvent` gains `provider_response_seen`, emitted when the runner\n * observes a 401 or a 429 / subscription-limit rejection from the AI\n * provider, attributed to the pinned `AIProviderConfig`. A platform with\n * no handler broadcasts it harmlessly; consumers must ignore unknown\n * fields, since the platform half ships independently.\n * - The `CredentialMint` success branch gains an optional `configId` — the\n * seat the platform actually minted for. When it differs from the one the\n * runner asked for, the runner repoints the live session at it. A platform\n * that omits the field produces exactly 3.8 behaviour (no switch is ever\n * detected).\n * - The `credentialRotated` broadcast may carry `entry.data.configId` to\n * move a running session to a different seat rather than merely rotating\n * the token on the current one. Absent → today's re-pull.\n * A 3.8 peer is unaffected: nothing was removed or re-shaped, every addition is\n * opt-in on a field a 3.8 peer never sets. A 3.9 host against a 3.8 runner sees\n * no `provider_response_seen` and must not read that as \"no limits were hit\"\n * (feature-detect on `major === 3 && minor >= 9`).\n *\n * Changed in 3.8.0:\n * Additive `prompt` receipt acknowledgement. The `prompt` command gains an\n * optional `messageId`; when set the runner emits exactly one new `prompt_ack`\n * event echoing it, as the first act of handling the frame — before the\n * session-readiness gate, the secrets check and the driver start, each of which\n * could previously drop a prompt with no trace at all. When absent nothing is\n * emitted, so a 3.7 host sees byte-identical behaviour. A 3.8 host against a\n * 3.7 runner gets no ack and must not read that as a lost prompt — feature-detect\n * on `major === 3 && minor >= 8`. The ack is receipt-only: it says the frame\n * arrived, never that the turn ran.\n *\n * Changed in 3.7.0:\n * Additive `connector_mutate` acknowledgement + flow-hydrate reconciliation.\n * Three changes, all additive under the major-equality rule:\n * - `ConnectorMutateCommand` gains an optional `requestId`. When set, the\n * runner emits exactly one new `connector_mutate_response` event (with\n * `ok` / `result` / `error` / `code` / `reconciled`) on every terminal path,\n * including the paths that previously only logged. When absent nothing is\n * emitted, so a 3.6 host sees byte-identical behaviour.\n * - `flow.hydrate` accepts an optional `payload.pendingDecisions` —\n * `PendingGateDecision[]` the runner replays against the snapshot in the\n * same invocation that creates the flow connector, reporting the outcome as\n * `reconciled`. A host that omits the key gets today's hydrate.\n * - A flow-targeted mutate whose connector is not yet registered now waits\n * (bounded, `SKAILE_FLOW_MUTATE_CONNECTOR_WAIT_MS`, default 8000 ms) and\n * re-plans instead of failing — a behaviour change on a path that used to\n * fail silently, visible to a 3.6 host only as the op succeeding.\n * A 3.6 peer is unaffected: no symbol was removed or re-shaped, the ack is\n * opt-in on a field a 3.6 host never sets, and unknown fields ride through the\n * round-trip. A 3.7 host against a 3.6 runner sees `requestId` ignored and no\n * response, which it must treat as \"unacknowledged\" (feature-detect on\n * `major === 3 && minor >= 7`). Spec: `runner/MIGRATION-flow-connector.md`.\n *\n * Changed in 3.6.0:\n * Additive resolved-agent-config wire field. `ResolvedSkaileConfig` gains an\n * optional `agentConfig?: ResolvedAgentConfig` carrying the platform-resolved\n * driver / model / registry / modelRef / thinking / effort — the\n * same values the platform bakes into the generated skaile.yaml\n * `agent-config.default`. The runner applies it disk-first: any on-disk\n * `agent-config` profile with at least one agent setting disables the wire\n * value outright, so yaml-on-disk (docker-mode) sessions are byte-identical.\n * Additive under the major-equality rule: an older runner ignores the field\n * and an older platform simply omits it.\n *\n * Changed in 3.5.0:\n * Flow-connector host-contract fix (workspaces#379). Three coordinated changes,\n * all additive under the major-equality rule:\n * - `op:\"hydrate\"` on the bare `\"flow\"` connector now auto-creates the\n * `flow:<runId>` connector on a cold container from its `{ state, flow }`\n * payload, so a persisted run rehydrates in one op. A peer that still issues\n * `start` then `hydrate` keeps working unchanged.\n * - The dead `SessionInit.activeFlows` field (never read by the runner) and its\n * `ActiveFlowRehydration` type are removed — wire-compatible (nothing produced\n * or consumed them) but source-breaking for typed hosts, hence the bump.\n * - Malformed / conflicting flow `start` and `hydrate` payloads now fail loudly\n * (warn with a reason) instead of silently falling through.\n * Because the handshake compares only `major`, a 3.4 host and a 3.5 runner\n * interoperate: the auto-create path is opt-in on the payload the host sends, and\n * the removed field was already inert. Spec: `runner/MIGRATION-flow-connector.md`.\n *\n * Changed in 3.4.0:\n * Additive embedded-app capability source. `CapabilityOrigin` gains a\n * `{ kind: 'app'; appId: string }` variant and `Capability.side` gains `'app'`\n * (\"the handler runs in the embedded app\"). Both are additive: a peer that does\n * not understand `origin:'app'` / `side:'app'` never produces or routes them, so\n * they ride through transparently under the major-equality rule. No new message\n * types — `capability_register` / `capability_invoked` / `capability_result` /\n * `capability_approve` / `render_invoked` are reused verbatim. Spec:\n * `_devlog/specs/2026-07-07-app-capability-source.md`.\n *\n * Changed in 3.3.0:\n * Additive agent-to-agent (session-to-session) communication extension.\n * `AgentEvent` gains an `a2a_message` variant carrying cross-session messages\n * (`direction`, `peerSessionId`, `peerName`, `exchangeId`, `text`). `Capability`\n * gains an optional `callTimeoutMs?: number` so a long-running capability call\n * (e.g. a 5-minute `platform.ask_session`) can exceed the default capability-call\n * timeout. Both are additive: a peer that does not understand them ignores the\n * event / falls back to the default timeout, so they ride through transparently\n * under the major-equality rule.\n *\n * Changed in 3.2.0:\n * Additive wake-time resume cascade. `AgentReconfigureOptions` gains optional\n * `resumeSessionId` and `expectedCapabilitySignature` fields driving the tier-1\n * native SDK resume path; `AgentEvent` gains `ResumeAttemptedEvent` and\n * `ResumeFailedEvent`. `FinishedEvent` gains optional `customType` /\n * `customData` for capability-routed custom payloads. All additive — clients\n * that omit the resume hint or ignore the new events keep working unchanged.\n *\n * Changed in 3.1.0:\n * Additive cost / token usage extension. `FinishedEvent` gains an optional\n * `tokens?: TokenUsage` field carrying per-turn input / output / cache-read /\n * cache-creation / reasoning token counts. `AgentDriver.getTokenUsage()` is\n * widened to return the same `TokenUsage` shape (existing consumers reading\n * `inputTokens` / `outputTokens` keep working unchanged). Drivers that do not\n * surface token usage continue to return `null` / omit the field.\n *\n * Changed in 3.0.0:\n * Major bump for the deterministic session bootstrap rewrite. `ConfigureCommandV2`,\n * `provision_secrets`, `request_access_token`, `add_resource`, `remove_resource`,\n * `set_log_level`, `state_action`, `lifecycle`, `remount_mount`, `compact`, and\n * `reconfigure_agent` are removed from the `AgentCommand` union. Their semantics\n * are reachable through:\n * - `session_init` (one deterministic envelope at session start that delivers\n * identity, resolved config, pre-minted credentials, secrets, capabilities,\n * shared state, active flows, resume hints, and logging config),\n * - `host.refresh_credential` (capability invocation that replaces the\n * refresh-on-401 path of `request_access_token`), and\n * - `runner.*` capabilities (`runner.add_mount`, `runner.add_connector`,\n * `runner.remove_resource`, `runner.update_credential`, `runner.set_log_level`,\n * `runner.set_state`, `runner.lifecycle`, and since 4.9.0 `runner.reconfigure`)\n * invoked by the platform via the\n * bidirectional capability registry.\n *\n * Capabilities gain an `audience: ('llm' | 'user' | 'runtime')[]` field that\n * scopes visibility: host RPCs (`host.*`) and runner RPCs (`runner.*`) are\n * `['runtime']` and never reach the LLM tool list or the user-facing command\n * palette. v2.x capabilities without an explicit `audience` default to\n * `['llm', 'user']`, preserving prior behaviour.\n *\n * Spec: `_devlog/specs/2026-05-10-deterministic-session-bootstrap.md`.\n *\n * @docLink packages/types/protocol-v3#protocol-version\n */\nexport const PROTOCOL_VERSION: ProtocolVersion = { major: 4, minor: 14, patch: 0 };\n\n/**\n * String form of {@link PROTOCOL_VERSION}, kept in lock-step. Useful for\n * `package.json` version fields and HTTP `User-Agent` strings.\n *\n * @category Protocol\n * @since 3.0.0\n * @docLink packages/types/protocol-v3#protocol-version\n */\nexport const PROTOCOL_VERSION_STRING = \"4.14.0\";\n\n/**\n * Parse a `\"major.minor.patch\"` string into a {@link ProtocolVersion}.\n *\n * @param s - the version string to parse, exactly three dot-separated non-negative integers\n * @returns the parsed protocol version\n * @throws {Error} if the string is not exactly three dot-separated non-negative integers\n *\n * @example\n * ```ts\n * parseVersion('2.0.0'); // { major: 2, minor: 0, patch: 0 }\n * parseVersion('2.1'); // throws\n * ```\n *\n * @category Protocol\n * @since 2.0.0\n * @docLink packages/types/protocol-v2#parse-version\n */\nexport function parseVersion(s: string): ProtocolVersion {\n const parts = s.split(\".\");\n if (parts.length !== 3) {\n throw new Error(`Invalid ProtocolVersion: \"${s}\" (expected \"major.minor.patch\")`);\n }\n const [maj, min, pat] = parts;\n const major = Number(maj);\n const minor = Number(min);\n const patch = Number(pat);\n if (\n !Number.isInteger(major) ||\n !Number.isInteger(minor) ||\n !Number.isInteger(patch) ||\n major < 0 ||\n minor < 0 ||\n patch < 0\n ) {\n throw new Error(`Invalid ProtocolVersion: \"${s}\" (each part must be a non-negative integer)`);\n }\n return { major, minor, patch };\n}\n\n/**\n * Format a {@link ProtocolVersion} record into its `\"major.minor.patch\"` string form.\n *\n * @param v - the protocol version to format\n * @returns the dot-joined string form\n *\n * @example\n * ```ts\n * formatVersion({ major: 2, minor: 0, patch: 0 }); // '2.0.0'\n * ```\n *\n * @category Protocol\n * @since 2.0.0\n * @docLink packages/types/protocol-v2#format-version\n */\nexport function formatVersion(v: ProtocolVersion): string {\n return `${v.major}.${v.minor}.${v.patch}`;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../asset-manager/src/install-agent.ts","../asset-manager/src/installer.ts"],"names":["parseYaml","basename","join","resolve","existsSync"],"mappings":"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","file":"chunk-VCLN2IUM.js","sourcesContent":["/**\n * Agent installation — renders a GitAgent package (agent.yaml + SOUL.md + RULES.md)\n * into the framework-native format (`.claude/agents/<name>.md`, `.omp/agents/<name>/`,\n * `.codex/agents/<name>.toml`) and resolves abilities, contracts, fragments, and\n * prompt extensions from the workspace config along the way.\n *\n * System prompt phases (per agent):\n * 1. extends merge — inherit from parent agent.yaml if manifest.extends is set\n * 2. ability refs — read SKILL.md frontmatter from installed skills dir\n * 3. contract refs — locate CONTRACT.md files in the installed skills dir\n * 4. fragments — resolve framework fragments (agent-mode, handoff, etc.)\n * 5. prompt-extensions — load per-project markdown extensions from skaile.yaml\n *\n * Used by `installer.ts` (the asset-install path) and `skaile install`. Sub-agents\n * declared in `agent.yaml#requires` are installed flat (no nesting) in the same\n * deploy directory.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { basename, isAbsolute, join, relative, resolve } from \"node:path\";\nimport type { DriverTarget, SkWorkspaceConfig } from \"@skaile/workspaces/core\";\nimport { DRIVER_TARGETS } from \"@skaile/workspaces/core\";\nimport { parse as parseYaml } from \"yaml\";\nimport {\n type AbilityRef,\n type ConnectorRef,\n type ContractRef,\n type FragmentContext,\n loadPromptExtensions,\n resolveFragments,\n} from \"./fragments.js\";\nimport { type AgentManifest, type AgentRenderInput, renderAgentToFramework } from \"./renderers.js\";\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction readManifest(agentDir: string): AgentManifest | null {\n const yamlPath = join(agentDir, \"agent.yaml\");\n if (!existsSync(yamlPath)) return null;\n try {\n return parseYaml(readFileSync(yamlPath, \"utf-8\")) as AgentManifest;\n } catch {\n return null;\n }\n}\n\nfunction readFile(agentDir: string, name: string): string | null {\n const p = join(agentDir, name);\n if (!existsSync(p)) return null;\n try {\n return readFileSync(p, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/** Extract YAML frontmatter from a markdown file (content between first two --- delimiters). */\nfunction parseFrontmatter(content: string): Record<string, unknown> {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return {};\n try {\n return (parseYaml(match[1]!) as Record<string, unknown>) ?? {};\n } catch {\n return {};\n }\n}\n\n/**\n * Merge parent and child agent manifests.\n * Scalars: child wins. Arrays: parent + child, deduplicated.\n */\nfunction mergeManifests(parent: AgentManifest, child: AgentManifest): AgentManifest {\n const result: AgentManifest = { ...parent };\n for (const [k, val] of Object.entries(child) as [keyof AgentManifest, unknown][]) {\n if (val === undefined) continue;\n const parentVal = result[k as keyof AgentManifest];\n if (Array.isArray(val) && Array.isArray(parentVal)) {\n (result as Record<string, unknown>)[k] = [...new Set([...parentVal, ...val])];\n } else {\n (result as Record<string, unknown>)[k] = val;\n }\n }\n return result;\n}\n\n/**\n * Phase 1: inherit scalars/arrays from a parent agent when `manifest.extends` is set.\n * Returns the (possibly merged) manifest; pushes a warning when the parent is missing.\n */\nfunction applyExtendsMerge(\n manifest: AgentManifest,\n srcDir: string,\n warnings: string[],\n): AgentManifest {\n if (!manifest.extends) return manifest;\n const parentDir = resolve(srcDir, manifest.extends);\n const parentManifest = readManifest(parentDir);\n if (parentManifest) {\n return mergeManifests(parentManifest, manifest);\n }\n warnings.push(\n `extends: parent agent not found at \"${manifest.extends}\" (from ${srcDir}) — skipping inheritance`,\n );\n return manifest;\n}\n\n/** Phase 2: resolve ability refs — read description from installed SKILL.md files. */\nfunction resolveAbilityRefs(\n manifest: AgentManifest,\n workspaceRoot: string,\n skillsRelDir: string,\n): AbilityRef[] {\n const abilityRefs: AbilityRef[] = [];\n for (const name of manifest.abilities ?? []) {\n const skillMdPath = join(workspaceRoot, skillsRelDir, name, \"SKILL.md\");\n if (!existsSync(skillMdPath)) continue;\n try {\n const fm = parseFrontmatter(readFileSync(skillMdPath, \"utf-8\"));\n const desc = typeof fm.description === \"string\" ? fm.description : undefined;\n if (desc) abilityRefs.push({ name, description: desc });\n } catch {\n // skip unreadable SKILL.md\n }\n }\n return abilityRefs;\n}\n\n/** Phase 3: resolve contract refs — locate CONTRACT.md files in the skills dir. */\nfunction resolveContractRefs(\n manifest: AgentManifest,\n workspaceRoot: string,\n skillsRelDir: string,\n): ContractRef[] {\n const contractRefs: ContractRef[] = [];\n for (const name of manifest.contracts ?? []) {\n const contractAbsPath = join(workspaceRoot, skillsRelDir, name, \"CONTRACT.md\");\n if (!existsSync(contractAbsPath)) continue;\n contractRefs.push({ name, relativePath: relative(workspaceRoot, contractAbsPath) });\n }\n return contractRefs;\n}\n\n/** Phase 4: assemble the fragment context from the manifest, workspace config, and resolved refs. */\nfunction buildFragmentContext(\n manifest: AgentManifest,\n driverTarget: string,\n skillsRelDir: string,\n wsConfig: SkWorkspaceConfig | undefined,\n abilityRefs: AbilityRef[],\n contractRefs: ContractRef[],\n): FragmentContext {\n const subAgentNames = (manifest.requires ?? []).filter((r) => r.name).map((r) => r.name);\n\n const connectors: ConnectorRef[] = (wsConfig?.connectors ?? []).map((c) => ({\n id: c.id,\n driver: c.driver,\n access: c.access ?? \"read-write\",\n }));\n\n const agentsRelDir = DRIVER_TARGETS[driverTarget as DriverTarget]?.local.agent ?? \"\";\n\n return {\n framework: driverTarget,\n skillsDir: skillsRelDir,\n agentsDir: agentsRelDir,\n subAgents: subAgentNames,\n connectors,\n abilityRefs,\n contractRefs,\n };\n}\n\n// ── Core installation ─────────────────────────────────────────────────────────\n\n/**\n * Install a single GitAgent source directory using the appropriate renderer.\n *\n * When `includeSubAgents` is `true`, recursively installs `requires[]` entries as\n * separate flat agents in the same deploy directory (no nesting). Tracks visited\n * directories to prevent infinite loops in `requires[]` cycles.\n *\n * @param srcDir - Absolute path to the GitAgent source directory (contains `agent.yaml`).\n * @param agentDeployDir - Absolute path to the framework's agent deploy directory.\n * @param workspaceRoot - Absolute path to the workspace root.\n * @param driverTarget - Agent framework ID used to select the renderer.\n * @param skillsRelDir - Relative path to the installed skills dir (e.g. `\".claude/skills\"`).\n * @param nameOverride - Override name for the installed agent. Defaults to `manifest.name`.\n * @param includeSubAgents - When `true`, recursively install `requires[]` sub-agents.\n * @param visited - Set of resolved source paths already processed (cycle guard).\n * @param wsConfig - Workspace config from `skaile.yaml` (fragments, connectors, extensions).\n * @param log - Optional logger callback for progress messages.\n * @returns Object with `created` file paths and `warnings` list.\n * @docLink packages/asset-manager/concepts#install-agent\n */\nexport function installAgent(\n srcDir: string,\n agentDeployDir: string,\n workspaceRoot: string,\n driverTarget: string,\n /** Relative path to the installed skills dir (e.g. \".claude/skills\") */\n skillsRelDir: string,\n nameOverride: string | undefined,\n includeSubAgents: boolean,\n visited: Set<string>,\n wsConfig: SkWorkspaceConfig | undefined,\n log?: (msg: string) => void,\n): { created: string[]; warnings: string[] } {\n const created: string[] = [];\n const warnings: string[] = [];\n\n const realSrc = resolve(srcDir);\n if (visited.has(realSrc)) return { created, warnings };\n visited.add(realSrc);\n\n const initialManifest = readManifest(srcDir);\n if (!initialManifest) {\n warnings.push(`${srcDir} has no agent.yaml — skipping (not a valid GitAgent package)`);\n return { created, warnings };\n }\n\n // Phase 1: extends merge — inherit scalars/arrays from parent agent\n const manifest = applyExtendsMerge(initialManifest, srcDir, warnings);\n\n const agentName = nameOverride ?? manifest.name ?? basename(srcDir);\n\n log?.(`Installing git-agent: ${agentName} (${driverTarget})`);\n\n // Phase 2: resolve ability refs — read description from installed SKILL.md files\n const abilityRefs = resolveAbilityRefs(manifest, workspaceRoot, skillsRelDir);\n\n // Phase 3: resolve contract refs — locate CONTRACT.md files in the skills dir\n const contractRefs = resolveContractRefs(manifest, workspaceRoot, skillsRelDir);\n\n // Phase 4: build fragment context and resolve framework fragments + prompt extensions\n const fragmentCtx = buildFragmentContext(\n manifest,\n driverTarget,\n skillsRelDir,\n wsConfig,\n abilityRefs,\n contractRefs,\n );\n\n const frameworkFragments = resolveFragments(\n fragmentCtx,\n wsConfig?.agent?.fragments,\n workspaceRoot,\n );\n const promptExtensions = loadPromptExtensions(\n wsConfig?.agent?.[\"prompt-extensions\"],\n workspaceRoot,\n );\n\n const input: AgentRenderInput = {\n manifest,\n soul: readFile(srcDir, \"SOUL.md\"),\n rules: readFile(srcDir, \"RULES.md\"),\n duties: readFile(srcDir, \"DUTIES.md\"),\n agentName,\n agentDeployDir,\n workspaceRoot,\n abilityRefs,\n contractRefs,\n frameworkFragments,\n promptExtensions,\n };\n\n const result = renderAgentToFramework(input, driverTarget, log);\n created.push(...result.created);\n warnings.push(...result.warnings);\n\n // Recursively install sub-agents from requires[] as flat top-level agents\n if (includeSubAgents) {\n installSubAgents(manifest, agentName, srcDir, agentDeployDir, workspaceRoot, driverTarget, {\n skillsRelDir,\n includeSubAgents,\n visited,\n wsConfig,\n log,\n created,\n warnings,\n });\n }\n\n return { created, warnings };\n}\n\n/**\n * Recursively install `requires[]` entries as separate flat agents in the same deploy\n * directory. Appends rendered file paths and warnings into the shared `created`/`warnings`\n * arrays carried on `ctx`.\n */\nfunction installSubAgents(\n manifest: AgentManifest,\n agentName: string,\n srcDir: string,\n agentDeployDir: string,\n workspaceRoot: string,\n driverTarget: string,\n ctx: {\n skillsRelDir: string;\n includeSubAgents: boolean;\n visited: Set<string>;\n wsConfig: SkWorkspaceConfig | undefined;\n log?: (msg: string) => void;\n created: string[];\n warnings: string[];\n },\n): void {\n for (const req of manifest.requires ?? []) {\n if (!req.source || !req.name) continue;\n\n const subSrc = isAbsolute(req.source) ? req.source : resolve(srcDir, req.source);\n\n if (!existsSync(subSrc)) {\n ctx.warnings.push(`Sub-agent source not found: ${req.source} (from ${agentName})`);\n continue;\n }\n\n const sub = installAgent(\n subSrc,\n agentDeployDir,\n workspaceRoot,\n driverTarget,\n ctx.skillsRelDir,\n undefined, // use sub-agent's own name from its agent.yaml\n ctx.includeSubAgents,\n ctx.visited,\n ctx.wsConfig,\n ctx.log,\n );\n ctx.created.push(...sub.created);\n ctx.warnings.push(...sub.warnings);\n }\n}\n","/**\n * Asset deployment — copies assets into framework dirs by default (self-contained,\n * cache-safe, portable); `--link` opts into a symlink for the local-path dev loop.\n */\n\nimport {\n cpSync,\n existsSync,\n lstatSync,\n mkdirSync,\n rmSync,\n statSync,\n symlinkSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport type {\n AiComponent,\n CatalogEntry,\n DriverTarget,\n SourceDeclaration,\n} from \"@skaile/workspaces/core\";\nimport {\n applyPatch,\n computeHash,\n DRIVER_TARGETS,\n deployedBase,\n deployedDir,\n isDeployed,\n resolveSkWorkspaceConfig,\n} from \"@skaile/workspaces/core\";\nimport { installAgent } from \"./install-agent.js\";\nimport type { Log } from \"./renderers.js\";\n\nexport type { Log } from \"./renderers.js\";\n\nconst noop: Log = () => {};\n\n// ── Filesystem helpers ────────────────────────────────────────────────────────\n\nconst DIRECTORY_MANIFESTS = new Set([\"SKILL.md\", \"AGENT.md\", \"agent.yaml\", \"CONTRACT.md\"]);\n\nfunction clearDest(dest: string): void {\n try {\n const s = lstatSync(dest);\n if (s.isSymbolicLink()) unlinkSync(dest);\n else rmSync(dest, { recursive: true, force: true });\n } catch {}\n}\n\nfunction copyFromManifest(manifestPath: string, dest: string): void {\n const name = basename(manifestPath);\n const parentDir = dirname(manifestPath);\n clearDest(dest);\n\n // Source resolved to a directory itself (not a manifest file) — copy it whole;\n // a plain cpSync without `recursive` throws on a directory.\n if (statSync(manifestPath).isDirectory()) {\n cpSync(manifestPath, dest, { recursive: true });\n } else if (DIRECTORY_MANIFESTS.has(name) || basename(parentDir) === basename(dest)) {\n cpSync(parentDir, dest, { recursive: true });\n } else {\n mkdirSync(dest, { recursive: true });\n cpSync(manifestPath, join(dest, name));\n }\n}\n\nfunction symlinkFromManifest(manifestPath: string, dest: string): void {\n const name = basename(manifestPath);\n const parentDir = dirname(manifestPath);\n clearDest(dest);\n mkdirSync(dirname(dest), { recursive: true });\n\n if (statSync(manifestPath).isDirectory()) {\n symlinkSync(resolve(manifestPath), dest);\n } else if (DIRECTORY_MANIFESTS.has(name) || basename(parentDir) === basename(dest)) {\n symlinkSync(resolve(parentDir), dest);\n } else {\n mkdirSync(dest, { recursive: true });\n symlinkSync(resolve(manifestPath), join(dest, name));\n }\n}\n\n// ── Deploy options ───────────────────────────────────────────────────────────\n\n/**\n * Options controlling where and how assets are deployed.\n *\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport interface DeployOptions {\n /** Agent framework to target (determines framework-specific directory layout). Defaults to `\"claude-code\"`. */\n driverTarget?: DriverTarget;\n /** When `true`, deploy into the global Skaile cache rather than a project workspace. */\n global?: boolean;\n /** Absolute path to the workspace root. Defaults to `process.cwd()`. */\n cwd?: string;\n /**\n * Opt into a symlink (the author dev-loop) instead of a copy — honoured only\n * when the source has a real local path. Machine-local / not for committing;\n * for store/factory sources (no stable local path) it is a no-op (still copy).\n */\n link?: boolean;\n}\n\n// ── Deploy / remove ──────────────────────────────────────────────────────────\n\n/**\n * Deploy a single asset to the framework-specific directory.\n *\n * Copies by default — self-contained, cache-safe, and portable, so a deployed\n * asset survives a `cache clean` of its source and a committed `.claude/` stays\n * machine-independent. `opts.link` opts into a symlink (the live dev-loop), but\n * only when the source has a real local path; store/factory sources (no stable\n * local path) ignore it and still copy. Agents are rendered via the enriched\n * `installAgent` path which resolves abilities, contracts, and framework\n * fragments before writing the native agent file.\n *\n * @param entry - Catalog entry describing the asset to deploy.\n * @param repositories - Repository declarations from `skaile.yaml` (used to\n * determine whether the source is a local path or a remote clone).\n * @param opts - Deployment target options.\n * @param log - Optional logger callback for progress messages.\n * @returns `true` when the asset was deployed successfully.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function deployAsset(\n entry: CatalogEntry,\n repositories: Record<string, SourceDeclaration>,\n opts: DeployOptions = {},\n log: Log = noop,\n): boolean {\n const driverTarget = opts.driverTarget ?? \"claude-code\";\n const globalInstall = opts.global ?? false;\n const cwd = opts.cwd;\n\n // Bundles are not deployed directly — their dependencies are.\n // MCP servers are configured in skaile.yaml, not deployed to driver target dirs.\n if (entry.kind === \"bundle\" || entry.kind === \"mcp-server\") return true;\n\n // Agents need framework-specific rendering via the enriched installAgent path\n if (entry.kind === \"agent\") {\n const workspaceRoot = cwd ?? process.cwd();\n const agentDeployDir = deployedBase(\n \"agent\" as AiComponent,\n driverTarget as DriverTarget,\n globalInstall,\n cwd,\n );\n const targetMap = DRIVER_TARGETS[driverTarget as DriverTarget];\n const skillsRelDir = targetMap?.local.skill ?? \"\";\n const wsConfig = resolveSkWorkspaceConfig(workspaceRoot);\n const name = basename(entry.source);\n const srcDir = DIRECTORY_MANIFESTS.has(name) ? dirname(entry.source) : entry.source;\n const result = installAgent(\n srcDir,\n agentDeployDir,\n workspaceRoot,\n driverTarget,\n skillsRelDir,\n entry.name,\n /* includeSubAgents */ true,\n new Set<string>(),\n wsConfig,\n log,\n );\n for (const w of result.warnings) log(` warn: ${w}`);\n if (result.created.length > 0) return true;\n // Fall through to raw deploy if renderer produces no files (unsupported framework, etc.)\n }\n\n const dest = deployedDir(entry.kind as AiComponent, entry.name, driverTarget, globalInstall, cwd);\n mkdirSync(dirname(dest), { recursive: true });\n\n // Symlink only on explicit opt-in AND when the source has a real local path.\n // Factory sources have a `path` (the bundled dir under node_modules, replaced\n // on every upgrade) but no stable dev-loop, so they always copy. Default copy\n // keeps deploys cache-safe and portable.\n const repoDecl = entry.publisher ? repositories[entry.publisher] : undefined;\n const hasLocalPath = repoDecl?.path != null && repoDecl.factory !== true;\n\n if (opts.link === true && hasLocalPath) {\n symlinkFromManifest(entry.source, dest);\n log(` symlink ${entry.kind}:${entry.name}`);\n return true;\n } else {\n copyFromManifest(entry.source, dest);\n log(` copy ${entry.kind}:${entry.name}`);\n return true;\n }\n}\n\n/**\n * Deploy all resolved assets, applying patches where configured.\n *\n * Already-deployed assets are skipped unless their deployed manifest content differs\n * from the source. This handles copies that have gone stale after a source update.\n * In copy mode (the default, `!opts.link`) an existing **symlink** dest is healed:\n * it is removed and re-deployed as a real copy, so an old/legacy symlink deploy is\n * silently upgraded. With `opts.link` an existing symlink is left alone.\n *\n * @param resolved - Catalog entries to deploy (output of `resolveAll`).\n * @param repositories - Repository declarations from `skaile.yaml`.\n * @param patches - Map of `kind:name` → patch file path for patch application.\n * @param opts - Deployment target options.\n * @param log - Optional logger callback for progress messages.\n * @returns Array of asset refs (`kind:name`) that were newly deployed in this call.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function deployAll(\n resolved: CatalogEntry[],\n repositories: Record<string, SourceDeclaration>,\n patches: Record<string, string>,\n opts: DeployOptions = {},\n log: Log = noop,\n): string[] {\n const deployed: string[] = [];\n const driverTarget = opts.driverTarget ?? \"claude-code\";\n const globalInstall = opts.global ?? false;\n const cwd = opts.cwd;\n\n for (const entry of resolved) {\n // Skip non-deployable asset kinds — bundles are resolved to their contents,\n // mcp-servers are wired at session startup, and mixin kinds (persona, ruleset,\n // knowledge) are resolved by the mixin-resolver at session creation time.\n if (\n entry.kind === \"bundle\" ||\n entry.kind === \"mcp-server\" ||\n entry.kind === \"persona\" ||\n entry.kind === \"ruleset\" ||\n entry.kind === \"knowledge\"\n )\n continue;\n\n const ref = `${entry.kind}:${entry.name}`;\n\n if (isDeployed(entry.kind as AiComponent, entry.name, driverTarget, globalInstall, cwd)) {\n // Compare the deployed manifest file against the source to detect stale copies.\n // For symlinks the deployed path resolves through to the source file, so hashes\n // always match — symlinked installs are never needlessly re-linked.\n const dest = deployedDir(\n entry.kind as AiComponent,\n entry.name,\n driverTarget,\n globalInstall,\n cwd,\n );\n // Heal: in copy mode an existing symlink dest is left to fall through to a\n // real copy below (cache-safe + portable) — bypass the hash skip entirely.\n // With --link a symlink dest is intentional, so it takes the normal skip path.\n let destIsSymlink = false;\n try {\n destIsSymlink = lstatSync(dest).isSymbolicLink();\n } catch {}\n const healSymlink = destIsSymlink && opts.link !== true;\n // Surface the one-time symlink→copy migration so an author who relied on a\n // live symlink dev-loop knows why edits stopped reflecting.\n if (healSymlink) log(` healed symlink → copy: ${ref} (use --link for the dev-loop)`);\n\n if (!healSymlink) {\n const manifestName = basename(entry.source);\n const deployedManifest = join(dest, manifestName);\n // isDeployed() only lstats the dir, so a present-but-empty dir (manifest\n // file deleted) reads as deployed. A missing manifest must never count as\n // \"already deployed\" — fall through to re-deploy instead of skipping.\n // (existsSync follows symlinks, so for symlinked installs the manifest\n // resolves through to the live source and the hash check below still\n // skips them.)\n if (existsSync(deployedManifest)) {\n try {\n const srcHash = computeHash(entry.source);\n const depHash = computeHash(deployedManifest);\n if (srcHash === depHash) {\n log(` already deployed: ${ref}`);\n continue;\n }\n log(` updating: ${ref} (content changed)`);\n // fall through to redeploy\n } catch {\n // Deployed manifest unreadable (e.g. agent rendered to a different path) — skip\n log(` already deployed: ${ref}`);\n continue;\n }\n }\n }\n }\n\n deployAsset(entry, repositories, opts, log);\n deployed.push(ref);\n\n // Apply patch if configured\n const patchFile = patches[ref];\n if (patchFile && existsSync(patchFile)) {\n const dest = deployedDir(\n entry.kind as AiComponent,\n entry.name,\n driverTarget,\n globalInstall,\n cwd,\n );\n if (applyPatch(dest, patchFile)) {\n log(` patched ${ref}`);\n } else {\n log(` patch failed for ${ref}`);\n }\n }\n }\n\n return deployed;\n}\n\n/**\n * Remove a deployed asset from the framework directory.\n *\n * Removes symlinks with `unlink`; removes copied directories with `rm -rf`.\n *\n * @param kind - Asset kind (`skill`, `agent`, `prompt`, `flow`, `contract`).\n * @param name - Asset name as registered in the catalog.\n * @param opts - Deployment target options (must match the options used at install time).\n * @returns `true` if the asset existed and was removed; `false` if it was not deployed.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function removeAsset(kind: string, name: string, opts: DeployOptions = {}): boolean {\n const driverTarget = opts.driverTarget ?? \"claude-code\";\n const globalInstall = opts.global ?? false;\n const cwd = opts.cwd;\n\n const dest = deployedDir(kind as AiComponent, name, driverTarget, globalInstall, cwd);\n try {\n const s = lstatSync(dest);\n if (s.isSymbolicLink()) unlinkSync(dest);\n else rmSync(dest, { recursive: true, force: true });\n return true;\n } catch {\n return false;\n }\n}\n\n// ── Scaffold ─────────────────────────────────────────────────────────────────\n\nconst SKILL_TEMPLATE = `---\nname: \"{name}\"\ndescription: \"\"\nmetadata:\n version: \"0.1.0\"\n---\n\n# {name}\n\nSkill prompt goes here.\n`;\n\nconst BUNDLE_TEMPLATE = `name: {name}\ndescription: A curated set of assets\nversion: 0.1.0\ndependencies:\n - skill:example-skill\n`;\n\nconst FLOW_TEMPLATE = `id: \"{name}\"\nversion: \"0.1.0\"\nname: \"{name}\"\ndescription: Flow description\n\nglobals:\n approval_mode: checkpoint\n\nnodes: []\n`;\n\n/**\n * Create a minimal scaffold directory for a new asset.\n *\n * Writes the appropriate manifest file (`SKILL.md`, `AGENT.md`, `CONTRACT.md`,\n * `<name>.bundle.yaml`, `<name>.flow.yaml`, or `<name>.prompt.md`) inside a\n * new `<destDir>/<name>/` directory.\n *\n * @param name - Asset name (also used as the directory name).\n * @param kind - Asset kind: `skill` | `agent` | `bundle` | `flow` | `prompt` | `contract`.\n * @param destDir - Parent directory to create the asset in.\n * @returns `{ ok: true, path }` on success, `{ ok: false, path: errorMessage }` if the\n * directory already exists.\n * @docLink packages/asset-manager/api-reference#installer\n */\nexport function createScaffold(\n name: string,\n kind: string,\n destDir: string,\n): { ok: boolean; path: string } {\n const dest = join(destDir, name);\n if (existsSync(dest)) {\n return { ok: false, path: `Directory '${name}' already exists in ${destDir}` };\n }\n mkdirSync(dest, { recursive: true });\n\n if (kind === \"bundle\") {\n writeFileSync(\n join(dest, `${name}.bundle.yaml`),\n BUNDLE_TEMPLATE.replace(/\\{name\\}/g, name),\n \"utf8\",\n );\n } else if (kind === \"flow\") {\n writeFileSync(\n join(dest, `${name}.flow.yaml`),\n FLOW_TEMPLATE.replace(/\\{name\\}/g, name),\n \"utf8\",\n );\n } else if (kind === \"prompt\") {\n writeFileSync(\n join(dest, `${name}.prompt.md`),\n SKILL_TEMPLATE.replace(/\\{name\\}/g, name),\n \"utf8\",\n );\n } else if (kind === \"agent\") {\n writeFileSync(join(dest, \"AGENT.md\"), SKILL_TEMPLATE.replace(/\\{name\\}/g, name), \"utf8\");\n } else if (kind === \"contract\") {\n writeFileSync(join(dest, \"CONTRACT.md\"), SKILL_TEMPLATE.replace(/\\{name\\}/g, name), \"utf8\");\n } else {\n // Default: skill\n writeFileSync(join(dest, \"SKILL.md\"), SKILL_TEMPLATE.replace(/\\{name\\}/g, name), \"utf8\");\n }\n\n return { ok: true, path: dest };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../cli/src/paths.ts"],"names":[],"mappings":";;;;;;AAgBA,IAAM,WAAW,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAW5D,SAAS,iBAAiB,IAAA,EAA6B;AACrD,EAAA,IAAI,GAAA,GAAM,IAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,IAAI,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,CAAK,KAAK,YAAY,CAAC,GAAG,OAAO,GAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC/B,IAAA,IAAI,WAAW,GAAA,EAAK;AACpB,IAAA,GAAA,GAAM,MAAA;AAAA,EACR;AACA,EAAA,OAAO,IAAA;AACT;AAYO,IAAM,aAAA,GAA+B,iBAAiB,QAAQ;AAc9D,IAAM,YAAA,GACX,iBAAA,EAAkB,CAAE,CAAC,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,EAAA,CAAG,OAAA,EAAQ,EAAG,SAAA,EAAW,WAAW","file":"chunk-XN7DAZB7.js","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { factoryAssetRoots } from \"@skaile/workspaces/core\";\n\n/**\n * The content-root policy lives in `@skaile/workspaces/core` so the flow\n * connector's resolution surfaces can reach it too — `factory-assets → cli`\n * would be a module cycle. Re-exported here because this module is the CLI's\n * documented path surface and every CLI caller imports it from here.\n *\n * @docLink cli/dev-guide#paths\n */\nexport { aiResourceRoots } from \"@skaile/workspaces/core\";\n\nconst __ownDir = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Walk up from `from` looking for the monorepo marker (`biome.json`, the\n * repo-root shared tooling config). Returns the matching directory or `null`\n * when none is found within eight levels — the latter is the typical case when\n * `@skaile/workspaces` has been installed via `npm i` without a skaile-dev\n * workspace context. Used only to gate dev-only commands (e.g.\n * `serve --compile-test`); first-party content is located via\n * {@link aiResourceRoots}, not this.\n */\nfunction findMonorepoRoot(from: string): string | null {\n let dir = from;\n for (let i = 0; i < 8; i++) {\n if (fs.existsSync(path.join(dir, \"biome.json\"))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Absolute path to the monorepo root, or `null` when the CLI is running\n * outside the skaile-dev workspace (typical for `npm i -g` installs).\n *\n * Consumers that only make sense inside the workspace (e.g.\n * `skaile serve --compile-test`) MUST check for `null` and report a\n * \"monorepo-only feature\" error before proceeding.\n *\n * @docLink cli/dev-guide#paths\n */\nexport const MONOREPO_ROOT: string | null = findMonorepoRoot(__ownDir);\n\n/**\n * Default content root used by path display and the `validate` command.\n *\n * The primary first-party `factory-assets/` root resolved through the shared\n * `factoryAssetRoots()` helper — the `SKAILE_FACTORY_ASSETS_DIR` override when\n * set, else the in-repo source during dev / bundled `dist/factory-assets/` after\n * `npm i`. Falls back to `~/.skaile/libraries/` — the user-library directory\n * managed by `skaile library add` — when the package cannot be located.\n * Consumers `fs.existsSync` first and degrade to \"no skills / flows discovered\".\n *\n * @docLink cli/dev-guide#paths\n */\nexport const AI_RESOURCES: string =\n factoryAssetRoots()[0] ?? path.join(os.homedir(), \".skaile\", \"libraries\");\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../cli/src/ensure-sources.ts"],"names":[],"mappings":"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","file":"ensure-sources-IGU65O72.js","sourcesContent":["/**\n * ensure-sources.ts — hydrate the `~/.skaile/cache/sources/` clone cache from a\n * project's `skaile.yaml` `sources:` entries.\n *\n * Called by `skaile init` (idempotent: no-op when no sources declared) and\n * `skaile install` so checking out a project pulls its source clones onto\n * the local machine.\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n getGlobalCacheDir,\n type SourceEntry,\n sourceCacheKey,\n sourceShortName,\n WorkspaceYamlEditor,\n} from \"@skaile/workspaces/core\";\nimport { logErr, logInfo, logOk } from \"./helpers.ts\";\n\nfunction sourceClonePath(key: string): string {\n return path.join(getGlobalCacheDir(), key);\n}\n\nexport interface EnsureResult {\n cloned: string[];\n cached: string[];\n failed: string[];\n}\n\n/** Load `sources:` from a project's `skaile.yaml`, or `null` when unavailable. */\nfunction loadProjectSources(yamlPath: string, quiet: boolean): SourceEntry[] | null {\n try {\n return WorkspaceYamlEditor.load(yamlPath).getSources();\n } catch (err) {\n if (!quiet) {\n logErr(`Could not read ${yamlPath}: ${err instanceof Error ? err.message : String(err)}`);\n }\n return null;\n }\n}\n\n/**\n * Hydrate a single source entry into `result`: skip when already cached,\n * otherwise clone and record success/failure. Mutates `result` in place.\n */\nfunction hydrateSourceEntry(entry: SourceEntry, quiet: boolean, result: EnsureResult): void {\n const key = sourceCacheKey(entry.url);\n const slug = sourceShortName(entry.url);\n const dest = sourceClonePath(key);\n if (existsSync(dest)) {\n result.cached.push(slug);\n return;\n }\n mkdirSync(path.dirname(dest), { recursive: true });\n const args = [\"clone\", entry.url, dest];\n if (entry.pin) args.splice(1, 0, \"--branch\", entry.pin);\n const clone = spawnSync(\"git\", args, { stdio: quiet ? \"pipe\" : \"inherit\" });\n if (clone.status !== 0) {\n result.failed.push(slug);\n if (quiet) {\n logErr(`git clone failed for ${entry.url}`);\n }\n return;\n }\n result.cloned.push(slug);\n}\n\n/** Log a full-hydrate summary of cloned + reused-cached entries. */\nfunction logHydrateSummary(result: EnsureResult): void {\n for (const n of result.cloned) logOk(`Cloned source \"${n}\".`);\n if (result.cached.length > 0) {\n logInfo(`Reused cached clones: ${result.cached.join(\", \")}`);\n }\n}\n\n/**\n * Walk `projectDir/skaile.yaml` `sources:` and clone any entries whose\n * clone directory does not yet exist under `~/.skaile/cache/sources/`. Existing\n * clones are left untouched — this is hydration, not sync.\n *\n * Quiet by default: when `quiet: true` the helper only prints failures.\n * On full hydrate (`quiet: false`) it logs each cloned/cached entry.\n */\nexport function ensureSourcesCloned(\n projectDir: string,\n opts: { quiet?: boolean } = {},\n): EnsureResult {\n const result: EnsureResult = { cloned: [], cached: [], failed: [] };\n const yamlPath = path.join(projectDir, \"skaile.yaml\");\n if (!existsSync(yamlPath)) return result;\n\n const quiet = opts.quiet ?? false;\n const sources = loadProjectSources(yamlPath, quiet);\n if (sources === null) return result;\n if (sources.length === 0) return result;\n\n for (const entry of sources) {\n hydrateSourceEntry(entry, quiet, result);\n }\n\n if (!quiet) {\n logHydrateSummary(result);\n }\n\n return result;\n}\n"]}
@@ -1,24 +0,0 @@
1
- export { flowFindFlowForSession, flowGetSession, flowList, flowListSessions, flowShow } from './chunk-MRS5YHPI.js';
2
- import './chunk-OEBAXTQ4.js';
3
- import './chunk-R6O6YWU7.js';
4
- import './chunk-X5YPJV4N.js';
5
- import './chunk-5JAO4MXA.js';
6
- import './chunk-FJYOQMXT.js';
7
- import './chunk-4GY63JU6.js';
8
- import './chunk-VRFKCF3R.js';
9
- import './chunk-KIFJWSNC.js';
10
- import './chunk-K5GBV4SA.js';
11
- import './chunk-QVZA2MDT.js';
12
- import './chunk-QKXDRBLL.js';
13
- import './chunk-EB4ZTESQ.js';
14
- import './chunk-P4VHQA4N.js';
15
- import './chunk-SQ7IN7KR.js';
16
- import './chunk-GEEW6SY2.js';
17
- import './chunk-JMKB7IB4.js';
18
- import './chunk-ICSCSM5D.js';
19
- import './chunk-MJHSLODD.js';
20
- import './chunk-C3CAXQMA.js';
21
- import './chunk-BOFL7GIF.js';
22
- import './chunk-NSBPE2FW.js';
23
- //# sourceMappingURL=flows-6MDMBQUZ.js.map
24
- //# sourceMappingURL=flows-6MDMBQUZ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../cli/src/commands/library-publish.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,IAAM,iBAAA,GAAoB,sBAAA;AAG1B,SAAS,YAAY,GAAA,EAAkC;AACrD,EAAA,IAAI,GAAA,CAAI,OAAA,KAAY,KAAA,EAAO,OAAO,MAAA;AAClC,EAAA,OAAQ,IAAI,aAAA,CAAmC,GAAA;AACjD;AAGA,SAAS,SAAS,GAAA,EAAsB;AACtC,EAAA,IAAI,GAAA,CAAI,OAAA,KAAY,KAAA,EAAO,OAAO,MAAA;AAClC,EAAA,OAAQ,GAAA,CAAI,cAAmC,MAAA,IAAU,MAAA;AAC3D;AAMA,SAAS,aAAa,OAAA,EAAoC;AACxD,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAA,GAAO,YAAA,CAAa,IAAA,CAAK,OAAA,EAAS,iBAAiB,GAAG,OAAO,CAAA;AAAA,EAC/D,CAAA,CAAA,MAAQ;AACN,IAAA,MAAA;AAAA,MACE,CAAA,GAAA,EAAM,CAAA,CAAE,GAAA,CAAI,iBAAiB,CAAC,CAAA,+GAAA;AAAA,KAEhC;AACA,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACA,EAAA,MAAM,EAAE,QAAA,EAAU,WAAA,EAAY,GAAI,qBAAqB,IAAI,CAAA;AAC3D,EAAA,MAAM,SAAS,WAAA,CAAY,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,OAAO,CAAA;AAC/D,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,KAAA,MAAW,CAAA,IAAK,QAAQ,MAAA,CAAO,CAAA,EAAG,EAAE,IAAI,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AACxD,IAAA,MAAA,CAAO,mFAA8E,CAAA;AACrF,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACA,EAAA,OAAO,QAAA;AACT;AAGA,SAAS,MAAA,CAAO,KAAA,EAAkB,GAAA,EAAa,IAAA,EAAgB;AAC7D,EAAA,OAAO,KAAA,CAAM,KAAA,EAAO,CAAC,IAAA,EAAM,GAAA,EAAK,GAAG,IAAI,CAAA,EAAG,EAAE,QAAA,EAAU,OAAA,EAAS,CAAA;AACjE;AAQA,SAAS,cAAc,IAAA,EAKd;AACP,EAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAW,MAAA,EAAQ,OAAM,GAAI,IAAA;AAE9C,EAAA,MAAM,SAAS,MAAA,CAAO,KAAA,EAAO,SAAS,CAAC,WAAA,EAAa,WAAW,CAAC,CAAA;AAChE,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,MAAM,OAAO,MAAA,CAAO,KAAA,EAAO,OAAA,EAAS,CAAC,MAAM,CAAC,CAAA;AAC5C,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,iBAAA,EAAA,CAAqB,IAAA,CAAK,MAAA,IAAU,EAAA,EAAI,QAAA,EAAS,CAAE,IAAA,EAAK,IAAK,CAAA,KAAA,EAAQ,IAAA,CAAK,MAAM,CAAA,CAAE,CAAA;AAAA,OACpF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAAS,OAAO,KAAA,EAAO,OAAA,EAAS,CAAC,QAAA,EAAU,SAAA,EAAW,QAAQ,CAAC,CAAA;AACrE,EAAA,MAAM,UAAA,GACJ,MAAA,CAAO,MAAA,KAAW,CAAA,GACd,CAAC,QAAA,EAAU,SAAA,EAAW,QAAA,EAAU,SAAS,CAAA,GACzC,CAAC,QAAA,EAAU,KAAA,EAAO,UAAU,SAAS,CAAA;AAC3C,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,KAAA,EAAO,OAAA,EAAS,UAAU,CAAA;AACnD,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,mBAAA,EAAA,CAAuB,SAAA,CAAU,MAAA,IAAU,EAAA,EAAI,QAAA,EAAS,CAAE,IAAA,EAAK,IAAK,CAAA,KAAA,EAAQ,SAAA,CAAU,MAAM,CAAA,CAAE,CAAA;AAAA,KAChG;AAAA,EACF;AAEA,EAAA,MAAM,MAAM,MAAA,CAAO,KAAA,EAAO,SAAS,CAAC,KAAA,EAAO,IAAI,CAAC,CAAA;AAChD,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,gBAAA,EAAA,CAAoB,GAAA,CAAI,MAAA,IAAU,EAAA,EAAI,QAAA,EAAS,CAAE,IAAA,EAAK,IAAK,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,KACjF;AAAA,EACF;AAIA,EAAA,MAAM,MAAA,GAAS,KAAA;AAAA,IACb,KAAA;AAAA,IACA;AAAA,MACE,IAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA;AAAA,MACA,iCAAA;AAAA,MACA,IAAA;AAAA,MACA,kBAAA;AAAA,MACA,QAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,EAAE,UAAU,OAAA;AAAQ,GACtB;AACA,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,MAAM,GAAA,GAAM,GAAG,MAAA,CAAO,MAAA,IAAU,EAAE,CAAA,EAAG,MAAA,CAAO,UAAU,EAAE,CAAA,CAAA;AACxD,IAAA,IAAI,CAAC,oBAAA,CAAqB,IAAA,CAAK,GAAG,CAAA,EAAG;AACnC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,GAAA,CAAI,IAAA,MAAU,CAAA,KAAA,EAAQ,MAAA,CAAO,MAAM,CAAA,CAAE,CAAA,CAAE,CAAA;AAAA,IAC/E;AAAA,EACF;AAEA,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,KAAA,EAAO,OAAA,EAAS,CAAC,QAAQ,QAAA,EAAU,CAAA,KAAA,EAAQ,MAAM,CAAA,CAAE,CAAC,CAAA;AACxE,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,iBAAA,EAAA,CAAqB,IAAA,CAAK,MAAA,IAAU,EAAA,EAAI,QAAA,EAAS,CAAE,IAAA,EAAK,IAAK,CAAA,KAAA,EAAQ,IAAA,CAAK,MAAM,CAAA,CAAE,CAAA;AAAA,KACpF;AAAA,EACF;AACF;AAMA,SAAS,eAAA,CAAgB,MAAc,KAAA,EAA0B;AAC/D,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,IAAA,EAAM,CAAC,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAM,UAAU,CAAA,EAAG,EAAE,QAAA,EAAU,OAAA,EAAS,CAAA;AACnF,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,IAAA,MAAM,UAAU,GAAA,CAAI,MAAA,IAAU,EAAA,EAAI,QAAA,GAAW,IAAA,EAAK;AAClD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,IAAI,CAAA,SAAA,EAAY,UAAU,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA,CAAE,CAAA;AAAA,EACpF;AAIA,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,GAAA,CAAI,MAAA,IAAU,EAAE;AAAA,EAAK,GAAA,CAAI,UAAU,EAAE,CAAA,CAAA;AACpD,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,+BAA+B,CAAA;AACvD,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,IAAI,CAAA;AAAA,EAAwC,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAA;AAAA,EAC5F;AACA,EAAA,OAAO,MAAM,CAAC,CAAA,CAAE,QAAQ,QAAA,EAAU,EAAE,EAAE,IAAA,EAAK;AAC7C;AAGA,eAAe,cAAA,CACb,IAAA,EACA,IAAA,EAOA,MAAA,EACA,QAAmB,SAAA,EACJ;AACf,EAAA,MAAM,WAAW,MAAA,KAAW,MAAA;AAC5B,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,MAAM,kBAAA,EAAmB;AACpD,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,cAAA,CAAe,IAAI,CAAA;AAC7C,IAAA,MAAM,QAAA,GAAW,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA;AAItC,IAAA,IAAI,SAAA,GAAY,YAAY,GAAG,CAAA;AAC/B,IAAA,IAAI,eAAA,GAAkB,KAAA;AACtB,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,IAAI,KAAK,UAAA,EAAY;AACnB,QAAA,IAAI,KAAK,MAAA,EAAQ;AAGf,UAAA,eAAA,GAAkB,IAAA;AAClB,UAAA,SAAA,GAAY,CAAA,kCAAA,EAAqC,IAAI,IAAI,CAAA,CAAA;AAAA,QAC3D,CAAA,MAAO;AACL,UAAA,SAAA,GAAY,eAAA,CAAgB,GAAA,CAAI,IAAA,EAAM,KAAK,CAAA;AAC3C,UAAA,MAAM,OAAA,CAAQ,cAAc,IAAA,EAAM;AAAA,YAChC,OAAA,EAAS,KAAA;AAAA,YACT,eAAe,EAAE,GAAA,EAAK,WAAW,MAAA,EAAQ,MAAA,EAAQ,UAAU,KAAA;AAAM,WAClE,CAAA;AACD,UAAA,KAAA,CAAM,CAAA,iBAAA,EAAoB,CAAA,CAAE,GAAA,CAAI,SAAS,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,QAC/C;AAAA,MACF,CAAA,MAAO;AACL,QAAA,MAAA;AAAA,UACE,CAAA,SAAA,EAAY,IAAI,CAAA,2BAAA,EAAyB,CAAA,CAAE,IAAI,CAAA,oBAAA,EAAuB,IAAI,QAAQ,CAAC,CAAA,6DAAA;AAAA,SAErF;AACA,QAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,MAChB;AAAA,IACF;AAGA,IAAA,MAAM,SAAA,GAAY,SAAS,SAAA,IAAa,sBAAA;AACxC,IAAA,MAAM,aAAa,IAAA,CAAK,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,KAAK,CAAA,GAAI,KAAA,CAAA;AACvD,IAAA,MAAM,WAAA,GAAA,CAAe,QAAA,CAAS,MAAA,IAAU,EAAC,EACtC,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,UAAA,IAAc,CAAA,CAAE,IAAA,KAAS,UAAU,CAAA,CAClD,GAAA,CAAI,CAAC,CAAA,KAAM,MAAA,CAAO,CAAA,CAAE,IAAA,EAAM,SAAA,EAAW,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,OAAA,IAAW,QAAA,CAAS,OAAO,CAAC,CAAA;AAE9E,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,IAAO,QAAA,CAAS,GAAG,CAAA;AAE1C,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,OAAA,CAAQ,CAAA,iBAAA,EAAoB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AAC3C,MAAA,OAAA;AAAA,QACE,CAAA,cAAA,EAAiB,SAAS,CAAA,EAAG,eAAA,GAAkB,uDAAuD,EAAE,CAAA;AAAA,OAC1G;AACA,MAAA,OAAA,CAAQ,CAAA,cAAA,EAAiB,SAAS,CAAA,CAAE,CAAA;AAGpC,MAAA,IAAI,QAAA,CAAS,SAAA,KAAc,QAAA,IAAY,oBAAA,EAAqB,CAAA,EAAI;AAC9D,QAAA,IAAI;AACF,UAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,MAAA,IAAU,uBAAA,EAAwB,EAAG,qBAAA;AAAA,YACxD,QAAA,CAAS;AAAA,WACX;AACA,UAAA,OAAA,CAAQ,CAAA,cAAA,EAAiB,2BAAA,CAA4B,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,QAC/D,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF;AACA,MAAA,OAAA,CAAQ,CAAA,cAAA,EAAiB,SAAS,CAAA,CAAE,CAAA;AACpC,MAAA,OAAA,CAAQ,CAAA,gBAAA,EAAmB,WAAA,CAAY,MAAM,CAAA,UAAA,CAAY,CAAA;AACzD,MAAA,KAAA,MAAW,CAAA,IAAK,WAAA,EAAa,OAAA,CAAQ,CAAA,IAAA,EAAO,CAAC,CAAA,CAAE,CAAA;AAC/C,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,QAAA,IAAY,CAAC,oBAAA,EAAqB,EAAG;AACxC,MAAA,MAAA,CAAO,sDAAiD,CAAA;AACxD,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAEA,IAAA,MAAM,GAAA,GAAM,UAAU,uBAAA,EAAwB;AAI9C,IAAA,IAAI,SAAS,SAAA,EAAW;AACtB,MAAA,MAAM,IAAA,GAAO,MAAM,kBAAA,CAAmB,GAAA,EAAK,SAAS,SAAS,CAAA;AAC7D,MAAA,IAAI,CAAC,KAAK,EAAA,EAAI;AACZ,QAAA,MAAA,CAAO,IAAA,CAAK,OAAA,IAAW,CAAA,sBAAA,EAAyB,QAAA,CAAS,SAAS,CAAA,CAAA,CAAG,CAAA;AACrE,QAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,MAChB;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAGlB,MAAA,OAAA;AAAA,QACE,CAAA,wDAAA,EAA2D,CAAA,CAAE,GAAA,CAAI,SAAS,CAAC,CAAA,wEAAA;AAAA,OAE7E;AACA,MAAA,aAAA,CAAc,EAAE,OAAA,EAAS,GAAA,CAAI,IAAA,EAAM,SAAA,EAAW,QAAQ,QAAA,CAAS,GAAG,CAAA,EAAG,KAAA,EAAO,CAAA;AAC5E,MAAA,KAAA,CAAM,CAAA,OAAA,EAAU,CAAA,CAAE,GAAA,CAAI,IAAI,CAAC,OAAO,CAAA,CAAE,GAAA,CAAI,SAAS,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,IACvD;AAEA,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,cAAA,CAAe;AAAA,MACzC,SAAA,EAAW,SAAA;AAAA,MACX,GAAA,EAAK,SAAA;AAAA,MACL,QAAA;AAAA,MACA,SAAA,EAAW,UAAA;AAAA,MACX,MAAA,EAAQ;AAAA,KACT,CAAA;AAED,IAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACxB,MAAA,OAAA,CAAQ,CAAA,+BAAA,EAAkC,SAAA,CAAU,CAAC,CAAC,CAAA,GAAA,CAAK,CAAA;AAAA,IAC7D;AAAA,EACF,CAAA,SAAE;AACA,IAAA,KAAA,EAAM;AAAA,EACR;AACF;AAOA,eAAsB,iBAAA,CACpB,IAAA,EACA,IAAA,EACA,MAAA,EACA,QAAmB,SAAA,EACJ;AACf,EAAA,MAAM,cAAA,CAAe,MAAM,EAAE,GAAG,MAAM,QAAA,EAAU,KAAA,EAAM,EAAG,MAAA,EAAQ,KAAK,CAAA;AACxE;AAOA,eAAsB,kBAAA,CACpB,IAAA,EACA,IAAA,EACA,MAAA,EACA,QAAmB,SAAA,EACJ;AACf,EAAA,MAAM,cAAA,CAAe,MAAM,EAAE,GAAG,MAAM,QAAA,EAAU,IAAA,EAAK,EAAG,MAAA,EAAQ,KAAK,CAAA;AACvE;AAOA,eAAsB,cAAA,CACpB,IAAA,EACA,IAAA,EACA,MAAA,EACe;AACf,EAAA,MAAM,WAAW,MAAA,KAAW,MAAA;AAC5B,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,MAAM,kBAAA,EAAmB;AACpD,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,cAAA,CAAe,IAAI,CAAA;AAC7C,IAAA,MAAM,SAAA,GAAY,YAAY,GAAG,CAAA;AACjC,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAA,CAAO,CAAA,SAAA,EAAY,IAAI,CAAA,iDAAA,CAA8C,CAAA;AACrE,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAEA,IAAA,IAAI,CAAC,QAAA,IAAY,CAAC,oBAAA,EAAqB,EAAG;AACxC,MAAA,MAAA,CAAO,sDAAiD,CAAA;AACxD,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAEA,IAAA,MAAM,GAAA,GAAM,UAAU,uBAAA,EAAwB;AAC9C,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,WAAA,EAAY;AACnC,IAAA,MAAM,SAAS,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,SAAS,CAAA;AACnD,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAA,CAAO,CAAA,SAAA,EAAY,IAAI,CAAA,wDAAA,CAAqD,CAAA;AAC5E,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAEA,IAAA,MAAM,aAAa,IAAA,CAAK,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,KAAK,CAAA,GAAI,KAAA,CAAA;AACvD,IAAA,MAAM,cAAc,MAAM,GAAA,CAAI,gBAAA,CAAiB,MAAA,CAAO,EAAE,CAAA,EAAG,MAAA;AAAA,MACzD,CAAC,CAAA,KAAM,CAAA,CAAE,cAAc,CAAC,UAAA,IAAc,EAAE,IAAA,KAAS,UAAA;AAAA,KACnD;AACA,IAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,MAAA,OAAA,CAAQ,qDAAgD,CAAA;AACxD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,SAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,MAAA,IAAI;AACF,QAAA,MAAM,GAAA,CAAI,cAAA,CAAe,CAAA,CAAE,EAAE,CAAA;AAC7B,QAAA,MAAA,CAAO,KAAK,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AAAA,MACnC,SAAS,GAAA,EAAK;AACZ,QAAA,MAAA;AAAA,UACE,CAAA,eAAA,EAAkB,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,SACzF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,KAAA,CAAM,CAAA,OAAA,EAAU,MAAA,CAAO,MAAM,CAAA,UAAA,CAAY,CAAA;AACzC,IAAA,KAAA,MAAW,CAAA,IAAK,MAAA,EAAQ,OAAA,CAAQ,CAAA,EAAA,EAAK,CAAC,CAAA,CAAE,CAAA;AAAA,EAC1C,CAAA,SAAE;AACA,IAAA,KAAA,EAAM;AAAA,EACR;AACF","file":"library-publish-YKBYHZ43.js","sourcesContent":["/**\n * `skaile library publish / register / yank` — the first-party publish flow.\n * A git-backed library you own carries an in-repo `skaile.manifest.yaml`; this\n * commits + pushes the library repo (publish), or takes the current remote HEAD\n * as-is (register), then registers + syncs it as a store source and publishes\n * the manifest's assets under the manifest's own `publisher` (no namespace\n * remap — first-party authors intend their declared namespace).\n *\n * - `publish` = commit (if dirty) + push + register + sync + publish.\n * - `register` = same, but skip the commit/push (bytes already on GitHub).\n * - `yank` = unpublish the library's published assets (all, or one).\n *\n * The store REST surface is reached through the injectable {@link PublisherClient}\n * (default HTTP); git side-effects go through an injectable `spawn`. Both seams\n * keep the flow unit/integration-testable without a live store or a real remote.\n *\n * @docLink cli/commands/library\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { decodeSkaileManifest, type SkPublishManifest } from \"@skaile/workspaces/core\";\nimport type { GitBackendConfig, Library } from \"@skaile/workspaces/library\";\nimport { logErr, logInfo, logOk, S } from \"../helpers.ts\";\nimport { openLibraryManager } from \"../open-library.ts\";\nimport { isStoreAuthenticated } from \"../store-client.ts\";\nimport { makeHttpPublisherClient, type PublisherClient } from \"../store-publisher.ts\";\nimport {\n bareName,\n formatNamespaceAvailability,\n preflightNamespace,\n publishToStore,\n refFor,\n} from \"./publish-core.ts\";\n\n/** Injectable spawn contract — the subset of `spawnSync` these helpers use. */\ntype SpawnLike = typeof spawnSync;\n\n/** The fixed filename a library carries at its root for publication. */\nconst MANIFEST_FILENAME = \"skaile.manifest.yaml\";\n\n/** The remote url of a git-backed library, or `undefined` for a local one. */\nfunction remoteUrlOf(lib: Library): string | undefined {\n if (lib.backend !== \"git\") return undefined;\n return (lib.backendConfig as GitBackendConfig).url;\n}\n\n/** The publish branch of a git-backed library (defaults to `main`). */\nfunction branchOf(lib: Library): string {\n if (lib.backend !== \"git\") return \"main\";\n return (lib.backendConfig as GitBackendConfig).branch ?? \"main\";\n}\n\n/**\n * Read + decode the in-repo `skaile.manifest.yaml`. Prints each error\n * diagnostic and exits (1) — mirroring the sidecar flow's validation gate.\n */\nfunction loadManifest(libPath: string): SkPublishManifest {\n let text: string;\n try {\n text = readFileSync(join(libPath, MANIFEST_FILENAME), \"utf-8\");\n } catch {\n logErr(\n `No ${S.dim(MANIFEST_FILENAME)} in the library — author it (see \\`skaile library create\\`) ` +\n \"and run `skaile validate` before publishing.\",\n );\n process.exit(1);\n }\n const { manifest, diagnostics } = decodeSkaileManifest(text);\n const errors = diagnostics.filter((d) => d.severity === \"error\");\n if (errors.length > 0) {\n for (const d of errors) logErr(`${d.code}: ${d.message}`);\n logErr(\"The manifest has errors — fix them with `skaile validate` before publishing.\");\n process.exit(1);\n }\n return manifest;\n}\n\n/** Run a git command in `cwd` via the injected spawn; returns the result. */\nfunction runGit(spawn: SpawnLike, cwd: string, args: string[]) {\n return spawn(\"git\", [\"-C\", cwd, ...args], { encoding: \"utf-8\" });\n}\n\n/**\n * Ensure `libPath` is a git repo whose `origin` points at `remoteUrl`, then\n * commit any changes and push to `branch`. Idempotent re-publish: an unchanged\n * tree makes `git commit` fail with \"nothing to commit\" — swallowed. Push (or\n * any other git) failures surface as thrown Errors carrying git's stderr.\n */\nfunction commitAndPush(opts: {\n libPath: string;\n remoteUrl: string;\n branch: string;\n spawn: SpawnLike;\n}): void {\n const { libPath, remoteUrl, branch, spawn } = opts;\n\n const gitDir = runGit(spawn, libPath, [\"rev-parse\", \"--git-dir\"]);\n if (gitDir.status !== 0) {\n const init = runGit(spawn, libPath, [\"init\"]);\n if (init.status !== 0) {\n throw new Error(\n `git init failed: ${(init.stderr ?? \"\").toString().trim() || `exit ${init.status}`}`,\n );\n }\n }\n\n // Point origin at the resolved remote (add if absent, else set-url).\n const getUrl = runGit(spawn, libPath, [\"remote\", \"get-url\", \"origin\"]);\n const originArgs =\n getUrl.status === 0\n ? [\"remote\", \"set-url\", \"origin\", remoteUrl]\n : [\"remote\", \"add\", \"origin\", remoteUrl];\n const setOrigin = runGit(spawn, libPath, originArgs);\n if (setOrigin.status !== 0) {\n throw new Error(\n `git remote failed: ${(setOrigin.stderr ?? \"\").toString().trim() || `exit ${setOrigin.status}`}`,\n );\n }\n\n const add = runGit(spawn, libPath, [\"add\", \"-A\"]);\n if (add.status !== 0) {\n throw new Error(\n `git add failed: ${(add.stderr ?? \"\").toString().trim() || `exit ${add.status}`}`,\n );\n }\n\n // Fixed bot identity via -c so the commit succeeds regardless of the author's\n // git config (the publish commit is a machine action).\n const commit = spawn(\n \"git\",\n [\n \"-C\",\n libPath,\n \"-c\",\n \"user.email=publish@skaile.store\",\n \"-c\",\n \"user.name=skaile\",\n \"commit\",\n \"-m\",\n \"chore: publish\",\n ],\n { encoding: \"utf-8\" },\n );\n if (commit.status !== 0) {\n const out = `${commit.stdout ?? \"\"}${commit.stderr ?? \"\"}`;\n if (!/nothing to commit/i.test(out)) {\n throw new Error(`git commit failed: ${out.trim() || `exit ${commit.status}`}`);\n }\n }\n\n const push = runGit(spawn, libPath, [\"push\", \"origin\", `HEAD:${branch}`]);\n if (push.status !== 0) {\n throw new Error(\n `git push failed: ${(push.stderr ?? \"\").toString().trim() || `exit ${push.status}`}`,\n );\n }\n}\n\n/**\n * Provision a public GitHub repo `github.com/<you>/<name>` via `gh` and return\n * its https url. Parses the url `gh` prints on success. Throws on failure.\n */\nfunction createRepoViaGh(name: string, spawn: SpawnLike): string {\n const res = spawn(\"gh\", [\"repo\", \"create\", name, \"--public\"], { encoding: \"utf-8\" });\n if (res.status !== 0) {\n const stderr = (res.stderr ?? \"\").toString().trim();\n throw new Error(`gh repo create ${name} failed: ${stderr || `exit ${res.status}`}`);\n }\n // `gh repo create` prints the repo url (e.g. `https://github.com/<owner>/<name>`);\n // scan combined output for the first github.com url so we capture whatever\n // owner gh resolved (the authed user).\n const out = `${res.stdout ?? \"\"}\\n${res.stderr ?? \"\"}`;\n const match = out.match(/https:\\/\\/github\\.com\\/[^\\s]+/);\n if (!match) {\n throw new Error(`gh repo create ${name} succeeded but printed no repo url:\\n${out.trim()}`);\n }\n return match[0].replace(/\\.git$/, \"\").trim();\n}\n\n/** Shared publish body for `publish` (pushes) and `register` (skips the push). */\nasync function publishLibrary(\n name: string,\n opts: {\n asset?: string;\n createRepo?: boolean;\n ref?: string;\n dryRun?: boolean;\n skipPush: boolean;\n },\n client?: PublisherClient,\n spawn: SpawnLike = spawnSync,\n): Promise<void> {\n const injected = client !== undefined;\n const { manager, close } = await openLibraryManager();\n try {\n const lib = await manager.requireLibrary(name);\n const manifest = loadManifest(lib.path);\n\n // Resolve the remote: git-backed → its url; local + --create-repo → provision\n // and link; else stop with a hint.\n let remoteUrl = remoteUrlOf(lib);\n let wouldCreateRepo = false;\n if (!remoteUrl) {\n if (opts.createRepo) {\n if (opts.dryRun) {\n // A dry-run must not provision anything — defer the real\n // `gh repo create` to the live run and just show the would-be remote.\n wouldCreateRepo = true;\n remoteUrl = `https://github.com/<your-account>/${lib.name}`;\n } else {\n remoteUrl = createRepoViaGh(lib.name, spawn);\n await manager.updateLibrary(name, {\n backend: \"git\",\n backendConfig: { url: remoteUrl, branch: \"main\", authHint: \"ssh\" },\n });\n logOk(`Created + linked ${S.dim(remoteUrl)}.`);\n }\n } else {\n logErr(\n `Library \"${name}\" has no remote — run ${S.cmd(`skaile library link ${name} <url>`)} ` +\n \"first, or pass `--create-repo` to provision a public repo.\",\n );\n process.exit(1);\n }\n }\n\n // The manifest's own publisher is the namespace (first-party — no remap).\n const namespace = manifest.publisher ?? \"<manifest publisher>\";\n const targetName = opts.asset ? bareName(opts.asset) : undefined;\n const wouldBeRefs = (manifest.assets ?? [])\n .filter((a) => !targetName || a.name === targetName)\n .map((a) => refFor(a.kind, namespace, a.name, a.version ?? manifest.version));\n\n const sourceRef = opts.ref ?? branchOf(lib);\n\n if (opts.dryRun) {\n logInfo(`Publish plan for ${S.bold(name)}:`);\n logInfo(\n ` remote: ${remoteUrl}${wouldCreateRepo ? \" (would be created via `gh repo create --public`)\" : \"\"}`,\n );\n logInfo(` publisher: ${namespace}`);\n // Best-effort namespace-availability probe — a read-only GET, only when\n // signed in (or a client is injected). A failure keeps dry-run offline-safe.\n if (manifest.publisher && (injected || isStoreAuthenticated())) {\n try {\n const avail = await (client ?? makeHttpPublisherClient()).namespaceAvailability(\n manifest.publisher,\n );\n logInfo(` namespace: ${formatNamespaceAvailability(avail)}`);\n } catch {\n // Store unreachable / not signed in — skip the advisory, never fail.\n }\n }\n logInfo(` source ref: ${sourceRef}`);\n logInfo(` would publish ${wouldBeRefs.length} asset(s):`);\n for (const r of wouldBeRefs) logInfo(` ${r}`);\n return;\n }\n\n // A real publish makes store calls, so it needs a token (injected fakes bypass).\n if (!injected && !isStoreAuthenticated()) {\n logErr(\"Not signed in — run `skaile store login` first.\");\n process.exit(1);\n }\n\n const pub = client ?? makeHttpPublisherClient();\n\n // Preflight the namespace BEFORE the public git push, so a reserved/unclaimed\n // namespace fails fast with guidance instead of after publishing bytes.\n if (manifest.publisher) {\n const gate = await preflightNamespace(pub, manifest.publisher);\n if (!gate.ok) {\n logErr(gate.message ?? `Cannot publish under @${manifest.publisher}.`);\n process.exit(1);\n }\n }\n\n // publish commits + pushes the library repo; register takes the remote HEAD as-is.\n if (!opts.skipPush) {\n // `git add -A` stages every non-ignored file → a PUBLIC push. Surface it so\n // an unexpected file in the working tree is not silently published.\n logInfo(\n `Committing the library and pushing to the PUBLIC remote ${S.dim(remoteUrl)} ` +\n \"(.gitignore honored; anything else in the working tree becomes public).\",\n );\n commitAndPush({ libPath: lib.path, remoteUrl, branch: branchOf(lib), spawn });\n logOk(`Pushed ${S.dim(name)} to ${S.dim(remoteUrl)}.`);\n }\n\n const { published } = await publishToStore({\n sourceUrl: remoteUrl,\n ref: sourceRef,\n manifest,\n assetName: targetName,\n client: pub,\n });\n\n if (published.length > 0) {\n logInfo(`Consumers can now \\`skaile add ${published[0]}\\`.`);\n }\n } finally {\n close();\n }\n}\n\n/**\n * `skaile library publish <lib>` — commit + push the library repo, register +\n * sync it as a store source, and publish its manifest's assets under the\n * manifest publisher. See the module header for the full flow.\n */\nexport async function runLibraryPublish(\n name: string,\n opts: { asset?: string; createRepo?: boolean; ref?: string; dryRun?: boolean },\n client?: PublisherClient,\n spawn: SpawnLike = spawnSync,\n): Promise<void> {\n await publishLibrary(name, { ...opts, skipPush: false }, client, spawn);\n}\n\n/**\n * `skaile library register <lib>` — same as publish but skips the commit/push\n * (the bytes are already on GitHub at the current remote HEAD). Still requires a\n * git-backed remote.\n */\nexport async function runLibraryRegister(\n name: string,\n opts: { asset?: string; ref?: string; dryRun?: boolean },\n client?: PublisherClient,\n spawn: SpawnLike = spawnSync,\n): Promise<void> {\n await publishLibrary(name, { ...opts, skipPush: true }, client, spawn);\n}\n\n/**\n * `skaile library yank <lib>` — unpublish the library's published assets from\n * the store (all, or the single asset matching `opts.asset`'s name).\n * Auth-gated like publish.\n */\nexport async function runLibraryYank(\n name: string,\n opts: { asset?: string },\n client?: PublisherClient,\n): Promise<void> {\n const injected = client !== undefined;\n const { manager, close } = await openLibraryManager();\n try {\n const lib = await manager.requireLibrary(name);\n const remoteUrl = remoteUrlOf(lib);\n if (!remoteUrl) {\n logErr(`Library \"${name}\" has no remote — nothing published to yank.`);\n process.exit(1);\n }\n\n if (!injected && !isStoreAuthenticated()) {\n logErr(\"Not signed in — run `skaile store login` first.\");\n process.exit(1);\n }\n\n const pub = client ?? makeHttpPublisherClient();\n const rows = await pub.sourcesList();\n const source = rows.find((r) => r.url === remoteUrl);\n if (!source) {\n logErr(`Library \"${name}\" is not registered in the store — nothing to yank.`);\n process.exit(1);\n }\n\n const targetName = opts.asset ? bareName(opts.asset) : undefined;\n const candidates = (await pub.sourceCandidates(source.id)).filter(\n (c) => c.published && (!targetName || c.name === targetName),\n );\n if (candidates.length === 0) {\n logInfo(\"No published assets matched — nothing to yank.\");\n return;\n }\n\n const yanked: string[] = [];\n for (const c of candidates) {\n try {\n await pub.assetUnpublish(c.id);\n yanked.push(`${c.kind}:${c.name}`);\n } catch (err) {\n logErr(\n `Failed to yank ${c.kind}:${c.name}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n logOk(`Yanked ${yanked.length} asset(s):`);\n for (const r of yanked) logInfo(` ${r}`);\n } finally {\n close();\n }\n}\n"]}