@skaile/workspaces 1.3.0 → 1.5.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 (269) hide show
  1. package/CHANGELOG.md +395 -0
  2. package/README.md +1 -1
  3. package/dist/app-sdk/index.d.ts +2 -0
  4. package/dist/app-sdk/index.js +481 -0
  5. package/dist/app-sdk/index.js.map +1 -0
  6. package/dist/app-sdk/src/app.d.ts +152 -0
  7. package/dist/app-sdk/src/app.d.ts.map +1 -0
  8. package/dist/app-sdk/src/connection-params.d.ts +117 -0
  9. package/dist/app-sdk/src/connection-params.d.ts.map +1 -0
  10. package/dist/app-sdk/src/define-app-capability.d.ts +139 -0
  11. package/dist/app-sdk/src/define-app-capability.d.ts.map +1 -0
  12. package/dist/app-sdk/src/index.d.ts +17 -0
  13. package/dist/app-sdk/src/index.d.ts.map +1 -0
  14. package/dist/app-sdk/src/logger.d.ts +26 -0
  15. package/dist/app-sdk/src/logger.d.ts.map +1 -0
  16. package/dist/app-sdk/src/transport.d.ts +93 -0
  17. package/dist/app-sdk/src/transport.d.ts.map +1 -0
  18. package/dist/app-sdk/src/ws-transport.d.ts +79 -0
  19. package/dist/app-sdk/src/ws-transport.d.ts.map +1 -0
  20. package/dist/{asset-feeds-NEZKG6YS.js → asset-feeds-T35ELX2O.js} +11 -11
  21. package/dist/{asset-feeds-NEZKG6YS.js.map → asset-feeds-T35ELX2O.js.map} +1 -1
  22. package/dist/asset-manager/index.js +15 -10
  23. package/dist/asset-manager/installer.js +9 -9
  24. package/dist/asset-manager/renderers.js +2 -2
  25. package/dist/asset-manager/src/index.d.ts +42 -6
  26. package/dist/asset-manager/src/index.d.ts.map +1 -1
  27. package/dist/bridge/drivers/claude-sdk.js +2 -2
  28. package/dist/bridge/drivers/codex.js +1 -1
  29. package/dist/bridge/drivers/continue.js +2 -2
  30. package/dist/bridge/drivers/echo.js +1 -1
  31. package/dist/bridge/drivers/gemini.js +3 -3
  32. package/dist/bridge/drivers/goose.js +2 -2
  33. package/dist/bridge/drivers/omp.js +1 -1
  34. package/dist/bridge/drivers/opencode.js +2 -2
  35. package/dist/bridge/drivers/qwen.js +3 -3
  36. package/dist/bridge/index.js +3 -3
  37. package/dist/{chunk-YOPSHV7V.js → chunk-2DWXGUZA.js} +3 -3
  38. package/dist/{chunk-YOPSHV7V.js.map → chunk-2DWXGUZA.js.map} +1 -1
  39. package/dist/{chunk-XBG2YDQQ.js → chunk-2ZMO4CFG.js} +3 -3
  40. package/dist/{chunk-XBG2YDQQ.js.map → chunk-2ZMO4CFG.js.map} +1 -1
  41. package/dist/{chunk-OBSSORCE.js → chunk-3CHARYD4.js} +84 -12
  42. package/dist/chunk-3CHARYD4.js.map +1 -0
  43. package/dist/{chunk-SKADPHAM.js → chunk-4N5XR5DQ.js} +2 -2
  44. package/dist/chunk-4N5XR5DQ.js.map +1 -0
  45. package/dist/{chunk-WFEPI5LA.js → chunk-6NR2BEIY.js} +6 -6
  46. package/dist/{chunk-WFEPI5LA.js.map → chunk-6NR2BEIY.js.map} +1 -1
  47. package/dist/{chunk-7CNIRF42.js → chunk-BGIC25VK.js} +26 -15
  48. package/dist/chunk-BGIC25VK.js.map +1 -0
  49. package/dist/{chunk-YXEPZ7LP.js → chunk-CNSNN7N6.js} +6 -6
  50. package/dist/{chunk-YXEPZ7LP.js.map → chunk-CNSNN7N6.js.map} +1 -1
  51. package/dist/{chunk-PSMW5HLX.js → chunk-DMG6NJH7.js} +5 -5
  52. package/dist/{chunk-PSMW5HLX.js.map → chunk-DMG6NJH7.js.map} +1 -1
  53. package/dist/{chunk-P3MJYPZE.js → chunk-FDE7XRQA.js} +57 -9
  54. package/dist/chunk-FDE7XRQA.js.map +1 -0
  55. package/dist/{chunk-K5SD7FSF.js → chunk-HKX5VSWQ.js} +3 -3
  56. package/dist/{chunk-K5SD7FSF.js.map → chunk-HKX5VSWQ.js.map} +1 -1
  57. package/dist/{chunk-AZAS3FKN.js → chunk-HY33RMEA.js} +49 -3
  58. package/dist/chunk-HY33RMEA.js.map +1 -0
  59. package/dist/{chunk-XKARS6EE.js → chunk-IEX5YV4R.js} +3 -3
  60. package/dist/{chunk-XKARS6EE.js.map → chunk-IEX5YV4R.js.map} +1 -1
  61. package/dist/{chunk-GB4SEEK4.js → chunk-IRORTHGA.js} +10 -4
  62. package/dist/chunk-IRORTHGA.js.map +1 -0
  63. package/dist/chunk-J5TI55E7.js +203 -0
  64. package/dist/chunk-J5TI55E7.js.map +1 -0
  65. package/dist/chunk-JIDKX7GC.js +122 -0
  66. package/dist/chunk-JIDKX7GC.js.map +1 -0
  67. package/dist/{chunk-BDUANIAR.js → chunk-KEQ4GLVM.js} +3 -3
  68. package/dist/{chunk-BDUANIAR.js.map → chunk-KEQ4GLVM.js.map} +1 -1
  69. package/dist/{chunk-5XS3BFJS.js → chunk-KMY7HVQ6.js} +3 -3
  70. package/dist/{chunk-5XS3BFJS.js.map → chunk-KMY7HVQ6.js.map} +1 -1
  71. package/dist/{chunk-BZMTR5WW.js → chunk-MZV6WCF3.js} +83 -51
  72. package/dist/chunk-MZV6WCF3.js.map +1 -0
  73. package/dist/{chunk-QK5JDAFF.js → chunk-NKTFEV7Q.js} +4 -4
  74. package/dist/{chunk-QK5JDAFF.js.map → chunk-NKTFEV7Q.js.map} +1 -1
  75. package/dist/{chunk-DZCK7GRW.js → chunk-P4VHQA4N.js} +22 -6
  76. package/dist/chunk-P4VHQA4N.js.map +1 -0
  77. package/dist/{chunk-EVZKWY5J.js → chunk-PK7Q7MC7.js} +5 -4
  78. package/dist/chunk-PK7Q7MC7.js.map +1 -0
  79. package/dist/{chunk-ETYDLXI5.js → chunk-RDYOU6N6.js} +2 -2
  80. package/dist/{chunk-ETYDLXI5.js.map → chunk-RDYOU6N6.js.map} +1 -1
  81. package/dist/{chunk-RHMQPLIK.js → chunk-RSYV7XEN.js} +14 -8
  82. package/dist/chunk-RSYV7XEN.js.map +1 -0
  83. package/dist/{chunk-SUOGVHGJ.js → chunk-TNSCHS4I.js} +2 -2
  84. package/dist/{chunk-SUOGVHGJ.js.map → chunk-TNSCHS4I.js.map} +1 -1
  85. package/dist/{chunk-Z5Z3MYDL.js → chunk-UPZGQZEJ.js} +3 -3
  86. package/dist/{chunk-Z5Z3MYDL.js.map → chunk-UPZGQZEJ.js.map} +1 -1
  87. package/dist/{chunk-RJ3HUSBC.js → chunk-UQ5FK2AB.js} +3 -3
  88. package/dist/{chunk-RJ3HUSBC.js.map → chunk-UQ5FK2AB.js.map} +1 -1
  89. package/dist/{chunk-OUWNTFDG.js → chunk-UQKYT4V6.js} +38 -6
  90. package/dist/chunk-UQKYT4V6.js.map +1 -0
  91. package/dist/chunk-WYGXYGJH.js +688 -0
  92. package/dist/chunk-WYGXYGJH.js.map +1 -0
  93. package/dist/{chunk-TJRWGMD2.js → chunk-ZBZQC5R7.js} +3 -3
  94. package/dist/{chunk-TJRWGMD2.js.map → chunk-ZBZQC5R7.js.map} +1 -1
  95. package/dist/cli/index.js +1022 -374
  96. package/dist/cli/index.js.map +1 -1
  97. package/dist/cli/src/commands/catalog.d.ts +18 -0
  98. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  99. package/dist/cli/src/commands/library-cmd.d.ts +2 -2
  100. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  101. package/dist/cli/src/commands/library-publish.d.ts +53 -0
  102. package/dist/cli/src/commands/library-publish.d.ts.map +1 -0
  103. package/dist/cli/src/commands/preset-apply.d.ts +59 -0
  104. package/dist/cli/src/commands/preset-apply.d.ts.map +1 -0
  105. package/dist/cli/src/commands/preset-cmd.d.ts +8 -2
  106. package/dist/cli/src/commands/preset-cmd.d.ts.map +1 -1
  107. package/dist/cli/src/commands/preset-export.d.ts +102 -0
  108. package/dist/cli/src/commands/preset-export.d.ts.map +1 -0
  109. package/dist/cli/src/commands/project.d.ts.map +1 -1
  110. package/dist/cli/src/commands/publish-core.d.ts +75 -0
  111. package/dist/cli/src/commands/publish-core.d.ts.map +1 -0
  112. package/dist/cli/src/commands/run.d.ts.map +1 -1
  113. package/dist/cli/src/commands/source-manifest-publish.d.ts +82 -0
  114. package/dist/cli/src/commands/source-manifest-publish.d.ts.map +1 -0
  115. package/dist/cli/src/commands/source-manifest.d.ts +65 -6
  116. package/dist/cli/src/commands/source-manifest.d.ts.map +1 -1
  117. package/dist/cli/src/commands/source.d.ts +13 -0
  118. package/dist/cli/src/commands/source.d.ts.map +1 -1
  119. package/dist/cli/src/commands/store.d.ts.map +1 -1
  120. package/dist/cli/src/commands/why.d.ts +18 -0
  121. package/dist/cli/src/commands/why.d.ts.map +1 -1
  122. package/dist/cli/src/driver-error.d.ts +12 -0
  123. package/dist/cli/src/driver-error.d.ts.map +1 -0
  124. package/dist/cli/src/open-library.d.ts +4 -0
  125. package/dist/cli/src/open-library.d.ts.map +1 -1
  126. package/dist/cli/src/store-auth.d.ts +42 -0
  127. package/dist/cli/src/store-auth.d.ts.map +1 -0
  128. package/dist/cli/src/store-client.d.ts +20 -22
  129. package/dist/cli/src/store-client.d.ts.map +1 -1
  130. package/dist/cli/src/store-publisher.d.ts +91 -0
  131. package/dist/cli/src/store-publisher.d.ts.map +1 -0
  132. package/dist/connectors/config.js +6 -6
  133. package/dist/connectors/index.js +8 -8
  134. package/dist/core/index.js +5 -5
  135. package/dist/core/publish-manifest.js +1 -1
  136. package/dist/core/runtime-assets.js +3 -3
  137. package/dist/core/src/cache-paths.d.ts +17 -0
  138. package/dist/core/src/cache-paths.d.ts.map +1 -1
  139. package/dist/core/src/index.d.ts +2 -2
  140. package/dist/core/src/index.d.ts.map +1 -1
  141. package/dist/core/src/publish-manifest.d.ts.map +1 -1
  142. package/dist/core/src/repo-manager.d.ts +13 -2
  143. package/dist/core/src/repo-manager.d.ts.map +1 -1
  144. package/dist/core/src/walker.d.ts +10 -0
  145. package/dist/core/src/walker.d.ts.map +1 -1
  146. package/dist/core/src/workspace-yaml-editor.d.ts +14 -1
  147. package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
  148. package/dist/core/workspace-config.js +2 -2
  149. package/dist/deploy/index.js +5 -5
  150. package/dist/discovery/index.js +3 -3
  151. package/dist/discovery/src/discover-manifest.d.ts.map +1 -1
  152. package/dist/discovery/src/discover.d.ts +17 -4
  153. package/dist/discovery/src/discover.d.ts.map +1 -1
  154. package/dist/discovery/src/index.d.ts +1 -1
  155. package/dist/discovery/src/index.d.ts.map +1 -1
  156. package/dist/discovery/src/reference-lint.d.ts +7 -0
  157. package/dist/discovery/src/reference-lint.d.ts.map +1 -1
  158. package/dist/discovery/src/source-config.d.ts +28 -0
  159. package/dist/discovery/src/source-config.d.ts.map +1 -1
  160. package/dist/discovery/src/tree-entries.d.ts.map +1 -1
  161. package/dist/{ensure-sources-4BAJGJRK.js → ensure-sources-QDVFUIUP.js} +18 -13
  162. package/dist/ensure-sources-QDVFUIUP.js.map +1 -0
  163. package/dist/factory-assets/connectors/box.js +8 -8
  164. package/dist/factory-assets/connectors/deploy.js +8 -8
  165. package/dist/factory-assets/connectors/devserver.js +8 -8
  166. package/dist/factory-assets/connectors/flow/adapter.js +8 -8
  167. package/dist/factory-assets/connectors/flow/engine/engine.d.ts +4 -1
  168. package/dist/factory-assets/connectors/flow/engine/engine.d.ts.map +1 -1
  169. package/dist/factory-assets/connectors/flow/engine/types.d.ts +41 -6
  170. package/dist/factory-assets/connectors/flow/engine/types.d.ts.map +1 -1
  171. package/dist/factory-assets/connectors/flow/engine.js +6 -6
  172. package/dist/factory-assets/connectors/flow/run-flow.js +9 -9
  173. package/dist/factory-assets/connectors/flow.js +8 -8
  174. package/dist/factory-assets/connectors/git.js +8 -8
  175. package/dist/factory-assets/connectors/gmail.js +8 -8
  176. package/dist/factory-assets/connectors/googledrive.js +8 -8
  177. package/dist/factory-assets/connectors/local.js +8 -8
  178. package/dist/factory-assets/connectors/mattermost.js +8 -8
  179. package/dist/factory-assets/connectors/memory.js +8 -8
  180. package/dist/factory-assets/connectors/minio.js +8 -8
  181. package/dist/factory-assets/connectors/postgres.js +8 -8
  182. package/dist/factory-assets/connectors/s3.js +8 -8
  183. package/dist/factory-assets/connectors/sharepoint.js +8 -8
  184. package/dist/factory-assets/connectors/sqlite.js +8 -8
  185. package/dist/factory-assets/connectors/static-server.js +8 -8
  186. package/dist/factory-assets/connectors/tunnel.js +8 -8
  187. package/dist/factory-assets/connectors/webdav.js +8 -8
  188. package/dist/factory-assets/connectors/xstate-store.js +8 -8
  189. package/dist/factory-assets/connectors/xstate.js +8 -8
  190. package/dist/factory-assets/skills/skaile-author-asset/SKILL.md +1 -1
  191. package/dist/factory-assets/skills/skaile-manage-workspace/SKILL.md +1 -1
  192. package/dist/{flows-UFCOGAAM.js → flows-MRVXTYWC.js} +4 -4
  193. package/dist/{flows-UFCOGAAM.js.map → flows-MRVXTYWC.js.map} +1 -1
  194. package/dist/helpers-TF7GCBRQ.js +27 -0
  195. package/dist/{helpers-2OL4FRFB.js.map → helpers-TF7GCBRQ.js.map} +1 -1
  196. package/dist/library/index.js +9 -9
  197. package/dist/library/install.js +5 -5
  198. package/dist/library/src/index.d.ts +2 -2
  199. package/dist/library/src/index.d.ts.map +1 -1
  200. package/dist/library/src/local/local-catalog-source.d.ts +12 -1
  201. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  202. package/dist/library/src/sync/manifest-writeback.d.ts +36 -0
  203. package/dist/library/src/sync/manifest-writeback.d.ts.map +1 -1
  204. package/dist/library-publish-K5IBE44D.js +249 -0
  205. package/dist/library-publish-K5IBE44D.js.map +1 -0
  206. package/dist/open-library-4HMIDK3N.js +29 -0
  207. package/dist/{open-library-RPV2LIKL.js.map → open-library-4HMIDK3N.js.map} +1 -1
  208. package/dist/{paths-ML33B5SB.js → paths-P3DWFUPS.js} +8 -8
  209. package/dist/{paths-ML33B5SB.js.map → paths-P3DWFUPS.js.map} +1 -1
  210. package/dist/{plugin-store-G4HKWCTU.js → plugin-store-S7OMGI7N.js} +7 -7
  211. package/dist/{plugin-store-G4HKWCTU.js.map → plugin-store-S7OMGI7N.js.map} +1 -1
  212. package/dist/runner/index.js +14 -14
  213. package/dist/runner/src/agent.d.ts.map +1 -1
  214. package/dist/runner/src/capability-registry.d.ts +15 -4
  215. package/dist/runner/src/capability-registry.d.ts.map +1 -1
  216. package/dist/sdk/asset-manager.js +15 -10
  217. package/dist/sdk/bridge.js +3 -3
  218. package/dist/sdk/core.js +5 -5
  219. package/dist/sdk/flow.js +6 -6
  220. package/dist/sdk/index.js +14 -14
  221. package/dist/sdk/runner.js +14 -14
  222. package/dist/sdk/session.js +2 -2
  223. package/dist/sdk/types.js +1 -1
  224. package/dist/session/index.js +2 -2
  225. package/dist/{setup-WS6PF6JQ.js → setup-2CCS63L6.js} +10 -10
  226. package/dist/{setup-WS6PF6JQ.js.map → setup-2CCS63L6.js.map} +1 -1
  227. package/dist/source-LOAM7IIQ.js +30 -0
  228. package/dist/{source-22U5NOY4.js.map → source-LOAM7IIQ.js.map} +1 -1
  229. package/dist/source-manifest-publish-TGVZ6KMC.js +228 -0
  230. package/dist/source-manifest-publish-TGVZ6KMC.js.map +1 -0
  231. package/dist/tui/index.js +14 -14
  232. package/dist/types/index.js +1 -1
  233. package/dist/types/manifests.js +1 -1
  234. package/dist/types/src/capabilities.d.ts +8 -2
  235. package/dist/types/src/capabilities.d.ts.map +1 -1
  236. package/dist/types/src/logging.d.ts +3 -2
  237. package/dist/types/src/logging.d.ts.map +1 -1
  238. package/dist/types/src/manifests/_shared.d.ts +4 -4
  239. package/dist/types/src/manifests/index.d.ts +2 -2
  240. package/dist/types/src/manifests/index.d.ts.map +1 -1
  241. package/dist/types/src/manifests/preset.d.ts +10 -0
  242. package/dist/types/src/manifests/preset.d.ts.map +1 -1
  243. package/dist/types/src/version.d.ts +11 -1
  244. package/dist/types/src/version.d.ts.map +1 -1
  245. package/dist/workspace-plugin/adapters/mcp.js +2 -2
  246. package/dist/workspace-plugin/adapters/omp.js +3 -3
  247. package/dist/workspace-plugin/index.js +1 -1
  248. package/package.json +7 -1
  249. package/dist/chunk-7CNIRF42.js.map +0 -1
  250. package/dist/chunk-AZAS3FKN.js.map +0 -1
  251. package/dist/chunk-BZMTR5WW.js.map +0 -1
  252. package/dist/chunk-DZCK7GRW.js.map +0 -1
  253. package/dist/chunk-EVZKWY5J.js.map +0 -1
  254. package/dist/chunk-GB4SEEK4.js.map +0 -1
  255. package/dist/chunk-JQMIG7D3.js +0 -93
  256. package/dist/chunk-JQMIG7D3.js.map +0 -1
  257. package/dist/chunk-OBSSORCE.js.map +0 -1
  258. package/dist/chunk-OUWNTFDG.js.map +0 -1
  259. package/dist/chunk-P3MJYPZE.js.map +0 -1
  260. package/dist/chunk-RHMQPLIK.js.map +0 -1
  261. package/dist/chunk-RYRJEVQ4.js +0 -377
  262. package/dist/chunk-RYRJEVQ4.js.map +0 -1
  263. package/dist/chunk-SKADPHAM.js.map +0 -1
  264. package/dist/ensure-sources-4BAJGJRK.js.map +0 -1
  265. package/dist/helpers-2OL4FRFB.js +0 -22
  266. package/dist/open-library-RPV2LIKL.js +0 -29
  267. package/dist/source-22U5NOY4.js +0 -30
  268. package/dist/store-client-YLMBH5MF.js +0 -15
  269. package/dist/store-client-YLMBH5MF.js.map +0 -1
