@skaile/workspaces 3.17.0 → 3.19.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 (273) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-FQT6GH24.js → asset-feeds-OO3NIRVI.js} +7 -7
  4. package/dist/{asset-feeds-FQT6GH24.js.map → asset-feeds-OO3NIRVI.js.map} +1 -1
  5. package/dist/asset-manager/catalog-deployer.js +3 -3
  6. package/dist/asset-manager/index.js +6 -6
  7. package/dist/asset-manager/installer.js +4 -4
  8. package/dist/bridge/codex-app-server.js +2 -203
  9. package/dist/bridge/codex-app-server.js.map +1 -1
  10. package/dist/bridge/drivers/claude-sdk.js +5 -5
  11. package/dist/bridge/drivers/codex.js +1238 -6
  12. package/dist/bridge/drivers/codex.js.map +1 -1
  13. package/dist/bridge/drivers/continue.js +2 -2
  14. package/dist/bridge/drivers/echo.js +2 -2
  15. package/dist/bridge/drivers/gemini.js +3 -3
  16. package/dist/bridge/drivers/goose.js +2 -2
  17. package/dist/bridge/drivers/omp.js +1 -1
  18. package/dist/bridge/drivers/opencode.js +2 -2
  19. package/dist/bridge/drivers/qwen.js +3 -3
  20. package/dist/bridge/index.js +7 -6
  21. package/dist/bridge/src/capability-dispatch.d.ts +1 -1
  22. package/dist/bridge/src/capability-dispatch.d.ts.map +1 -1
  23. package/dist/bridge/src/codex/credentials.d.ts +12 -0
  24. package/dist/bridge/src/codex/credentials.d.ts.map +1 -0
  25. package/dist/bridge/src/codex/inputs.d.ts +8 -0
  26. package/dist/bridge/src/codex/inputs.d.ts.map +1 -0
  27. package/dist/bridge/src/codex/instance-state.d.ts +16 -0
  28. package/dist/bridge/src/codex/instance-state.d.ts.map +1 -0
  29. package/dist/bridge/src/codex/managed-driver.d.ts +73 -0
  30. package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -0
  31. package/dist/bridge/src/codex/native-approvals.d.ts +22 -0
  32. package/dist/bridge/src/codex/native-approvals.d.ts.map +1 -0
  33. package/dist/bridge/src/codex/native-mcp-approval.d.ts +13 -0
  34. package/dist/bridge/src/codex/native-mcp-approval.d.ts.map +1 -0
  35. package/dist/bridge/src/codex/native-policy.d.ts +38 -0
  36. package/dist/bridge/src/codex/native-policy.d.ts.map +1 -0
  37. package/dist/bridge/src/codex/native-protocol.generated.d.ts +291 -201
  38. package/dist/bridge/src/codex/native-protocol.generated.d.ts.map +1 -1
  39. package/dist/bridge/src/codex/native-state.d.ts +7 -0
  40. package/dist/bridge/src/codex/native-state.d.ts.map +1 -0
  41. package/dist/bridge/src/codex/questions.d.ts +19 -0
  42. package/dist/bridge/src/codex/questions.d.ts.map +1 -0
  43. package/dist/bridge/src/codex-app-server.d.ts +8 -1
  44. package/dist/bridge/src/codex-app-server.d.ts.map +1 -1
  45. package/dist/bridge/src/drivers/codex.d.ts +9 -1
  46. package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
  47. package/dist/bridge/src/index.d.ts +1 -0
  48. package/dist/bridge/src/index.d.ts.map +1 -1
  49. package/dist/bridge/src/normalizer.d.ts.map +1 -1
  50. package/dist/bridge/src/runtime.d.ts +3 -2
  51. package/dist/bridge/src/runtime.d.ts.map +1 -1
  52. package/dist/bridge/src/types.d.ts +83 -4
  53. package/dist/bridge/src/types.d.ts.map +1 -1
  54. package/dist/{chunk-BCOGOM6F.js → chunk-23L3P7IB.js} +4 -4
  55. package/dist/{chunk-BCOGOM6F.js.map → chunk-23L3P7IB.js.map} +1 -1
  56. package/dist/{chunk-NC5YXVZF.js → chunk-2FDKUKDE.js} +3 -3
  57. package/dist/{chunk-NC5YXVZF.js.map → chunk-2FDKUKDE.js.map} +1 -1
  58. package/dist/{chunk-CMGYUF5P.js → chunk-34RUVLL6.js} +7 -7
  59. package/dist/{chunk-CMGYUF5P.js.map → chunk-34RUVLL6.js.map} +1 -1
  60. package/dist/{chunk-EXT2LNST.js → chunk-3BOWST5G.js} +125 -37
  61. package/dist/chunk-3BOWST5G.js.map +1 -0
  62. package/dist/{chunk-BUKPS4YL.js → chunk-4JDCKPTM.js} +2 -2
  63. package/dist/{chunk-BUKPS4YL.js.map → chunk-4JDCKPTM.js.map} +1 -1
  64. package/dist/{chunk-5KSIVLOX.js → chunk-5T7Y3AZU.js} +3 -3
  65. package/dist/{chunk-5KSIVLOX.js.map → chunk-5T7Y3AZU.js.map} +1 -1
  66. package/dist/{chunk-HEKLK4NG.js → chunk-5Y4RBNT2.js} +6 -6
  67. package/dist/{chunk-HEKLK4NG.js.map → chunk-5Y4RBNT2.js.map} +1 -1
  68. package/dist/{chunk-PYX4WZLJ.js → chunk-7ECAUWFU.js} +9 -9
  69. package/dist/{chunk-PYX4WZLJ.js.map → chunk-7ECAUWFU.js.map} +1 -1
  70. package/dist/{chunk-QFYEDM63.js → chunk-7J4W54DV.js} +5 -5
  71. package/dist/{chunk-QFYEDM63.js.map → chunk-7J4W54DV.js.map} +1 -1
  72. package/dist/{chunk-RRVQAE5D.js → chunk-7ZO3MUP3.js} +6 -5
  73. package/dist/chunk-7ZO3MUP3.js.map +1 -0
  74. package/dist/{chunk-HY6CIKFH.js → chunk-CP62G5PK.js} +8 -7
  75. package/dist/chunk-CP62G5PK.js.map +1 -0
  76. package/dist/{chunk-OIDFK7SG.js → chunk-DCG4UWJM.js} +3 -3
  77. package/dist/{chunk-OIDFK7SG.js.map → chunk-DCG4UWJM.js.map} +1 -1
  78. package/dist/{chunk-RTM4SFLA.js → chunk-GMKNGIIB.js} +7 -4
  79. package/dist/chunk-GMKNGIIB.js.map +1 -0
  80. package/dist/{chunk-CIPK5JMJ.js → chunk-H662SXKS.js} +4 -4
  81. package/dist/{chunk-CIPK5JMJ.js.map → chunk-H662SXKS.js.map} +1 -1
  82. package/dist/{chunk-VT4MPCRK.js → chunk-HFL3PYJ7.js} +3 -3
  83. package/dist/{chunk-VT4MPCRK.js.map → chunk-HFL3PYJ7.js.map} +1 -1
  84. package/dist/{chunk-NMAICJUA.js → chunk-IST2V7RU.js} +3 -3
  85. package/dist/{chunk-NMAICJUA.js.map → chunk-IST2V7RU.js.map} +1 -1
  86. package/dist/{chunk-ZNCZ7RUO.js → chunk-JVFZ5R7L.js} +3 -3
  87. package/dist/{chunk-ZNCZ7RUO.js.map → chunk-JVFZ5R7L.js.map} +1 -1
  88. package/dist/{chunk-FRER2PEN.js → chunk-KB2GC6YY.js} +16 -3
  89. package/dist/chunk-KB2GC6YY.js.map +1 -0
  90. package/dist/chunk-LOO5CB5M.js +12 -0
  91. package/dist/chunk-LOO5CB5M.js.map +1 -0
  92. package/dist/{chunk-AL6BU3SP.js → chunk-OJ4N4T4H.js} +12 -4
  93. package/dist/chunk-OJ4N4T4H.js.map +1 -0
  94. package/dist/{chunk-X7FJ3ES3.js → chunk-OLRKNOO2.js} +4 -4
  95. package/dist/{chunk-X7FJ3ES3.js.map → chunk-OLRKNOO2.js.map} +1 -1
  96. package/dist/chunk-PHBYB4XT.js +247 -0
  97. package/dist/chunk-PHBYB4XT.js.map +1 -0
  98. package/dist/{chunk-EO7IJY3Q.js → chunk-PWBURVRH.js} +3 -3
  99. package/dist/{chunk-EO7IJY3Q.js.map → chunk-PWBURVRH.js.map} +1 -1
  100. package/dist/chunk-QEZPFJX3.js +254 -0
  101. package/dist/chunk-QEZPFJX3.js.map +1 -0
  102. package/dist/{chunk-C4AP3XZB.js → chunk-QG2ZXU5W.js} +4 -4
  103. package/dist/{chunk-C4AP3XZB.js.map → chunk-QG2ZXU5W.js.map} +1 -1
  104. package/dist/{chunk-OZ7UNMTK.js → chunk-RPVTPVGX.js} +7 -5
  105. package/dist/chunk-RPVTPVGX.js.map +1 -0
  106. package/dist/{chunk-S4UA244H.js → chunk-S635WMXH.js} +4 -4
  107. package/dist/{chunk-S4UA244H.js.map → chunk-S635WMXH.js.map} +1 -1
  108. package/dist/{chunk-2XGFQKNJ.js → chunk-SBDTLR3Q.js} +2 -2
  109. package/dist/{chunk-2XGFQKNJ.js.map → chunk-SBDTLR3Q.js.map} +1 -1
  110. package/dist/{chunk-BQMRUH7J.js → chunk-SFCVAEJ5.js} +4 -4
  111. package/dist/{chunk-BQMRUH7J.js.map → chunk-SFCVAEJ5.js.map} +1 -1
  112. package/dist/{chunk-KCI7DAKE.js → chunk-SZ3HIMSX.js} +988 -238
  113. package/dist/chunk-SZ3HIMSX.js.map +1 -0
  114. package/dist/chunk-T3YLZQS4.js +336 -0
  115. package/dist/chunk-T3YLZQS4.js.map +1 -0
  116. package/dist/{chunk-PBRMY64S.js → chunk-WB4EWSDR.js} +31 -9
  117. package/dist/chunk-WB4EWSDR.js.map +1 -0
  118. package/dist/{chunk-SUPIVTLX.js → chunk-XL45U3C5.js} +3 -3
  119. package/dist/{chunk-SUPIVTLX.js.map → chunk-XL45U3C5.js.map} +1 -1
  120. package/dist/{chunk-AXEOG4B5.js → chunk-YCMHWNZA.js} +3 -3
  121. package/dist/{chunk-AXEOG4B5.js.map → chunk-YCMHWNZA.js.map} +1 -1
  122. package/dist/{chunk-SWUVULBU.js → chunk-YLSMYOHN.js} +7 -7
  123. package/dist/{chunk-SWUVULBU.js.map → chunk-YLSMYOHN.js.map} +1 -1
  124. package/dist/{chunk-NIQPSQFN.js → chunk-YWGL52GT.js} +4 -4
  125. package/dist/{chunk-NIQPSQFN.js.map → chunk-YWGL52GT.js.map} +1 -1
  126. package/dist/cli/index.js +75 -53
  127. package/dist/cli/index.js.map +1 -1
  128. package/dist/cli/src/commands/serve.d.ts.map +1 -1
  129. package/dist/client/index.js +1 -1
  130. package/dist/client/src/client.d.ts +3 -2
  131. package/dist/client/src/client.d.ts.map +1 -1
  132. package/dist/connectors/config.js +4 -4
  133. package/dist/connectors/index.js +12 -11
  134. package/dist/connectors/src/connector-prompt.d.ts +11 -0
  135. package/dist/connectors/src/connector-prompt.d.ts.map +1 -1
  136. package/dist/core/index.js +3 -3
  137. package/dist/core/runtime-assets.js +2 -2
  138. package/dist/core/src/workspace-config.d.ts.map +1 -1
  139. package/dist/core/workspace-config.js +1 -1
  140. package/dist/deploy/index.js +3 -3
  141. package/dist/{ensure-sources-4GBXK6UR.js → ensure-sources-PR7YN3HV.js} +9 -9
  142. package/dist/{ensure-sources-4GBXK6UR.js.map → ensure-sources-PR7YN3HV.js.map} +1 -1
  143. package/dist/factory-assets/connectors/box.js +12 -11
  144. package/dist/factory-assets/connectors/deploy.js +12 -11
  145. package/dist/factory-assets/connectors/devserver.js +12 -11
  146. package/dist/factory-assets/connectors/flow/CONNECTOR.md +4 -5
  147. package/dist/factory-assets/connectors/flow/adapter.d.ts +8 -0
  148. package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
  149. package/dist/factory-assets/connectors/flow/adapter.js +12 -11
  150. package/dist/factory-assets/connectors/flow/contract/index.d.ts +1 -1
  151. package/dist/factory-assets/connectors/flow/contract/index.d.ts.map +1 -1
  152. package/dist/factory-assets/connectors/flow/contract/schema.d.ts +50 -17
  153. package/dist/factory-assets/connectors/flow/contract/schema.d.ts.map +1 -1
  154. package/dist/factory-assets/connectors/flow/contract.js +3 -3
  155. package/dist/factory-assets/connectors/flow/engine/index.d.ts +1 -0
  156. package/dist/factory-assets/connectors/flow/engine/index.d.ts.map +1 -1
  157. package/dist/factory-assets/connectors/flow/engine.js +5 -5
  158. package/dist/factory-assets/connectors/flow/run-flow.js +13 -12
  159. package/dist/factory-assets/connectors/flow/subprompt-runner.d.ts +10 -1
  160. package/dist/factory-assets/connectors/flow/subprompt-runner.d.ts.map +1 -1
  161. package/dist/factory-assets/connectors/flow.js +12 -11
  162. package/dist/factory-assets/connectors/git.js +12 -11
  163. package/dist/factory-assets/connectors/gmail.js +12 -11
  164. package/dist/factory-assets/connectors/googledrive.js +12 -11
  165. package/dist/factory-assets/connectors/local.js +12 -11
  166. package/dist/factory-assets/connectors/mattermost.js +12 -11
  167. package/dist/factory-assets/connectors/memory.js +12 -11
  168. package/dist/factory-assets/connectors/minio.js +12 -11
  169. package/dist/factory-assets/connectors/postgres.js +12 -11
  170. package/dist/factory-assets/connectors/s3.js +12 -11
  171. package/dist/factory-assets/connectors/sharepoint.js +12 -11
  172. package/dist/factory-assets/connectors/sqlite.js +12 -11
  173. package/dist/factory-assets/connectors/static-server.js +12 -11
  174. package/dist/factory-assets/connectors/tunnel.js +12 -11
  175. package/dist/factory-assets/connectors/webdav.js +12 -11
  176. package/dist/factory-assets/connectors/xstate-store.js +12 -11
  177. package/dist/factory-assets/connectors/xstate.js +12 -11
  178. package/dist/{flows-2SUFOVVO.js → flows-COBS26MK.js} +6 -6
  179. package/dist/{flows-2SUFOVVO.js.map → flows-COBS26MK.js.map} +1 -1
  180. package/dist/{helpers-26LW4IXY.js → helpers-TFSZSWT5.js} +9 -9
  181. package/dist/{helpers-26LW4IXY.js.map → helpers-TFSZSWT5.js.map} +1 -1
  182. package/dist/library/index.js +4 -4
  183. package/dist/library/install.js +3 -3
  184. package/dist/{library-publish-IYGHOPEK.js → library-publish-WVIUUYG3.js} +14 -14
  185. package/dist/{library-publish-IYGHOPEK.js.map → library-publish-WVIUUYG3.js.map} +1 -1
  186. package/dist/{open-library-HH5LST7Z.js → open-library-2AWZGIWE.js} +12 -12
  187. package/dist/{open-library-HH5LST7Z.js.map → open-library-2AWZGIWE.js.map} +1 -1
  188. package/dist/{paths-4APA2PKT.js → paths-CZPCCBYX.js} +6 -6
  189. package/dist/{paths-4APA2PKT.js.map → paths-CZPCCBYX.js.map} +1 -1
  190. package/dist/{plugin-store-JQAIKR3R.js → plugin-store-ZEIBSNTO.js} +5 -5
  191. package/dist/{plugin-store-JQAIKR3R.js.map → plugin-store-ZEIBSNTO.js.map} +1 -1
  192. package/dist/{project-U5QRUCBN.js → project-XZDKNIRG.js} +10 -10
  193. package/dist/{project-U5QRUCBN.js.map → project-XZDKNIRG.js.map} +1 -1
  194. package/dist/resolver/index.js +3 -3
  195. package/dist/runner/index.js +25 -16
  196. package/dist/runner/src/capability-registry.d.ts +4 -0
  197. package/dist/runner/src/capability-registry.d.ts.map +1 -1
  198. package/dist/runner/src/codex-init.d.ts +2 -11
  199. package/dist/runner/src/codex-init.d.ts.map +1 -1
  200. package/dist/runner/src/codex-resource-tools.d.ts +16 -0
  201. package/dist/runner/src/codex-resource-tools.d.ts.map +1 -0
  202. package/dist/runner/src/codex-tools.d.ts +12 -0
  203. package/dist/runner/src/codex-tools.d.ts.map +1 -0
  204. package/dist/runner/src/define-capability.d.ts +2 -0
  205. package/dist/runner/src/define-capability.d.ts.map +1 -1
  206. package/dist/runner/src/external-mcp.d.ts +8 -3
  207. package/dist/runner/src/external-mcp.d.ts.map +1 -1
  208. package/dist/runner/src/index.d.ts +2 -0
  209. package/dist/runner/src/index.d.ts.map +1 -1
  210. package/dist/runner/src/managed-codex-bootstrap.d.ts +54 -0
  211. package/dist/runner/src/managed-codex-bootstrap.d.ts.map +1 -0
  212. package/dist/runner/src/resources.d.ts +1 -0
  213. package/dist/runner/src/resources.d.ts.map +1 -1
  214. package/dist/runner/src/serve.d.ts +5 -0
  215. package/dist/runner/src/serve.d.ts.map +1 -1
  216. package/dist/runner/src/session-builder.d.ts +18 -1
  217. package/dist/runner/src/session-builder.d.ts.map +1 -1
  218. package/dist/sdk/asset-manager.js +6 -6
  219. package/dist/sdk/bridge.js +7 -6
  220. package/dist/sdk/client.js +1 -1
  221. package/dist/sdk/core.js +3 -3
  222. package/dist/sdk/flow.js +5 -5
  223. package/dist/sdk/index.js +26 -17
  224. package/dist/sdk/index.js.map +1 -1
  225. package/dist/sdk/resolver.js +3 -3
  226. package/dist/sdk/runner.js +25 -16
  227. package/dist/sdk/session.js +2 -2
  228. package/dist/sdk/store.js +1 -1
  229. package/dist/sdk/types.js +1 -1
  230. package/dist/session/index.js +2 -2
  231. package/dist/{setup-XKTBHRWM.js → setup-J34TR5IR.js} +9 -8
  232. package/dist/setup-J34TR5IR.js.map +1 -0
  233. package/dist/{skills-Q7PJVB3W.js → skills-LG6IQSSN.js} +5 -5
  234. package/dist/{skills-Q7PJVB3W.js.map → skills-LG6IQSSN.js.map} +1 -1
  235. package/dist/{source-ODR4IU6R.js → source-QYINHHUP.js} +13 -13
  236. package/dist/{source-ODR4IU6R.js.map → source-QYINHHUP.js.map} +1 -1
  237. package/dist/{source-manifest-publish-WCJY3GAM.js → source-manifest-publish-3RBW5E2O.js} +15 -15
  238. package/dist/{source-manifest-publish-WCJY3GAM.js.map → source-manifest-publish-3RBW5E2O.js.map} +1 -1
  239. package/dist/store/index.js +1 -1
  240. package/dist/store/react.js +1 -1
  241. package/dist/store/react.js.map +1 -1
  242. package/dist/store/src/react.d.ts +1 -1
  243. package/dist/store/src/react.d.ts.map +1 -1
  244. package/dist/store/src/store.d.ts +2 -1
  245. package/dist/store/src/store.d.ts.map +1 -1
  246. package/dist/tui/index.js +25 -16
  247. package/dist/tui/index.js.map +1 -1
  248. package/dist/types/index.js +1 -1
  249. package/dist/types/src/events.d.ts +14 -1
  250. package/dist/types/src/events.d.ts.map +1 -1
  251. package/dist/types/src/index.d.ts +2 -2
  252. package/dist/types/src/index.d.ts.map +1 -1
  253. package/dist/types/src/protocol.d.ts +18 -0
  254. package/dist/types/src/protocol.d.ts.map +1 -1
  255. package/dist/types/src/runtime.d.ts +3 -1
  256. package/dist/types/src/runtime.d.ts.map +1 -1
  257. package/dist/types/src/version.d.ts +7 -1
  258. package/dist/types/src/version.d.ts.map +1 -1
  259. package/dist/workspace-plugin/adapters/mcp.js +9 -255
  260. package/dist/workspace-plugin/adapters/mcp.js.map +1 -1
  261. package/dist/workspace-plugin/adapters/omp.js +7 -7
  262. package/dist/workspace-plugin/index.js +1 -1
  263. package/package.json +4 -1
  264. package/dist/chunk-AL6BU3SP.js.map +0 -1
  265. package/dist/chunk-EXT2LNST.js.map +0 -1
  266. package/dist/chunk-FRER2PEN.js.map +0 -1
  267. package/dist/chunk-HY6CIKFH.js.map +0 -1
  268. package/dist/chunk-KCI7DAKE.js.map +0 -1
  269. package/dist/chunk-OZ7UNMTK.js.map +0 -1
  270. package/dist/chunk-PBRMY64S.js.map +0 -1
  271. package/dist/chunk-RRVQAE5D.js.map +0 -1
  272. package/dist/chunk-RTM4SFLA.js.map +0 -1
  273. package/dist/setup-XKTBHRWM.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../cli/src/store-auth.ts","../cli/src/store-client.ts"],"names":["readFileSync"],"mappings":"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","file":"chunk-SUPIVTLX.js","sourcesContent":["/**\n * Keycloak Device Authorization Grant (RFC 8628) for the store CLI: a public\n * device-flow client (`skaile-store-cli`) issues a plain realm JWT the store's\n * `AuthGuard` accepts — a CLI can't use the storefront's confidential browser\n * client. Tokens cache at `~/.skaile/auth.json` (0600, shared with `store/cli`);\n * `getAccessToken` refreshes transparently. All targets are env-overridable.\n *\n * @docLink cli/dev-guide#store-auth\n */\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { chmodSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * A PKCE (RFC 7636) `code_verifier` + its S256 `code_challenge`. Keycloak\n * enforces PKCE on the `skaile-store-cli` device flow (the device-authorization\n * request 400s with \"Missing parameter: code_challenge_method\" otherwise), so\n * every `deviceLogin` mints a fresh pair: the challenge goes on the device-auth\n * request, the verifier on the matching token poll. `base64url` (no padding)\n * per the spec.\n */\nfunction makePkcePair(): { verifier: string; challenge: string } {\n const verifier = randomBytes(32).toString(\"base64url\");\n const challenge = createHash(\"sha256\").update(verifier).digest(\"base64url\");\n return { verifier, challenge };\n}\n\n/** Resolved auth targets — every field has a prod default, all env-overridable. */\nexport interface StoreAuthConfig {\n keycloakUrl: string;\n realm: string;\n clientId: string;\n authFile: string;\n}\n\nfunction trimTrailingSlash(url: string): string {\n return url.replace(/\\/+$/, \"\");\n}\n\n/**\n * Load the auth config. Defaults target the production store\n * (`auth.skaile.ai`, realm `skaile-store`, public client `skaile-store-cli`);\n * override with `SKAILE_KEYCLOAK_URL` / `SKAILE_STORE_REALM` /\n * `SKAILE_STORE_CLI_CLIENT` / `SKAILE_AUTH_FILE` for dev or a preview deploy.\n */\nexport function loadStoreAuthConfig(): StoreAuthConfig {\n const home = process.env.SKAILE_HOME ?? join(homedir(), \".skaile\");\n return {\n keycloakUrl: trimTrailingSlash(process.env.SKAILE_KEYCLOAK_URL ?? \"https://auth.skaile.ai\"),\n realm: process.env.SKAILE_STORE_REALM ?? \"skaile-store\",\n clientId: process.env.SKAILE_STORE_CLI_CLIENT ?? \"skaile-store-cli\",\n authFile: process.env.SKAILE_AUTH_FILE ?? join(home, \"auth.json\"),\n };\n}\n\n/** Keycloak OIDC endpoints derived from the realm base. */\nfunction oidc(config: StoreAuthConfig): { deviceAuth: string; token: string } {\n const base = `${config.keycloakUrl}/realms/${config.realm}/protocol/openid-connect`;\n return { deviceAuth: `${base}/auth/device`, token: `${base}/token` };\n}\n\nexport interface StoredAuth {\n access_token: string;\n refresh_token?: string;\n /** Epoch ms when the access token expires (with a safety margin already applied). */\n expires_at: number;\n}\n\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n error?: string;\n error_description?: string;\n}\n\ninterface DeviceAuthResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete?: string;\n interval?: number;\n expires_in: number;\n}\n\n/** Refresh this many ms before real expiry so an in-flight call never 401s. */\nconst EXPIRY_MARGIN_MS = 30_000;\n\n/** Injectable seams so the poll loop is unit-testable without real time or network. */\nexport interface AuthDeps {\n fetchImpl?: typeof fetch;\n sleep?: (ms: number) => Promise<void>;\n /** Called once with the verification URL + user code (default: write to stderr). */\n onPrompt?: (url: string, userCode: string) => void;\n}\n\nfunction readAuth(config: StoreAuthConfig): StoredAuth | null {\n try {\n const parsed = JSON.parse(readFileSync(config.authFile, \"utf-8\"));\n // Reject a corrupt / hand-edited file rather than treat it as a session.\n if (parsed && typeof parsed.access_token === \"string\") return parsed as StoredAuth;\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * The caller's store identity, decoded LOCALLY from the cached token's JWT\n * payload (no network, no signature check — this is an author-side hint, not an\n * authorization decision). Returns `null` when not signed in or the token is\n * unreadable. `githubLogin` is the verified GitHub handle (the preferred\n * publisher namespace); `username` is the Keycloak `preferred_username`.\n */\nexport function getStoreIdentity(\n config: StoreAuthConfig = loadStoreAuthConfig(),\n): { username?: string; githubLogin?: string } | null {\n const auth = readAuth(config);\n if (!auth) return null;\n try {\n const payload = auth.access_token.split(\".\")[1];\n const json = JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf-8\"));\n const username = typeof json.preferred_username === \"string\" ? json.preferred_username : undefined;\n const githubLogin = typeof json.github_login === \"string\" ? json.github_login : undefined;\n return username || githubLogin ? { username, githubLogin } : null;\n } catch {\n return null;\n }\n}\n\nfunction writeAuth(config: StoreAuthConfig, auth: StoredAuth): void {\n mkdirSync(dirname(config.authFile), { recursive: true });\n writeFileSync(config.authFile, JSON.stringify(auth, null, 2), { mode: 0o600 });\n chmodSync(config.authFile, 0o600);\n}\n\n/** Remove the cached session (sign out). */\nexport function logout(config: StoreAuthConfig): void {\n try {\n rmSync(config.authFile);\n } catch {\n // already absent — nothing to do\n }\n}\n\n/** True when a cached, well-formed session exists (validity/refresh resolved on use). */\nexport function hasStoredAuth(config: StoreAuthConfig): boolean {\n return readAuth(config) !== null;\n}\n\nfunction tokenToStored(token: TokenResponse): StoredAuth {\n return {\n access_token: token.access_token,\n refresh_token: token.refresh_token,\n expires_at: Date.now() + (token.expires_in ?? 300) * 1000 - EXPIRY_MARGIN_MS,\n };\n}\n\nconst defaultSleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\nfunction defaultPrompt(url: string, userCode: string): void {\n process.stderr.write(\n `\\nTo sign in, open:\\n\\n ${url}\\n\\nand enter the code: ${userCode}\\n\\nWaiting for approval…\\n`,\n );\n}\n\n/**\n * Run the device flow to completion, persisting tokens on success. Prints the\n * verification URL + user code for the operator to approve in a browser.\n */\nexport async function deviceLogin(\n config: StoreAuthConfig,\n deps: AuthDeps = {},\n): Promise<StoredAuth> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const sleep = deps.sleep ?? defaultSleep;\n const onPrompt = deps.onPrompt ?? defaultPrompt;\n const endpoints = oidc(config);\n const pkce = makePkcePair();\n\n const deviceRes = await fetchImpl(endpoints.deviceAuth, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n client_id: config.clientId,\n scope: \"openid profile\",\n code_challenge: pkce.challenge,\n code_challenge_method: \"S256\",\n }),\n });\n if (!deviceRes.ok) {\n throw new Error(\n `Device authorization request failed (${deviceRes.status}): ${await deviceRes.text()}`,\n );\n }\n const device = (await deviceRes.json()) as DeviceAuthResponse;\n\n onPrompt(device.verification_uri_complete ?? device.verification_uri, device.user_code);\n\n const intervalMs = (device.interval ?? 5) * 1000;\n const deadline = Date.now() + device.expires_in * 1000;\n let waitMs = intervalMs;\n\n while (Date.now() < deadline) {\n await sleep(waitMs);\n const tokenRes = await fetchImpl(endpoints.token, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n device_code: device.device_code,\n client_id: config.clientId,\n code_verifier: pkce.verifier,\n }),\n });\n const token = (await tokenRes.json()) as TokenResponse;\n if (tokenRes.ok) {\n const stored = tokenToStored(token);\n writeAuth(config, stored);\n return stored;\n }\n // RFC 8628 §3.5 pending / slow-down handling.\n if (token.error === \"authorization_pending\") continue;\n if (token.error === \"slow_down\") {\n waitMs += 5_000;\n continue;\n }\n throw new Error(`Sign-in failed: ${token.error_description ?? token.error ?? \"unknown error\"}`);\n }\n throw new Error(\"Sign-in timed out before approval.\");\n}\n\n/** Exchange a refresh token for a fresh access token; persist on success. */\nasync function refresh(\n config: StoreAuthConfig,\n refreshToken: string,\n fetchImpl: typeof fetch,\n): Promise<StoredAuth> {\n const res = await fetchImpl(oidc(config).token, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: config.clientId,\n }),\n });\n const token = (await res.json()) as TokenResponse;\n if (!res.ok) {\n throw new Error(\n `Token refresh failed: ${token.error_description ?? token.error ?? res.status}`,\n );\n }\n const stored = tokenToStored(token);\n writeAuth(config, stored);\n return stored;\n}\n\n/**\n * Return a valid access token, refreshing if it is expired (or about to). Throws\n * a clear \"run `skaile store login`\" error when there is no usable session.\n */\nexport async function getAccessToken(\n config: StoreAuthConfig,\n deps: AuthDeps = {},\n): Promise<string> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const auth = readAuth(config);\n if (!auth) throw new Error(\"Not signed in. Run `skaile store login` first.\");\n if (Date.now() < auth.expires_at) return auth.access_token;\n if (!auth.refresh_token) throw new Error(\"Session expired. Run `skaile store login` again.\");\n try {\n return (await refresh(config, auth.refresh_token, fetchImpl)).access_token;\n } catch {\n throw new Error(\"Session expired and refresh failed. Run `skaile store login` again.\");\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\nimport { type AuthDeps, getAccessToken, hasStoredAuth, loadStoreAuthConfig } from \"./store-auth.ts\";\n\n/**\n * Connection configuration for the AI Asset Store API. `jwt` is normally left\n * null here and filled per-call by the caller from {@link getStoreToken} (the\n * device-flow session); it stays on the type for the `{ ...config, jwt }` spread.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n}\n\n/**\n * Read the store API base URL (settings `storeUrl` → `SKAILE_STORE_URL` →\n * default). Auth is not read here — it lives in the device-flow session; see\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function getStoreConfig(): StoreConfig {\n const settingsPath = globalSettingsPath();\n let settings: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n settings = mapLegacyFields(JSON.parse(readFileSync(settingsPath, \"utf-8\")));\n } catch {\n settings = {};\n }\n }\n return {\n url: settings.storeUrl ?? process.env.SKAILE_STORE_URL ?? \"https://api.skaile.store\",\n jwt: null,\n };\n}\n\n/**\n * Return a valid store access token (Keycloak device-flow session, refreshed if\n * needed). Throws a \"run `skaile store login`\" error when there is no session.\n * This is the auth source for every `/api/v1/*` publisher call.\n */\nexport function getStoreToken(deps?: AuthDeps): Promise<string> {\n return getAccessToken(loadStoreAuthConfig(), deps);\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API.\n *\n * @param config - Store connection config (URL + auth token).\n * @param path - API path (e.g. `/api/assets`).\n * @param opts - Optional method, body, query params, extra headers, and\n * `timeoutMs` (default 1500). Publisher calls pass a longer timeout because\n * they trigger server-side clone/sync work.\n * @returns Parsed JSON response body.\n * @docLink cli/dev-guide#store-client\n */\nexport async function storeFetch<T = any>(\n config: StoreConfig,\n path: string,\n opts?: {\n method?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n timeoutMs?: number;\n },\n): Promise<T> {\n let url = `${config.url}${path}`;\n if (opts?.params) {\n const sp = new URLSearchParams(opts.params);\n url += `?${sp}`;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(opts?.headers ?? {}),\n };\n if (config.jwt) {\n headers.Authorization = `Bearer ${config.jwt}`;\n }\n\n const fetchOpts: RequestInit = {\n method: opts?.method ?? \"GET\",\n headers,\n };\n if (opts?.body) {\n fetchOpts.body = JSON.stringify(opts.body);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts?.timeoutMs ?? 1_500);\n try {\n const res = await fetch(url, { ...fetchOpts, signal: controller.signal });\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n // Prefer the store's human-readable `message` (e.g. \"Namespace '@x' is\n // reserved … Sign in with GitHub to claim it\") over the bare `error` code\n // (`UNPROCESSABLE_CONTENT`) — the message is the actionable part.\n const b = body as { message?: string; error?: string };\n throw new Error(b.message ?? b.error ?? `Store API error: ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Return `true` when a store session exists (a Keycloak device-flow token cached\n * at `~/.skaile/auth.json`). Validity/refresh is resolved on use via\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(): boolean {\n return hasStoredAuth(loadStoreAuthConfig());\n}\n"]}