@@ -0,0 +1,152 @@
1
+ /**
2
+ * `createSkaileApp` — the thin app SDK that makes an embedded app
3
+ * agent-controllable.
4
+ *
5
+ * An app becomes a *capability peer*, mirroring how the runner behaves toward
6
+ * the platform:
7
+ *
8
+ * 1. Opens an authenticated back-connection (via an {@link AppTransport}).
9
+ * 2. Performs the app handshake — sends `app_hello`, awaits `app_hello_ack`
10
+ * (binding the connection to `session + appId`) or `app_hello_nack` (refusal).
11
+ * 3. Registers its `app.*` capabilities via `capability_register`, stamping
12
+ * each with `origin:{kind:'app', appId}` and `side:'app'`. Register /
13
+ * deregister mid-session is supported.
14
+ * 4. Answers inbound `capability_invoked` events by running the local handler
15
+ * and replying with `capability_result` (a thrown handler rides back as
16
+ * `{ error }`).
17
+ *
18
+ * The approval round-trip for `requiresApproval` capabilities is handled
19
+ * entirely platform-side: the gateway parks the invocation for user approval
20
+ * and only forwards `capability_invoked` to the app *after* approval, so the
21
+ * app just marks the capability and answers when asked.
22
+ *
23
+ * The peer reconnects and replays its registrations on a dropped socket, and on
24
+ * a *retryable* refusal — the app boots independently of the session's agent
25
+ * container and can win that race. See {@link ReconnectOptions}.
26
+ *
27
+ * @category App SDK
28
+ * @since 3.4.0
29
+ */
30
+ import type { Capability } from "@skaile/workspaces/types";
31
+ import type { DefinedAppCapability } from "./define-app-capability.js";
32
+ import { type AppLogger } from "./logger.js";
33
+ import type { AppTransport } from "./transport.js";
34
+ /** Default timeout waiting for the gateway's `app_hello_ack`. */
35
+ export declare const DEFAULT_HELLO_TIMEOUT_MS = 10000;
36
+ /**
37
+ * Reconnect / retry policy. Set `reconnect: false` on {@link SkaileAppOptions}
38
+ * to disable entirely (one attempt, no replay).
39
+ *
40
+ * @category App SDK
41
+ * @since 3.5.0
42
+ */
43
+ export interface ReconnectOptions {
44
+ /** Attempts before giving up. Default 5. */
45
+ maxAttempts?: number;
46
+ /** First backoff delay in ms; doubles each attempt. Default 1000. */
47
+ baseMs?: number;
48
+ /** Backoff ceiling in ms. Default 30000. */
49
+ maxMs?: number;
50
+ }
51
+ /**
52
+ * The gateway refused the handshake. `retryable` mirrors the wire field: `true`
53
+ * for a transient refusal (the agent container is not up yet), `false` for a
54
+ * permanent one (bad token, `appId` not permitted).
55
+ *
56
+ * @category App SDK
57
+ * @since 3.5.0
58
+ */
59
+ export declare class AppHandshakeRefusedError extends Error {
60
+ readonly retryable: boolean;
61
+ constructor(reason: string, retryable: boolean);
62
+ }
63
+ /**
64
+ * Options for {@link createSkaileApp}.
65
+ *
66
+ * @category App SDK
67
+ * @since 3.4.0
68
+ */
69
+ export interface SkaileAppOptions {
70
+ /** The embedded app's stable id. Every registered capability is bound to it. */
71
+ appId: string;
72
+ /**
73
+ * The app back-connection. Inject {@link createWebSocketAppTransport} in
74
+ * production or a fake in tests. The transport carries the injected session
75
+ * identity as its connection credential.
76
+ *
77
+ * With `reconnect` enabled the transport must be able to produce a **fresh**
78
+ * token per attempt — the gateway consumes it at `app_hello`. Pass a
79
+ * `SessionTokenProvider` rather than a bare string.
80
+ */
81
+ transport: AppTransport;
82
+ /** Protocol version the SDK announces in `app_hello`. Defaults to the SDK's. */
83
+ protocolVersion?: string;
84
+ /** Timeout waiting for `app_hello_ack`. Defaults to {@link DEFAULT_HELLO_TIMEOUT_MS}. */
85
+ helloTimeoutMs?: number;
86
+ /** Logger for the SDK and (by default) capability handlers. Defaults to {@link noopLogger}. */
87
+ logger?: AppLogger;
88
+ /**
89
+ * Reconnect policy, or `false` to disable. Defaults to
90
+ * `{maxAttempts:5, baseMs:1000, maxMs:30000}`.
91
+ *
92
+ * @since 3.5.0
93
+ */
94
+ reconnect?: ReconnectOptions | false;
95
+ }
96
+ /** Result of a successful handshake — the bound session context. */
97
+ export interface AppSession {
98
+ sessionId: string;
99
+ userId?: string;
100
+ }
101
+ /**
102
+ * A connected (or connectable) Skaile app. Register capabilities before or
103
+ * after {@link connect}; post-connect changes are pushed to the gateway
104
+ * immediately.
105
+ *
106
+ * @category App SDK
107
+ * @since 3.4.0
108
+ */
109
+ export interface SkaileApp {
110
+ /**
111
+ * Add (or replace, by name) an app capability. Registering the same name
112
+ * again replaces it — mirrors the registry's replace-by-name semantics. When
113
+ * already connected, a `capability_register` is sent immediately.
114
+ */
115
+ registerCapability(cap: DefinedAppCapability): void;
116
+ /**
117
+ * Remove a capability by name. No-op when unknown. When connected, a
118
+ * `capability_deregister` is sent immediately so the tool disappears from the
119
+ * agent's catalog.
120
+ */
121
+ deregisterCapability(name: string): void;
122
+ /** Wire-format snapshot of the currently registered capabilities (origin stamped). */
123
+ readonly capabilities: readonly Capability[];
124
+ /** The bound session once connected; `null` before the handshake and while reconnecting. */
125
+ readonly session: AppSession | null;
126
+ /**
127
+ * Open the connection, perform the handshake, and register the current
128
+ * capabilities. Resolves with the bound {@link AppSession}. Rejects if the
129
+ * gateway refuses permanently, the handshake times out, or the transport
130
+ * disconnects mid-handshake. A *retryable* refusal is retried per the
131
+ * reconnect policy before rejecting.
132
+ */
133
+ connect(): Promise<AppSession>;
134
+ /**
135
+ * Subscribe to session binding changes. Fires on **every** bind — including
136
+ * the initial `connect()` — with the new {@link AppSession}, and with `null`
137
+ * whenever the connection drops. Returns an unsubscribe function.
138
+ *
139
+ * @since 3.5.0
140
+ */
141
+ onSessionChange(handler: (session: AppSession | null) => void): () => void;
142
+ /** Disconnect and tear down. Idempotent. Cancels any pending reconnect. */
143
+ close(): Promise<void>;
144
+ }
145
+ /**
146
+ * Create a {@link SkaileApp}. See the module doc for the peer lifecycle.
147
+ *
148
+ * @category App SDK
149
+ * @since 3.4.0
150
+ */
151
+ export declare function createSkaileApp(options: SkaileAppOptions): SkaileApp;
152
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../app-sdk/src/app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAErE,iEAAiE;AACjE,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAS/C;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;gBAChB,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO;CAK/C;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;OAQG;IACH,SAAS,EAAE,YAAY,CAAC;IACxB,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+FAA+F;IAC/F,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC;CACtC;AAED,oEAAoE;AACpE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,kBAAkB,CAAC,GAAG,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACpD;;;;OAIG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,sFAAsF;IACtF,QAAQ,CAAC,YAAY,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7C,4FAA4F;IAC5F,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC;;;;;;OAMG;IACH,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC3E,2EAA2E;IAC3E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CA+RpE"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Connection-param handshake between the embedding host and the app frame.
3
+ *
4
+ * An embedded app needs three things to open its back-connection: the gateway
5
+ * URL, its own `appId`, and a session identity token. The token is a **secret**,
6
+ * so it must not ride in the iframe `src` — the preview surface that serves the
7
+ * app is unauthenticated, and a URL lands in access logs, `Referer` headers, and
8
+ * browser history. Instead the host posts it over `postMessage`, and the app
9
+ * asks for it with a ready ping once its script is running.
10
+ *
11
+ * The host cannot simply post on iframe `load`: it has no way to know when the
12
+ * app's script is listening. So the app speaks first.
13
+ *
14
+ * ```text
15
+ * app → host { type: 'skaile_app_ready', appId } targetOrigin = parentOrigin
16
+ * host → app { type: 'skaile_app_params', appId, url, token } targetOrigin = appOrigin
17
+ * ```
18
+ *
19
+ * Both sides pin the peer: the app checks `event.origin === parentOrigin` and
20
+ * that the message came from its own parent; the host checks the origin and that
21
+ * `event.source` is the very iframe it rendered. The app learns the expected
22
+ * parent origin from a **non-secret** query param on its `src`
23
+ * ({@link PARENT_ORIGIN_QUERY_PARAM}), which is safe to leak precisely because it
24
+ * is not a credential.
25
+ *
26
+ * @category App SDK
27
+ * @since 3.5.0
28
+ */
29
+ /**
30
+ * Query param on the app's iframe `src` carrying the embedder's origin. Not a
31
+ * secret — it is the value the app pins its `postMessage` peer to.
32
+ */
33
+ export declare const PARENT_ORIGIN_QUERY_PARAM = "skaileParentOrigin";
34
+ /** Default timeout waiting for the host's params reply. */
35
+ export declare const DEFAULT_PARAMS_TIMEOUT_MS = 10000;
36
+ /** App → host. Announces the app frame is listening and wants its params. */
37
+ export type SkaileAppReadyMessage = {
38
+ type: "skaile_app_ready";
39
+ /** The app asking. The host answers only for an app it actually embedded. */
40
+ appId: string;
41
+ };
42
+ /** Host → app. Carries the gateway URL and the single-use session identity token. */
43
+ export type SkaileAppParamsMessage = {
44
+ type: "skaile_app_params";
45
+ /** Echoed back so a frame embedding several apps can disambiguate. */
46
+ appId: string;
47
+ /** The gateway app-channel URL, e.g. `wss://platform/app-connect`. */
48
+ url: string;
49
+ /** Single-use session identity token. Consumed by the gateway at `app_hello`. */
50
+ token: string;
51
+ };
52
+ /** Resolved params, ready to hand to `createWebSocketAppTransport` + `createSkaileApp`. */
53
+ export type AppConnectionParams = {
54
+ url: string;
55
+ appId: string;
56
+ token: string;
57
+ };
58
+ /** The subset of `postMessage` targets this module needs. */
59
+ export type PostMessageTarget = {
60
+ postMessage(message: unknown, targetOrigin: string): void;
61
+ };
62
+ /** Structural view of a `MessageEvent`, so tests need no DOM. */
63
+ export type MessageEventLike = {
64
+ readonly origin: string;
65
+ readonly source: unknown;
66
+ readonly data: unknown;
67
+ };
68
+ /** Structural view of the `window` bits this module needs. Injectable for tests. */
69
+ export type AppWindowLike = {
70
+ readonly parent: PostMessageTarget | null;
71
+ readonly location: {
72
+ readonly search: string;
73
+ };
74
+ addEventListener(type: "message", handler: (event: MessageEventLike) => void): void;
75
+ removeEventListener(type: "message", handler: (event: MessageEventLike) => void): void;
76
+ };
77
+ /**
78
+ * Options for {@link resolveAppConnectionParams}.
79
+ *
80
+ * @category App SDK
81
+ * @since 3.5.0
82
+ */
83
+ export interface ResolveAppConnectionParamsOptions {
84
+ /** The embedded app's stable id. Must match the params the host replies with. */
85
+ appId: string;
86
+ /**
87
+ * Expected origin of the embedding host. Defaults to the
88
+ * {@link PARENT_ORIGIN_QUERY_PARAM} query param on the current URL. Never `"*"`
89
+ * or `"null"` — an unpinned peer defeats the point of not putting the token in
90
+ * the URL.
91
+ */
92
+ parentOrigin?: string;
93
+ /** How long to wait for the host's reply. Defaults to {@link DEFAULT_PARAMS_TIMEOUT_MS}. */
94
+ timeoutMs?: number;
95
+ /** Window to listen and post on. Defaults to the global. Injectable for tests. */
96
+ windowRef?: AppWindowLike;
97
+ }
98
+ /**
99
+ * Ask the embedding host for this app's connection params.
100
+ *
101
+ * Posts a {@link SkaileAppReadyMessage} to the parent and resolves with the
102
+ * matching {@link SkaileAppParamsMessage}. Messages from any other origin, from
103
+ * any window other than the parent, or for another `appId` are ignored — not
104
+ * rejected — because a page may legitimately receive unrelated `postMessage`
105
+ * traffic.
106
+ *
107
+ * Call it again to re-request a fresh token: the token is single-use, so a
108
+ * reconnecting transport needs a new one (see `createSkaileApp`'s `reconnect`).
109
+ *
110
+ * @throws when not embedded, when the parent origin cannot be determined or is
111
+ * unpinnable, or when the host does not reply within `timeoutMs`.
112
+ *
113
+ * @category App SDK
114
+ * @since 3.5.0
115
+ */
116
+ export declare function resolveAppConnectionParams(options: ResolveAppConnectionParamsOptions): Promise<AppConnectionParams>;
117
+ //# sourceMappingURL=connection-params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-params.d.ts","sourceRoot":"","sources":["../../../app-sdk/src/connection-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;GAGG;AACH,eAAO,MAAM,yBAAyB,uBAAuB,CAAC;AAE9D,2DAA2D;AAC3D,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD,6EAA6E;AAC7E,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,kBAAkB,CAAC;IACzB,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qFAAqF;AACrF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,2FAA2F;AAC3F,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,6DAA6D;AAC7D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3D,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,oFAAoF;AACpF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI,CAAC;IACpF,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI,CAAC;CACxF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,iCAAiC;IAChD,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAsBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,iCAAiC,GACzC,OAAO,CAAC,mBAAmB,CAAC,CAyE9B"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * `defineAppCapability` — author-friendly factory for an embedded app's
3
+ * agent-controllable capabilities.
4
+ *
5
+ * It mirrors the runner's `defineCapability` (`@skaile/workspaces/runner`) but
6
+ * is scoped to the app side: the handler always runs *in the app*, so `side` is
7
+ * fixed to `'app'` and the author never passes it. The originating `appId` is
8
+ * known to the SDK, not the individual capability, so `origin` is stamped by
9
+ * {@link createSkaileApp} at registration time — not here.
10
+ *
11
+ * @category App SDK
12
+ * @since 3.4.0
13
+ */
14
+ import type { CapabilityAudience, CapabilityOrigin, RenderSpec } from "@skaile/workspaces/types";
15
+ import * as z from "zod";
16
+ import type { AppLogger } from "./logger.js";
17
+ /**
18
+ * Per-invocation context passed to an app capability handler. Analogous to the
19
+ * runner's `HandlerContext`, but carries the `appId` and the SDK's
20
+ * {@link AppLogger} (there is no server-side `capability:<origin>:<name>` log
21
+ * slice inside the app process).
22
+ *
23
+ * @category App SDK
24
+ * @since 3.4.0
25
+ */
26
+ export type AppHandlerContext = {
27
+ /** The session this app connection is bound to (from the hello ack). */
28
+ sessionId: string;
29
+ /** The embedded app's id. */
30
+ appId: string;
31
+ /** Logger to emit through; defaults to the SDK's configured logger. */
32
+ log: AppLogger;
33
+ };
34
+ /**
35
+ * Author-facing arguments to {@link defineAppCapability}. Mirrors the wire
36
+ * {@link import("@skaile/workspaces/types").Capability} fields an app may set,
37
+ * minus `side` / `origin` (fixed / stamped by the SDK) and the runtime-only
38
+ * fields that only make sense platform-side.
39
+ *
40
+ * @category App SDK
41
+ * @since 3.4.0
42
+ */
43
+ export type DefineAppCapabilityArgs<T extends z.ZodTypeAny, R extends z.ZodTypeAny | undefined = undefined> = {
44
+ /**
45
+ * Stable, session-unique name. Convention: `app.<sector>.<verb>` — e.g.
46
+ * `app.ui.switch_contract` (UI sector) or `app.backend.insert_contract`
47
+ * (backend sector). v1 distinguishes sectors by this naming convention.
48
+ */
49
+ name: string;
50
+ /** Human-readable label for user-facing surfaces; falls back to `name`. */
51
+ displayName?: string;
52
+ /** Human/LLM-readable summary; shown to the agent at tool registration. */
53
+ description: string;
54
+ /** Zod schema validating the invocation arguments. Converted to JSON Schema. */
55
+ input: T;
56
+ /** Optional Zod schema for the return value. */
57
+ output?: R;
58
+ /** Lifetime: `session` survives the whole session, `turn` is dropped at end-of-turn. */
59
+ scope?: "session" | "turn";
60
+ /**
61
+ * When true, the platform shows a confirm UI and waits for user approval
62
+ * before the invocation is forwarded to the app. Mark every mutation
63
+ * (backend writes, destructive UI actions) with this.
64
+ */
65
+ requiresApproval?: boolean;
66
+ /** Documentation hint: side-effect, render, or pure query. */
67
+ kind?: "effect" | "render" | "query";
68
+ /**
69
+ * Audience scoping. Omit for the default (`['llm','user']`). App capabilities
70
+ * default to LLM-only in the command palette (`isUserInvokable`); set
71
+ * `['llm','user']` on the user-facing actions you want to appear in cmdK.
72
+ */
73
+ audience?: CapabilityAudience[];
74
+ /** Appended to the system prompt's `<CAPABILITIES>` section. */
75
+ promptFragment?: string;
76
+ /** Per-capability override for the platform's result round-trip timeout. */
77
+ callTimeoutMs?: number;
78
+ /** Render contract for capabilities that produce a UI surface. */
79
+ render?: RenderSpec;
80
+ /** The handler — runs in the app. Receives validated input + {@link AppHandlerContext}. */
81
+ handler: (args: z.infer<T>, ctx: AppHandlerContext) => Promise<R extends z.ZodTypeAny ? z.infer<R> : unknown>;
82
+ };
83
+ /**
84
+ * A defined app capability: the wire-format fields the SDK registers (minus the
85
+ * SDK-stamped `origin`), plus the Zod schemas and type-erased handler used for
86
+ * runtime input validation and inbound dispatch.
87
+ *
88
+ * @category App SDK
89
+ * @since 3.4.0
90
+ */
91
+ export type DefinedAppCapability = {
92
+ name: string;
93
+ displayName?: string;
94
+ description: string;
95
+ inputSchema: Record<string, unknown>;
96
+ outputSchema?: Record<string, unknown>;
97
+ /** Always `'app'` — the handler runs in the embedded app. */
98
+ side: "app";
99
+ scope?: "session" | "turn";
100
+ requiresApproval?: boolean;
101
+ kind?: "effect" | "render" | "query";
102
+ audience?: CapabilityAudience[];
103
+ promptFragment?: string;
104
+ callTimeoutMs?: number;
105
+ render?: RenderSpec;
106
+ /** Original Zod schema for runtime input validation. Not serialized to the wire. */
107
+ readonly inputZod: z.ZodTypeAny;
108
+ /** Original Zod schema for the optional output, if declared. Not serialized. */
109
+ readonly outputZod?: z.ZodTypeAny;
110
+ /** Type-erased handler dispatched on an inbound `capability_invoked`. */
111
+ handler: (args: unknown, ctx: AppHandlerContext) => Promise<unknown>;
112
+ };
113
+ /** Origin kind an app capability always carries once stamped by the SDK. */
114
+ export type AppCapabilityOrigin = Extract<CapabilityOrigin, {
115
+ kind: "app";
116
+ }>;
117
+ /**
118
+ * Build a {@link DefinedAppCapability} from author-friendly Zod-typed args.
119
+ * `side` is fixed to `'app'`; `origin` is added by the SDK at registration
120
+ * time (it needs the SDK's `appId`).
121
+ *
122
+ * @example
123
+ * ```ts
124
+ * const switchContract = defineAppCapability({
125
+ * name: 'app.ui.switch_contract',
126
+ * description: 'Switch the visible contract in the app UI.',
127
+ * input: z.object({ contractId: z.string() }),
128
+ * handler: async ({ contractId }, ctx) => {
129
+ * ctx.log.info('switching contract', { contractId });
130
+ * ui.select(contractId);
131
+ * },
132
+ * });
133
+ * ```
134
+ *
135
+ * @category App SDK
136
+ * @since 3.4.0
137
+ */
138
+ export declare function defineAppCapability<T extends z.ZodTypeAny, R extends z.ZodTypeAny | undefined = undefined>(args: DefineAppCapabilityArgs<T, R>): DefinedAppCapability;
139
+ //# sourceMappingURL=define-app-capability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-app-capability.d.ts","sourceRoot":"","sources":["../../../app-sdk/src/define-app-capability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `@skaile/workspaces/app-sdk` — the thin SDK an embedded app uses to become
3
+ * agent-controllable inside a Skaile session.
4
+ *
5
+ * See {@link createSkaileApp} for the entry point and the package README /
6
+ * the app-capability-source spec for the design.
7
+ *
8
+ * @category App SDK
9
+ * @since 3.4.0
10
+ */
11
+ export { AppHandshakeRefusedError, type AppSession, createSkaileApp, DEFAULT_HELLO_TIMEOUT_MS, type ReconnectOptions, type SkaileApp, type SkaileAppOptions, } from "./app.js";
12
+ export { type AppConnectionParams, type AppWindowLike, DEFAULT_PARAMS_TIMEOUT_MS, type MessageEventLike, PARENT_ORIGIN_QUERY_PARAM, type PostMessageTarget, resolveAppConnectionParams, type ResolveAppConnectionParamsOptions, type SkaileAppParamsMessage, type SkaileAppReadyMessage, } from "./connection-params.js";
13
+ export { type AppCapabilityOrigin, type AppHandlerContext, defineAppCapability, type DefineAppCapabilityArgs, type DefinedAppCapability, } from "./define-app-capability.js";
14
+ export { type AppLogger, consoleLogger, noopLogger } from "./logger.js";
15
+ export type { AppClientMessage, AppHelloAckMessage, AppHelloMessage, AppHelloNackMessage, AppServerMessage, AppTransport, } from "./transport.js";
16
+ export { createWebSocketAppTransport, type SessionTokenProvider, type WebSocketAppTransportOptions, type WebSocketFactory, } from "./ws-transport.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../app-sdk/src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,wBAAwB,EACxB,KAAK,UAAU,EACf,eAAe,EACf,wBAAwB,EACxB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,gBAAgB,GACtB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,yBAAyB,EACzB,KAAK,gBAAgB,EACrB,yBAAyB,EACzB,KAAK,iBAAiB,EACtB,0BAA0B,EAC1B,KAAK,iCAAiC,EACtC,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,mBAAmB,EACnB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,GAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,KAAK,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxE,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,2BAA2B,EAC3B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,GACtB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Minimal logger for the app SDK.
3
+ *
4
+ * The SDK is meant to run inside an embedded app (browser or a lightweight
5
+ * Node service), so it deliberately does not pull in the framework's
6
+ * `LogStore` / SQLite logging stack. Authors can pass their own {@link AppLogger}
7
+ * (e.g. a bridge to their app's telemetry) or accept the console-backed default.
8
+ *
9
+ * @category App SDK
10
+ * @since 3.4.0
11
+ */
12
+ /** Structured leveled logger the SDK and capability handlers emit through. */
13
+ export interface AppLogger {
14
+ debug(message: string, data?: unknown): void;
15
+ info(message: string, data?: unknown): void;
16
+ warn(message: string, data?: unknown): void;
17
+ error(message: string, data?: unknown): void;
18
+ }
19
+ /** A logger that discards everything. The default when none is supplied. */
20
+ export declare const noopLogger: AppLogger;
21
+ /**
22
+ * Console-backed logger, prefixing every line with `[skaile-app]`. Opt in by
23
+ * passing `logger: consoleLogger` to {@link createSkaileApp} during development.
24
+ */
25
+ export declare const consoleLogger: AppLogger;
26
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../app-sdk/src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,8EAA8E;AAC9E,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9C;AAED,4EAA4E;AAC5E,eAAO,MAAM,UAAU,EAAE,SAKxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,SAa3B,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * App-channel transport contract.
3
+ *
4
+ * An embedded, agent-controllable app talks to the Skaile platform gateway over
5
+ * a dedicated back-connection — a *different* surface from the agent protocol
6
+ * (`ClientTransport` / `ServerTransport` in `@skaile/workspaces/types`, which are
7
+ * typed to `AgentCommand` / `AgentEvent`). This channel carries only the app
8
+ * handshake plus the capability messages, so it gets its own small, decoupled
9
+ * transport interface. The SDK depends on {@link AppTransport}, never on a
10
+ * concrete socket, so tests inject a fake and the SDK stays browser-safe.
11
+ *
12
+ * The capability message *shapes* are reused verbatim from
13
+ * `@skaile/workspaces/types` — no new capability wire types are introduced.
14
+ * Only the connection handshake (`app_hello` / `app_hello_ack` /
15
+ * `app_hello_nack`) is new, and it is specific to this app↔gateway channel.
16
+ *
17
+ * @category App SDK
18
+ * @since 3.4.0
19
+ */
20
+ import type { CapabilityDeregisterCommand, CapabilityInvokedEvent, CapabilityRegisterCommand, CapabilityResultCommand } from "@skaile/workspaces/types";
21
+ /**
22
+ * First message an app sends after the socket opens. Declares which app this
23
+ * connection is; the *who* (session identity) is carried out-of-band by the
24
+ * connection's bearer credential (see {@link WebSocketAppTransportOptions}).
25
+ * The gateway binds the authenticated session to `appId` and replies with an
26
+ * {@link AppHelloAckMessage} (or refuses via {@link AppHelloNackMessage}).
27
+ */
28
+ export type AppHelloMessage = {
29
+ type: "app_hello";
30
+ /** The embedded app's stable id — bound to the authenticated session. */
31
+ appId: string;
32
+ /** Protocol version string the SDK speaks (see `PROTOCOL_VERSION_STRING`). */
33
+ protocolVersion: string;
34
+ };
35
+ /** Gateway acknowledgement that the app connection is bound and trusted. */
36
+ export type AppHelloAckMessage = {
37
+ type: "app_hello_ack";
38
+ /** The session this app connection is bound to. */
39
+ sessionId: string;
40
+ /** The session's owning user, when the gateway chooses to surface it. */
41
+ userId?: string;
42
+ };
43
+ /** Gateway refusal — identity could not be verified or `appId` is not permitted. */
44
+ export type AppHelloNackMessage = {
45
+ type: "app_hello_nack";
46
+ /** Human-readable reason (also surfaced to the app author). */
47
+ error: string;
48
+ /**
49
+ * Whether another attempt could succeed. `true` means the refusal is transient
50
+ * — the session's agent container is not up yet, and the app raced it on boot.
51
+ * Absent or `false` means permanent (bad token, `appId` not permitted): retrying
52
+ * only burns tokens.
53
+ *
54
+ * @since 3.5.0
55
+ */
56
+ retryable?: boolean;
57
+ };
58
+ /**
59
+ * Messages an app sends to the gateway. The three capability commands are the
60
+ * unchanged wire types from `@skaile/workspaces/types`; `app_hello` is the
61
+ * only channel-specific addition.
62
+ */
63
+ export type AppClientMessage = AppHelloMessage | CapabilityRegisterCommand | CapabilityDeregisterCommand | CapabilityResultCommand;
64
+ /**
65
+ * Messages the gateway sends to an app: the handshake outcome, then inbound
66
+ * `capability_invoked` events routed from the agent for this app's `side:'app'`
67
+ * capabilities.
68
+ */
69
+ export type AppServerMessage = AppHelloAckMessage | AppHelloNackMessage | CapabilityInvokedEvent;
70
+ /**
71
+ * The app back-connection transport. Mirrors the shape of the agent
72
+ * `ClientTransport` but is typed to the app channel's message unions. A
73
+ * concrete WebSocket implementation ships as {@link createWebSocketAppTransport};
74
+ * tests supply a fake.
75
+ *
76
+ * @category App SDK
77
+ * @since 3.4.0
78
+ */
79
+ export interface AppTransport {
80
+ /** Open the underlying connection. Resolves once the socket is ready. */
81
+ connect(): Promise<void>;
82
+ /** Close the connection and release resources. Idempotent. */
83
+ disconnect(): Promise<void>;
84
+ /** Send a message to the gateway. */
85
+ send(message: AppClientMessage): void;
86
+ /** Subscribe to messages from the gateway. Returns an unsubscribe function. */
87
+ onMessage(handler: (message: AppServerMessage) => void): () => void;
88
+ /** Subscribe to disconnects. Returns an unsubscribe function. */
89
+ onDisconnect(handler: () => void): () => void;
90
+ /** Whether the transport is currently connected. */
91
+ readonly connected: boolean;
92
+ }
93
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../app-sdk/src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,2BAA2B,EAC3B,sBAAsB,EACtB,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAElC;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oFAAoF;AACpF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,gBAAgB,CAAC;IACvB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GACxB,eAAe,GACf,yBAAyB,GACzB,2BAA2B,GAC3B,uBAAuB,CAAC;AAE5B;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG,mBAAmB,GAAG,sBAAsB,CAAC;AAEjG;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,8DAA8D;IAC9D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,qCAAqC;IACrC,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACtC,+EAA+E;IAC/E,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACpE,iEAAiE;IACjE,YAAY,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAC9C,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * WebSocket-backed {@link AppTransport}.
3
+ *
4
+ * Browser-safe: uses the standard `WebSocket` global (no `ws` dependency, no
5
+ * `node:*` imports), so it runs unchanged in an embedded app's iframe and in a
6
+ * lightweight Node 22+ service. The injected session identity is presented as a
7
+ * bearer **subprotocol** — the same `skaile-bearer.<base64url>` scheme the
8
+ * platform gateway already decodes for runner connections — so the gateway
9
+ * verifies identity at the WS upgrade, before any `app_hello` is processed.
10
+ *
11
+ * Frames are bare JSON of the app-channel messages (no `MessageV2` envelope),
12
+ * matching the runner peer's on-the-wire convention.
13
+ *
14
+ * @category App SDK
15
+ * @since 3.4.0
16
+ */
17
+ import type { AppTransport } from "./transport.js";
18
+ /** Minimal structural view of the parts of the `WebSocket` API the transport uses. */
19
+ type WebSocketLike = {
20
+ readonly readyState: number;
21
+ send(data: string): void;
22
+ close(code?: number, reason?: string): void;
23
+ addEventListener(type: "open", handler: () => void): void;
24
+ addEventListener(type: "close", handler: () => void): void;
25
+ addEventListener(type: "error", handler: () => void): void;
26
+ addEventListener(type: "message", handler: (ev: {
27
+ data: unknown;
28
+ }) => void): void;
29
+ };
30
+ /** Constructor shape for a `WebSocket` implementation (global or injected). */
31
+ export type WebSocketFactory = new (url: string, protocols?: string | string[]) => WebSocketLike;
32
+ /**
33
+ * Supplies a session identity token for one connection attempt.
34
+ *
35
+ * The gateway's token is **single-use** — it is consumed at `app_hello` — so a
36
+ * reconnecting transport cannot replay the one it opened with. Pass a provider
37
+ * (typically a call to `resolveAppConnectionParams`) and every `connect()` mints
38
+ * a fresh token.
39
+ *
40
+ * @category App SDK
41
+ * @since 3.5.0
42
+ */
43
+ export type SessionTokenProvider = () => string | Promise<string>;
44
+ /**
45
+ * Options for {@link createWebSocketAppTransport}.
46
+ *
47
+ * @category App SDK
48
+ * @since 3.4.0
49
+ */
50
+ export interface WebSocketAppTransportOptions {
51
+ /** The gateway app-channel URL (e.g. `wss://platform/app-connect`). */
52
+ url: string;
53
+ /**
54
+ * The injected session identity token, or a {@link SessionTokenProvider} that
55
+ * yields a fresh one per connection attempt. Presented as the WS bearer
56
+ * subprotocol; the gateway verifies it and resolves the session/user.
57
+ *
58
+ * A bare string cannot survive a reconnect (the gateway consumes the token at
59
+ * `app_hello`) — pass a provider whenever `reconnect` is enabled on the peer.
60
+ */
61
+ sessionToken: string | SessionTokenProvider;
62
+ /**
63
+ * WebSocket implementation. Defaults to the `WebSocket` global (browser /
64
+ * Node 22+). Injectable for tests or non-standard runtimes.
65
+ */
66
+ WebSocketImpl?: WebSocketFactory;
67
+ /** Connect timeout in ms. Default 10000. */
68
+ connectTimeoutMs?: number;
69
+ }
70
+ /**
71
+ * Create a WebSocket-backed {@link AppTransport}. The session token is sent as a
72
+ * bearer subprotocol at connect time; app-channel messages are JSON-framed.
73
+ *
74
+ * @category App SDK
75
+ * @since 3.4.0
76
+ */
77
+ export declare function createWebSocketAppTransport(options: WebSocketAppTransportOptions): AppTransport;
78
+ export {};
79
+ //# sourceMappingURL=ws-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-transport.d.ts","sourceRoot":"","sources":["../../../app-sdk/src/ws-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAsC,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAcvF,sFAAsF;AACtF,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC1D,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC3D,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC3D,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI,CAAC;CACnF,CAAC;AAEF,+EAA+E;AAC/E,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,aAAa,CAAC;AAEjG;;;;;;;;;;GAUG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,WAAW,4BAA4B;IAC3C,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,GAAG,oBAAoB,CAAC;IAC5C;;;OAGG;IACH,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAID;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,4BAA4B,GAAG,YAAY,CA0F/F"}