1
+ {"version":3,"sources":["../cli/src/store-auth.ts","../cli/src/store-client.ts"],"names":["readFileSync"],"mappings":"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","file":"chunk-XL45U3C5.js","sourcesContent":["/**\n * Keycloak Device Authorization Grant (RFC 8628) for the store CLI: a public\n * device-flow client (`skaile-store-cli`) issues a plain realm JWT the store's\n * `AuthGuard` accepts — a CLI can't use the storefront's confidential browser\n * client. Tokens cache at `~/.skaile/auth.json` (0600, shared with `store/cli`);\n * `getAccessToken` refreshes transparently. All targets are env-overridable.\n *\n * @docLink cli/dev-guide#store-auth\n */\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { chmodSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * A PKCE (RFC 7636) `code_verifier` + its S256 `code_challenge`. Keycloak\n * enforces PKCE on the `skaile-store-cli` device flow (the device-authorization\n * request 400s with \"Missing parameter: code_challenge_method\" otherwise), so\n * every `deviceLogin` mints a fresh pair: the challenge goes on the device-auth\n * request, the verifier on the matching token poll. `base64url` (no padding)\n * per the spec.\n */\nfunction makePkcePair(): { verifier: string; challenge: string } {\n const verifier = randomBytes(32).toString(\"base64url\");\n const challenge = createHash(\"sha256\").update(verifier).digest(\"base64url\");\n return { verifier, challenge };\n}\n\n/** Resolved auth targets — every field has a prod default, all env-overridable. */\nexport interface StoreAuthConfig {\n keycloakUrl: string;\n realm: string;\n clientId: string;\n authFile: string;\n}\n\nfunction trimTrailingSlash(url: string): string {\n return url.replace(/\\/+$/, \"\");\n}\n\n/**\n * Load the auth config. Defaults target the production store\n * (`auth.skaile.ai`, realm `skaile-store`, public client `skaile-store-cli`);\n * override with `SKAILE_KEYCLOAK_URL` / `SKAILE_STORE_REALM` /\n * `SKAILE_STORE_CLI_CLIENT` / `SKAILE_AUTH_FILE` for dev or a preview deploy.\n */\nexport function loadStoreAuthConfig(): StoreAuthConfig {\n const home = process.env.SKAILE_HOME ?? join(homedir(), \".skaile\");\n return {\n keycloakUrl: trimTrailingSlash(process.env.SKAILE_KEYCLOAK_URL ?? \"https://auth.skaile.ai\"),\n realm: process.env.SKAILE_STORE_REALM ?? \"skaile-store\",\n clientId: process.env.SKAILE_STORE_CLI_CLIENT ?? \"skaile-store-cli\",\n authFile: process.env.SKAILE_AUTH_FILE ?? join(home, \"auth.json\"),\n };\n}\n\n/** Keycloak OIDC endpoints derived from the realm base. */\nfunction oidc(config: StoreAuthConfig): { deviceAuth: string; token: string } {\n const base = `${config.keycloakUrl}/realms/${config.realm}/protocol/openid-connect`;\n return { deviceAuth: `${base}/auth/device`, token: `${base}/token` };\n}\n\nexport interface StoredAuth {\n access_token: string;\n refresh_token?: string;\n /** Epoch ms when the access token expires (with a safety margin already applied). */\n expires_at: number;\n}\n\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n error?: string;\n error_description?: string;\n}\n\ninterface DeviceAuthResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete?: string;\n interval?: number;\n expires_in: number;\n}\n\n/** Refresh this many ms before real expiry so an in-flight call never 401s. */\nconst EXPIRY_MARGIN_MS = 30_000;\n\n/** Injectable seams so the poll loop is unit-testable without real time or network. */\nexport interface AuthDeps {\n fetchImpl?: typeof fetch;\n sleep?: (ms: number) => Promise<void>;\n /** Called once with the verification URL + user code (default: write to stderr). */\n onPrompt?: (url: string, userCode: string) => void;\n}\n\nfunction readAuth(config: StoreAuthConfig): StoredAuth | null {\n try {\n const parsed = JSON.parse(readFileSync(config.authFile, \"utf-8\"));\n // Reject a corrupt / hand-edited file rather than treat it as a session.\n if (parsed && typeof parsed.access_token === \"string\") return parsed as StoredAuth;\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * The caller's store identity, decoded LOCALLY from the cached token's JWT\n * payload (no network, no signature check — this is an author-side hint, not an\n * authorization decision). Returns `null` when not signed in or the token is\n * unreadable. `githubLogin` is the verified GitHub handle (the preferred\n * publisher namespace); `username` is the Keycloak `preferred_username`.\n */\nexport function getStoreIdentity(\n config: StoreAuthConfig = loadStoreAuthConfig(),\n): { username?: string; githubLogin?: string } | null {\n const auth = readAuth(config);\n if (!auth) return null;\n try {\n const payload = auth.access_token.split(\".\")[1];\n const json = JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf-8\"));\n const username = typeof json.preferred_username === \"string\" ? json.preferred_username : undefined;\n const githubLogin = typeof json.github_login === \"string\" ? json.github_login : undefined;\n return username || githubLogin ? { username, githubLogin } : null;\n } catch {\n return null;\n }\n}\n\nfunction writeAuth(config: StoreAuthConfig, auth: StoredAuth): void {\n mkdirSync(dirname(config.authFile), { recursive: true });\n writeFileSync(config.authFile, JSON.stringify(auth, null, 2), { mode: 0o600 });\n chmodSync(config.authFile, 0o600);\n}\n\n/** Remove the cached session (sign out). */\nexport function logout(config: StoreAuthConfig): void {\n try {\n rmSync(config.authFile);\n } catch {\n // already absent — nothing to do\n }\n}\n\n/** True when a cached, well-formed session exists (validity/refresh resolved on use). */\nexport function hasStoredAuth(config: StoreAuthConfig): boolean {\n return readAuth(config) !== null;\n}\n\nfunction tokenToStored(token: TokenResponse): StoredAuth {\n return {\n access_token: token.access_token,\n refresh_token: token.refresh_token,\n expires_at: Date.now() + (token.expires_in ?? 300) * 1000 - EXPIRY_MARGIN_MS,\n };\n}\n\nconst defaultSleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\nfunction defaultPrompt(url: string, userCode: string): void {\n process.stderr.write(\n `\\nTo sign in, open:\\n\\n ${url}\\n\\nand enter the code: ${userCode}\\n\\nWaiting for approval…\\n`,\n );\n}\n\n/**\n * Run the device flow to completion, persisting tokens on success. Prints the\n * verification URL + user code for the operator to approve in a browser.\n */\nexport async function deviceLogin(\n config: StoreAuthConfig,\n deps: AuthDeps = {},\n): Promise<StoredAuth> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const sleep = deps.sleep ?? defaultSleep;\n const onPrompt = deps.onPrompt ?? defaultPrompt;\n const endpoints = oidc(config);\n const pkce = makePkcePair();\n\n const deviceRes = await fetchImpl(endpoints.deviceAuth, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n client_id: config.clientId,\n scope: \"openid profile\",\n code_challenge: pkce.challenge,\n code_challenge_method: \"S256\",\n }),\n });\n if (!deviceRes.ok) {\n throw new Error(\n `Device authorization request failed (${deviceRes.status}): ${await deviceRes.text()}`,\n );\n }\n const device = (await deviceRes.json()) as DeviceAuthResponse;\n\n onPrompt(device.verification_uri_complete ?? device.verification_uri, device.user_code);\n\n const intervalMs = (device.interval ?? 5) * 1000;\n const deadline = Date.now() + device.expires_in * 1000;\n let waitMs = intervalMs;\n\n while (Date.now() < deadline) {\n await sleep(waitMs);\n const tokenRes = await fetchImpl(endpoints.token, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n device_code: device.device_code,\n client_id: config.clientId,\n code_verifier: pkce.verifier,\n }),\n });\n const token = (await tokenRes.json()) as TokenResponse;\n if (tokenRes.ok) {\n const stored = tokenToStored(token);\n writeAuth(config, stored);\n return stored;\n }\n // RFC 8628 §3.5 pending / slow-down handling.\n if (token.error === \"authorization_pending\") continue;\n if (token.error === \"slow_down\") {\n waitMs += 5_000;\n continue;\n }\n throw new Error(`Sign-in failed: ${token.error_description ?? token.error ?? \"unknown error\"}`);\n }\n throw new Error(\"Sign-in timed out before approval.\");\n}\n\n/** Exchange a refresh token for a fresh access token; persist on success. */\nasync function refresh(\n config: StoreAuthConfig,\n refreshToken: string,\n fetchImpl: typeof fetch,\n): Promise<StoredAuth> {\n const res = await fetchImpl(oidc(config).token, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: config.clientId,\n }),\n });\n const token = (await res.json()) as TokenResponse;\n if (!res.ok) {\n throw new Error(\n `Token refresh failed: ${token.error_description ?? token.error ?? res.status}`,\n );\n }\n const stored = tokenToStored(token);\n writeAuth(config, stored);\n return stored;\n}\n\n/**\n * Return a valid access token, refreshing if it is expired (or about to). Throws\n * a clear \"run `skaile store login`\" error when there is no usable session.\n */\nexport async function getAccessToken(\n config: StoreAuthConfig,\n deps: AuthDeps = {},\n): Promise<string> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const auth = readAuth(config);\n if (!auth) throw new Error(\"Not signed in. Run `skaile store login` first.\");\n if (Date.now() < auth.expires_at) return auth.access_token;\n if (!auth.refresh_token) throw new Error(\"Session expired. Run `skaile store login` again.\");\n try {\n return (await refresh(config, auth.refresh_token, fetchImpl)).access_token;\n } catch {\n throw new Error(\"Session expired and refresh failed. Run `skaile store login` again.\");\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\nimport { type AuthDeps, getAccessToken, hasStoredAuth, loadStoreAuthConfig } from \"./store-auth.ts\";\n\n/**\n * Connection configuration for the AI Asset Store API. `jwt` is normally left\n * null here and filled per-call by the caller from {@link getStoreToken} (the\n * device-flow session); it stays on the type for the `{ ...config, jwt }` spread.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n}\n\n/**\n * Read the store API base URL (settings `storeUrl` → `SKAILE_STORE_URL` →\n * default). Auth is not read here — it lives in the device-flow session; see\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function getStoreConfig(): StoreConfig {\n const settingsPath = globalSettingsPath();\n let settings: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n settings = mapLegacyFields(JSON.parse(readFileSync(settingsPath, \"utf-8\")));\n } catch {\n settings = {};\n }\n }\n return {\n url: settings.storeUrl ?? process.env.SKAILE_STORE_URL ?? \"https://api.skaile.store\",\n jwt: null,\n };\n}\n\n/**\n * Return a valid store access token (Keycloak device-flow session, refreshed if\n * needed). Throws a \"run `skaile store login`\" error when there is no session.\n * This is the auth source for every `/api/v1/*` publisher call.\n */\nexport function getStoreToken(deps?: AuthDeps): Promise<string> {\n return getAccessToken(loadStoreAuthConfig(), deps);\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API.\n *\n * @param config - Store connection config (URL + auth token).\n * @param path - API path (e.g. `/api/assets`).\n * @param opts - Optional method, body, query params, extra headers, and\n * `timeoutMs` (default 1500). Publisher calls pass a longer timeout because\n * they trigger server-side clone/sync work.\n * @returns Parsed JSON response body.\n * @docLink cli/dev-guide#store-client\n */\nexport async function storeFetch<T = any>(\n config: StoreConfig,\n path: string,\n opts?: {\n method?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n timeoutMs?: number;\n },\n): Promise<T> {\n let url = `${config.url}${path}`;\n if (opts?.params) {\n const sp = new URLSearchParams(opts.params);\n url += `?${sp}`;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(opts?.headers ?? {}),\n };\n if (config.jwt) {\n headers.Authorization = `Bearer ${config.jwt}`;\n }\n\n const fetchOpts: RequestInit = {\n method: opts?.method ?? \"GET\",\n headers,\n };\n if (opts?.body) {\n fetchOpts.body = JSON.stringify(opts.body);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts?.timeoutMs ?? 1_500);\n try {\n const res = await fetch(url, { ...fetchOpts, signal: controller.signal });\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n // Prefer the store's human-readable `message` (e.g. \"Namespace '@x' is\n // reserved … Sign in with GitHub to claim it\") over the bare `error` code\n // (`UNPROCESSABLE_CONTENT`) — the message is the actionable part.\n const b = body as { message?: string; error?: string };\n throw new Error(b.message ?? b.error ?? `Store API error: ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Return `true` when a store session exists (a Keycloak device-flow token cached\n * at `~/.skaile/auth.json`). Validity/refresh is resolved on use via\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(): boolean {\n return hasStoredAuth(loadStoreAuthConfig());\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { InputSchema } from './chunk-HY6CIKFH.js';
1
+ import { InputSchema } from './chunk-CP62G5PK.js';
2
2
 
3
3
  // factory-assets/connectors/flow/contract/input-schema.ts
4
4
  var INPUT_SCHEMA_SHAPES_HINT = "{ kind: 'text', multiline? }, { kind: 'choice', options: [{ id, label, description? }], multiple? }, { kind: 'form', fields: [{ id, label, type: text|textarea|number|choice|file|date|boolean, required?, options?, accept? }] }, or { kind: 'file', accept?, maxSize?, multiple? }";
@@ -189,5 +189,5 @@ function describe(value) {
189
189
  }
190
190
 
191
191
  export { INPUT_SCHEMA_SHAPES_HINT, coerceInputSchema };
192
- //# sourceMappingURL=chunk-AXEOG4B5.js.map
193
- //# sourceMappingURL=chunk-AXEOG4B5.js.map
192
+ //# sourceMappingURL=chunk-YCMHWNZA.js.map
193
+ //# sourceMappingURL=chunk-YCMHWNZA.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../factory-assets/connectors/flow/contract/input-schema.ts"],"names":[],"mappings":"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","file":"chunk-AXEOG4B5.js","sourcesContent":["/**\n * Coercion of an agent-supplied `request_input` schema onto the flow contract.\n *\n * `request_input` used to cast whatever the agent passed straight into\n * `InputSchema`, so a choice gate could be persisted with option ids no host\n * could render — a run parked forever on a question no human could answer.\n * This module tolerates the shapes agents actually reach for (a bare string per\n * option, an option with a label and no id) and refuses the rest, because a\n * refusal the agent can read and retry beats a stored gate nobody can answer.\n *\n * Exported because hosts normalize the same payloads when they read a stored\n * gate; one shared rule is what keeps the write and read sides in agreement.\n */\n\nimport type { InputSchema } from \"@skaile/workspaces/types\";\nimport type * as z from \"zod\";\nimport { InputSchema as InputSchemaContract } from \"./schema.js\";\n\n/**\n * The shapes `request_input` accepts, phrased for an agent retrying a refused\n * call. Every optional key the contract admits is listed, because validation is\n * strict: an agent refused for one unknown key would otherwise read a key it\n * omitted here as illegal too.\n */\nexport const INPUT_SCHEMA_SHAPES_HINT =\n \"{ kind: 'text', multiline? }, { kind: 'choice', options: [{ id, label, description? }], multiple? }, { kind: 'form', fields: [{ id, label, type: text|textarea|number|choice|file|date|boolean, required?, options?, accept? }] }, or { kind: 'file', accept?, maxSize?, multiple? }\";\n\n/**\n * Outcome of {@link coerceInputSchema}: either a schema in the contract shape,\n * or the reasons it was refused — one entry per problem, each naming its path,\n * closed by a final entry naming the accepted shapes. The hint travels with the\n * issues so every caller's refusal is actionable without re-appending it.\n */\nexport type InputSchemaCoercion =\n | { ok: true; schema: InputSchema }\n | { ok: false; issues: string[] };\n\nconst KNOWN_KINDS = [\"text\", \"choice\", \"form\", \"file\"] as const;\n\n/** A coerced option or form field, and whether its id was derived from its label. */\ntype Prepared = { entry: Record<string, unknown>; derivedId: boolean };\n\n/**\n * Brings an untrusted `request_input` schema into the `InputSchema` contract.\n *\n * Tolerated: a JSON string wrapper, a choice option given as a bare string, and\n * an option or form field whose id is missing but whose label can supply one.\n * Refused: an unknown `kind`, an option or field that carries no usable label, a\n * duplicate explicit id, an id or label of the wrong type, and a choice or form\n * with nothing to answer — anything a host could not turn into an answerable\n * control. Options are never dropped: every unusable one produces an issue.\n *\n * @param value Raw `schema` argument as the agent supplied it.\n * @returns The contract-shaped schema, or the issues that make it unanswerable.\n */\nexport function coerceInputSchema(value: unknown): InputSchemaCoercion {\n let candidate: unknown = value;\n if (typeof candidate === \"string\") {\n try {\n candidate = JSON.parse(candidate);\n } catch {\n // A free-text box is still answerable, so an unparseable string keeps the\n // fallback it has always had rather than failing the agent's turn.\n return { ok: true, schema: { kind: \"text\" } };\n }\n }\n if (candidate === null || typeof candidate !== \"object\") {\n return { ok: true, schema: { kind: \"text\" } };\n }\n if (Array.isArray(candidate)) {\n return refuse([\n \"schema: expected an object with a `kind`, got an array — a bare option list needs { kind: 'choice', options: [...] }\",\n ]);\n }\n\n const raw = candidate as Record<string, unknown>;\n const kind = raw.kind;\n // An unknown kind is refused rather than degraded to text: text would discard\n // the agent's intent and hand the user a box the flow cannot consume.\n if (typeof kind !== \"string\" || !KNOWN_KINDS.some((known) => known === kind)) {\n return refuse([\n `schema.kind: expected one of ${KNOWN_KINDS.join(\", \")}, got ${describe(kind)}`,\n ]);\n }\n\n const issues: string[] = [];\n const prepared =\n kind === \"choice\"\n ? prepareChoice(raw, issues)\n : kind === \"form\"\n ? prepareForm(raw, issues)\n : raw;\n if (issues.length > 0) return refuse(issues);\n\n const parsed = InputSchemaContract.safeParse(prepared);\n if (!parsed.success) return refuse(formatIssues(parsed.error.issues));\n return { ok: true, schema: parsed.data };\n}\n\n/** Closes a refusal with the accepted shapes, so no caller has to know to add them. */\nfunction refuse(issues: string[]): InputSchemaCoercion {\n return { ok: false, issues: [...issues, `valid shapes: ${INPUT_SCHEMA_SHAPES_HINT}`] };\n}\n\nfunction prepareChoice(raw: Record<string, unknown>, issues: string[]): Record<string, unknown> {\n const options = raw.options;\n if (!Array.isArray(options)) {\n issues.push(`options: expected an array of choices, got ${describe(options)}`);\n return raw;\n }\n if (options.length === 0) {\n issues.push(\n \"options: expected at least one choice — a choice gate with none cannot be answered\",\n );\n return raw;\n }\n return { ...raw, options: coerceChoices(options, \"options\", issues) };\n}\n\nfunction prepareForm(raw: Record<string, unknown>, issues: string[]): Record<string, unknown> {\n const fields = raw.fields;\n if (!Array.isArray(fields)) {\n issues.push(`fields: expected an array of form fields, got ${describe(fields)}`);\n return raw;\n }\n // A form with no fields is as unanswerable as a choice with no options.\n if (fields.length === 0) {\n issues.push(\"fields: expected at least one field — a form gate with none cannot be answered\");\n return raw;\n }\n const prepared = fields.map((field, index) => coerceField(field, `fields[${index}]`, issues));\n return { ...raw, fields: settleIds(prepared, \"fields\", issues) };\n}\n\nfunction coerceChoices(\n options: unknown[],\n path: string,\n issues: string[],\n): Record<string, unknown>[] {\n const prepared = options.map((option, index) =>\n coerceChoice(option, `${path}[${index}]`, issues),\n );\n return settleIds(prepared, path, issues);\n}\n\nfunction coerceChoice(option: unknown, at: string, issues: string[]): Prepared | undefined {\n if (typeof option === \"string\") {\n const label = option.trim();\n if (label === \"\") {\n issues.push(`${at}: expected a non-empty string`);\n return undefined;\n }\n return { entry: { id: label, label }, derivedId: true };\n }\n if (!isPlainObject(option)) {\n issues.push(\n `${at}: expected a string or an object with { id, label }, got ${describe(option)}`,\n );\n return undefined;\n }\n const identity = coerceIdentity(option, at, issues);\n if (!identity) return undefined;\n const entry: Record<string, unknown> = { ...option, id: identity.id, label: identity.label };\n const { description } = entry;\n // An absent, null, or blank description carries nothing; the contract admits\n // only a non-empty string, and anything else stays for it to reject.\n if (\n description === null ||\n description === undefined ||\n (typeof description === \"string\" && description.trim() === \"\")\n ) {\n delete entry.description;\n }\n return { entry, derivedId: identity.derivedId };\n}\n\nfunction coerceField(field: unknown, at: string, issues: string[]): Prepared | undefined {\n if (!isPlainObject(field)) {\n issues.push(`${at}: expected an object with { id, label, type }, got ${describe(field)}`);\n return undefined;\n }\n const identity = coerceIdentity(field, at, issues);\n if (!identity) return undefined;\n const entry: Record<string, unknown> = { ...field, id: identity.id, label: identity.label };\n const options = field.options;\n // A select with nothing to select is the same unrenderable control a choice\n // gate with no options is, one level down.\n if (field.type === \"choice\" && (!Array.isArray(options) || options.length === 0)) {\n issues.push(\n `${at}.options: expected at least one choice — a choice field with none cannot be answered`,\n );\n return undefined;\n }\n if (Array.isArray(options)) {\n entry.options = coerceChoices(options, `${at}.options`, issues);\n }\n return { entry, derivedId: identity.derivedId };\n}\n\n/**\n * Resolves the `id`/`label` pair of an option or field, letting either supply\n * the other. An id or label of the wrong type is refused rather than replaced:\n * silently swapping in a different id is the failure this module exists to stop\n * — an agent that branches on the id it wrote would never see the substitution.\n */\nfunction coerceIdentity(\n raw: Record<string, unknown>,\n at: string,\n issues: string[],\n): { id: string; label: string; derivedId: boolean } | undefined {\n const id = explicitText(raw.id, at, \"id\", issues);\n const label = explicitText(raw.label, at, \"label\", issues);\n if (!id.ok || !label.ok) return undefined;\n const text = label.value ?? id.value;\n if (text === undefined) {\n issues.push(`${at}: expected a non-empty \\`label\\`, got ${describe(raw.label)}`);\n return undefined;\n }\n return { id: id.value ?? text, label: text, derivedId: id.value === undefined };\n}\n\n/**\n * An explicit `id`/`label`, or `undefined` when the agent supplied nothing to\n * carry (absent, null, or blank). Any other type is intent in the wrong shape,\n * so it is reported instead of dropped.\n */\nfunction explicitText(\n value: unknown,\n at: string,\n key: \"id\" | \"label\",\n issues: string[],\n): { ok: true; value: string | undefined } | { ok: false } {\n if (value === undefined || value === null) return { ok: true, value: undefined };\n if (typeof value !== \"string\") {\n issues.push(`${at}.${key}: expected a non-empty string, got ${describe(value)}`);\n return { ok: false };\n }\n const trimmed = value.trim();\n return { ok: true, value: trimmed === \"\" ? undefined : trimmed };\n}\n\n/**\n * Settles ids across a list of options or fields. Every explicit id is reserved\n * before any derived one is filled in, so a collision's verdict cannot depend on\n * which side of it came first — and a refusal never names an id the agent did\n * not write.\n */\nfunction settleIds(\n prepared: (Prepared | undefined)[],\n path: string,\n issues: string[],\n): Record<string, unknown>[] {\n const used = new Set<string>();\n const reserved = prepared.map((item, index) => {\n if (!item || item.derivedId) return item;\n const id = String(item.entry.id);\n if (used.has(id)) {\n issues.push(\n `${path}[${index}]: duplicate id \"${id}\" — ids must be unique or a host cannot tell the answers apart`,\n );\n return undefined;\n }\n used.add(id);\n return item;\n });\n\n const settled: Record<string, unknown>[] = [];\n reserved.forEach((item, index) => {\n if (!item) return;\n if (item.derivedId) item.entry.id = uniqueId(String(item.entry.id), index, used);\n used.add(String(item.entry.id));\n settled.push(item.entry);\n });\n return settled;\n}\n\nfunction uniqueId(base: string, index: number, used: Set<string>): string {\n if (!used.has(base)) return base;\n // Two options can legitimately share a label; the index disambiguates the id\n // derived from it so the answer stays unambiguous.\n let attempt = index;\n let candidate = `${base}-${attempt}`;\n while (used.has(candidate)) {\n attempt += 1;\n candidate = `${base}-${attempt}`;\n }\n return candidate;\n}\n\nfunction formatIssues(issues: readonly z.core.$ZodIssue[]): string[] {\n return issues.map((issue) => {\n const path = issue.path.reduce<string>((acc, segment) => {\n if (typeof segment === \"number\") return `${acc}[${segment}]`;\n return acc === \"\" ? String(segment) : `${acc}.${String(segment)}`;\n }, \"\");\n return `${path === \"\" ? \"schema\" : path}: ${issue.message}`;\n });\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction describe(value: unknown): string {\n if (value === undefined) return \"nothing\";\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"an array\";\n if (typeof value === \"string\") return `the string ${JSON.stringify(value)}`;\n if (typeof value === \"object\") return \"an object\";\n return `${typeof value} ${String(value)}`;\n}\n"]}
1
+ {"version":3,"sources":["../factory-assets/connectors/flow/contract/input-schema.ts"],"names":[],"mappings":"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","file":"chunk-YCMHWNZA.js","sourcesContent":["/**\n * Coercion of an agent-supplied `request_input` schema onto the flow contract.\n *\n * `request_input` used to cast whatever the agent passed straight into\n * `InputSchema`, so a choice gate could be persisted with option ids no host\n * could render — a run parked forever on a question no human could answer.\n * This module tolerates the shapes agents actually reach for (a bare string per\n * option, an option with a label and no id) and refuses the rest, because a\n * refusal the agent can read and retry beats a stored gate nobody can answer.\n *\n * Exported because hosts normalize the same payloads when they read a stored\n * gate; one shared rule is what keeps the write and read sides in agreement.\n */\n\nimport type { InputSchema } from \"@skaile/workspaces/types\";\nimport type * as z from \"zod\";\nimport { InputSchema as InputSchemaContract } from \"./schema.js\";\n\n/**\n * The shapes `request_input` accepts, phrased for an agent retrying a refused\n * call. Every optional key the contract admits is listed, because validation is\n * strict: an agent refused for one unknown key would otherwise read a key it\n * omitted here as illegal too.\n */\nexport const INPUT_SCHEMA_SHAPES_HINT =\n \"{ kind: 'text', multiline? }, { kind: 'choice', options: [{ id, label, description? }], multiple? }, { kind: 'form', fields: [{ id, label, type: text|textarea|number|choice|file|date|boolean, required?, options?, accept? }] }, or { kind: 'file', accept?, maxSize?, multiple? }\";\n\n/**\n * Outcome of {@link coerceInputSchema}: either a schema in the contract shape,\n * or the reasons it was refused — one entry per problem, each naming its path,\n * closed by a final entry naming the accepted shapes. The hint travels with the\n * issues so every caller's refusal is actionable without re-appending it.\n */\nexport type InputSchemaCoercion =\n | { ok: true; schema: InputSchema }\n | { ok: false; issues: string[] };\n\nconst KNOWN_KINDS = [\"text\", \"choice\", \"form\", \"file\"] as const;\n\n/** A coerced option or form field, and whether its id was derived from its label. */\ntype Prepared = { entry: Record<string, unknown>; derivedId: boolean };\n\n/**\n * Brings an untrusted `request_input` schema into the `InputSchema` contract.\n *\n * Tolerated: a JSON string wrapper, a choice option given as a bare string, and\n * an option or form field whose id is missing but whose label can supply one.\n * Refused: an unknown `kind`, an option or field that carries no usable label, a\n * duplicate explicit id, an id or label of the wrong type, and a choice or form\n * with nothing to answer — anything a host could not turn into an answerable\n * control. Options are never dropped: every unusable one produces an issue.\n *\n * @param value Raw `schema` argument as the agent supplied it.\n * @returns The contract-shaped schema, or the issues that make it unanswerable.\n */\nexport function coerceInputSchema(value: unknown): InputSchemaCoercion {\n let candidate: unknown = value;\n if (typeof candidate === \"string\") {\n try {\n candidate = JSON.parse(candidate);\n } catch {\n // A free-text box is still answerable, so an unparseable string keeps the\n // fallback it has always had rather than failing the agent's turn.\n return { ok: true, schema: { kind: \"text\" } };\n }\n }\n if (candidate === null || typeof candidate !== \"object\") {\n return { ok: true, schema: { kind: \"text\" } };\n }\n if (Array.isArray(candidate)) {\n return refuse([\n \"schema: expected an object with a `kind`, got an array — a bare option list needs { kind: 'choice', options: [...] }\",\n ]);\n }\n\n const raw = candidate as Record<string, unknown>;\n const kind = raw.kind;\n // An unknown kind is refused rather than degraded to text: text would discard\n // the agent's intent and hand the user a box the flow cannot consume.\n if (typeof kind !== \"string\" || !KNOWN_KINDS.some((known) => known === kind)) {\n return refuse([\n `schema.kind: expected one of ${KNOWN_KINDS.join(\", \")}, got ${describe(kind)}`,\n ]);\n }\n\n const issues: string[] = [];\n const prepared =\n kind === \"choice\"\n ? prepareChoice(raw, issues)\n : kind === \"form\"\n ? prepareForm(raw, issues)\n : raw;\n if (issues.length > 0) return refuse(issues);\n\n const parsed = InputSchemaContract.safeParse(prepared);\n if (!parsed.success) return refuse(formatIssues(parsed.error.issues));\n return { ok: true, schema: parsed.data };\n}\n\n/** Closes a refusal with the accepted shapes, so no caller has to know to add them. */\nfunction refuse(issues: string[]): InputSchemaCoercion {\n return { ok: false, issues: [...issues, `valid shapes: ${INPUT_SCHEMA_SHAPES_HINT}`] };\n}\n\nfunction prepareChoice(raw: Record<string, unknown>, issues: string[]): Record<string, unknown> {\n const options = raw.options;\n if (!Array.isArray(options)) {\n issues.push(`options: expected an array of choices, got ${describe(options)}`);\n return raw;\n }\n if (options.length === 0) {\n issues.push(\n \"options: expected at least one choice — a choice gate with none cannot be answered\",\n );\n return raw;\n }\n return { ...raw, options: coerceChoices(options, \"options\", issues) };\n}\n\nfunction prepareForm(raw: Record<string, unknown>, issues: string[]): Record<string, unknown> {\n const fields = raw.fields;\n if (!Array.isArray(fields)) {\n issues.push(`fields: expected an array of form fields, got ${describe(fields)}`);\n return raw;\n }\n // A form with no fields is as unanswerable as a choice with no options.\n if (fields.length === 0) {\n issues.push(\"fields: expected at least one field — a form gate with none cannot be answered\");\n return raw;\n }\n const prepared = fields.map((field, index) => coerceField(field, `fields[${index}]`, issues));\n return { ...raw, fields: settleIds(prepared, \"fields\", issues) };\n}\n\nfunction coerceChoices(\n options: unknown[],\n path: string,\n issues: string[],\n): Record<string, unknown>[] {\n const prepared = options.map((option, index) =>\n coerceChoice(option, `${path}[${index}]`, issues),\n );\n return settleIds(prepared, path, issues);\n}\n\nfunction coerceChoice(option: unknown, at: string, issues: string[]): Prepared | undefined {\n if (typeof option === \"string\") {\n const label = option.trim();\n if (label === \"\") {\n issues.push(`${at}: expected a non-empty string`);\n return undefined;\n }\n return { entry: { id: label, label }, derivedId: true };\n }\n if (!isPlainObject(option)) {\n issues.push(\n `${at}: expected a string or an object with { id, label }, got ${describe(option)}`,\n );\n return undefined;\n }\n const identity = coerceIdentity(option, at, issues);\n if (!identity) return undefined;\n const entry: Record<string, unknown> = { ...option, id: identity.id, label: identity.label };\n const { description } = entry;\n // An absent, null, or blank description carries nothing; the contract admits\n // only a non-empty string, and anything else stays for it to reject.\n if (\n description === null ||\n description === undefined ||\n (typeof description === \"string\" && description.trim() === \"\")\n ) {\n delete entry.description;\n }\n return { entry, derivedId: identity.derivedId };\n}\n\nfunction coerceField(field: unknown, at: string, issues: string[]): Prepared | undefined {\n if (!isPlainObject(field)) {\n issues.push(`${at}: expected an object with { id, label, type }, got ${describe(field)}`);\n return undefined;\n }\n const identity = coerceIdentity(field, at, issues);\n if (!identity) return undefined;\n const entry: Record<string, unknown> = { ...field, id: identity.id, label: identity.label };\n const options = field.options;\n // A select with nothing to select is the same unrenderable control a choice\n // gate with no options is, one level down.\n if (field.type === \"choice\" && (!Array.isArray(options) || options.length === 0)) {\n issues.push(\n `${at}.options: expected at least one choice — a choice field with none cannot be answered`,\n );\n return undefined;\n }\n if (Array.isArray(options)) {\n entry.options = coerceChoices(options, `${at}.options`, issues);\n }\n return { entry, derivedId: identity.derivedId };\n}\n\n/**\n * Resolves the `id`/`label` pair of an option or field, letting either supply\n * the other. An id or label of the wrong type is refused rather than replaced:\n * silently swapping in a different id is the failure this module exists to stop\n * — an agent that branches on the id it wrote would never see the substitution.\n */\nfunction coerceIdentity(\n raw: Record<string, unknown>,\n at: string,\n issues: string[],\n): { id: string; label: string; derivedId: boolean } | undefined {\n const id = explicitText(raw.id, at, \"id\", issues);\n const label = explicitText(raw.label, at, \"label\", issues);\n if (!id.ok || !label.ok) return undefined;\n const text = label.value ?? id.value;\n if (text === undefined) {\n issues.push(`${at}: expected a non-empty \\`label\\`, got ${describe(raw.label)}`);\n return undefined;\n }\n return { id: id.value ?? text, label: text, derivedId: id.value === undefined };\n}\n\n/**\n * An explicit `id`/`label`, or `undefined` when the agent supplied nothing to\n * carry (absent, null, or blank). Any other type is intent in the wrong shape,\n * so it is reported instead of dropped.\n */\nfunction explicitText(\n value: unknown,\n at: string,\n key: \"id\" | \"label\",\n issues: string[],\n): { ok: true; value: string | undefined } | { ok: false } {\n if (value === undefined || value === null) return { ok: true, value: undefined };\n if (typeof value !== \"string\") {\n issues.push(`${at}.${key}: expected a non-empty string, got ${describe(value)}`);\n return { ok: false };\n }\n const trimmed = value.trim();\n return { ok: true, value: trimmed === \"\" ? undefined : trimmed };\n}\n\n/**\n * Settles ids across a list of options or fields. Every explicit id is reserved\n * before any derived one is filled in, so a collision's verdict cannot depend on\n * which side of it came first — and a refusal never names an id the agent did\n * not write.\n */\nfunction settleIds(\n prepared: (Prepared | undefined)[],\n path: string,\n issues: string[],\n): Record<string, unknown>[] {\n const used = new Set<string>();\n const reserved = prepared.map((item, index) => {\n if (!item || item.derivedId) return item;\n const id = String(item.entry.id);\n if (used.has(id)) {\n issues.push(\n `${path}[${index}]: duplicate id \"${id}\" — ids must be unique or a host cannot tell the answers apart`,\n );\n return undefined;\n }\n used.add(id);\n return item;\n });\n\n const settled: Record<string, unknown>[] = [];\n reserved.forEach((item, index) => {\n if (!item) return;\n if (item.derivedId) item.entry.id = uniqueId(String(item.entry.id), index, used);\n used.add(String(item.entry.id));\n settled.push(item.entry);\n });\n return settled;\n}\n\nfunction uniqueId(base: string, index: number, used: Set<string>): string {\n if (!used.has(base)) return base;\n // Two options can legitimately share a label; the index disambiguates the id\n // derived from it so the answer stays unambiguous.\n let attempt = index;\n let candidate = `${base}-${attempt}`;\n while (used.has(candidate)) {\n attempt += 1;\n candidate = `${base}-${attempt}`;\n }\n return candidate;\n}\n\nfunction formatIssues(issues: readonly z.core.$ZodIssue[]): string[] {\n return issues.map((issue) => {\n const path = issue.path.reduce<string>((acc, segment) => {\n if (typeof segment === \"number\") return `${acc}[${segment}]`;\n return acc === \"\" ? String(segment) : `${acc}.${String(segment)}`;\n }, \"\");\n return `${path === \"\" ? \"schema\" : path}: ${issue.message}`;\n });\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction describe(value: unknown): string {\n if (value === undefined) return \"nothing\";\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"an array\";\n if (typeof value === \"string\") return `the string ${JSON.stringify(value)}`;\n if (typeof value === \"object\") return \"an object\";\n return `${typeof value} ${String(value)}`;\n}\n"]}
@@ -1,9 +1,9 @@
1
- import { getStoreManifestsDir } from './chunk-C4AP3XZB.js';
2
- import { deployAll, removeAsset, createScaffold } from './chunk-S4UA244H.js';
3
- import { resolveLibraryDir, writeLock, buildLockFile, readLock, verifyLock, extractForPatch, generatePatch, savePatch, applyPatch } from './chunk-CIPK5JMJ.js';
1
+ import { getStoreManifestsDir } from './chunk-QG2ZXU5W.js';
2
+ import { deployAll, removeAsset, createScaffold } from './chunk-S635WMXH.js';
3
+ import { resolveLibraryDir, writeLock, buildLockFile, readLock, verifyLock, extractForPatch, generatePatch, savePatch, applyPatch } from './chunk-H662SXKS.js';
4
4
  import { deployedBase, isDeployed, deployedDir } from './chunk-F3HNW354.js';
5
- import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-OIDFK7SG.js';
6
- import { loadMcpServerDeclarations, globalSkaileDir, resolveGlobalBackends, globalCacheRoot, migrateLegacyDir, resolveGlobalSkWorkspaceConfig, resolveSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, coerceVersion, matchPin, resolveAll, buildProvenanceIndex, ensureRepo, sourceShortName, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, readLinks, storeManifestSlug } from './chunk-OZ7UNMTK.js';
5
+ import { resolveRuntimeAssets, factoryAssetRoots } from './chunk-DCG4UWJM.js';
6
+ import { loadMcpServerDeclarations, globalSkaileDir, resolveGlobalBackends, globalCacheRoot, migrateLegacyDir, resolveGlobalSkWorkspaceConfig, resolveSkWorkspaceConfig, getGlobalCacheDir, sourceCacheKey, getRepoCommit, coerceVersion, matchPin, resolveAll, buildProvenanceIndex, ensureRepo, sourceShortName, scanRepo, SKAILE_YAML_DEFAULT, checkRepoStatus, resolveAsset, readLinks, storeManifestSlug } from './chunk-RPVTPVGX.js';
7
7
  import { scanDirectory, parseRequires } from './chunk-MKZOK4JU.js';
8
8
  import { parseAssetRef, slugifyAssetName, assetRefToStr } from './chunk-GEEW6SY2.js';
9
9
  import { appendHistory, getRecentHistory, clearHistory } from './chunk-KTBKW2FI.js';
@@ -2085,5 +2085,5 @@ var AssetManager = class {
2085
2085
  };
2086
2086
 
2087
2087
  export { AssetManager, FACTORY_SOURCE_URL, MissingManifestError, NON_DEPLOYABLE_KINDS, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, softDepName };
2088
- //# sourceMappingURL=chunk-SWUVULBU.js.map
2089
- //# sourceMappingURL=chunk-SWUVULBU.js.map
2088
+ //# sourceMappingURL=chunk-YLSMYOHN.js.map
2089
+ //# sourceMappingURL=chunk-YLSMYOHN.js.map