akanjs 3.0.2 → 3.1.0-rc.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 (378) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/base/baseEnv.ts +0 -4
  3. package/base/primitiveRegistry.ts +2 -2
  4. package/client/cookie.ts +5 -1
  5. package/client/csrLocation.ts +122 -0
  6. package/client/csrTypes.ts +32 -4
  7. package/client/device.ts +2 -1
  8. package/client/frameConfig.ts +78 -7
  9. package/client/index.ts +3 -0
  10. package/client/makePageProto.tsx +3 -2
  11. package/client/native/external-view.ts +1 -0
  12. package/client/route/RootLayoutDefinition.ts +7 -1
  13. package/client/route/RouteHead.ts +108 -0
  14. package/client/route/index.ts +1 -0
  15. package/client/router.ts +36 -23
  16. package/client/rscNavigation.ts +8 -2
  17. package/client/viewportMeta.ts +60 -0
  18. package/client/webManifest.ts +18 -0
  19. package/common/Logger.ts +7 -2
  20. package/common/PipelineNames.ts +31 -0
  21. package/common/PipelinePattern.ts +70 -0
  22. package/common/PipelinePlanSchema.ts +490 -0
  23. package/common/backoff.ts +14 -0
  24. package/common/index.ts +39 -0
  25. package/common/pipelinePlan.ts +259 -0
  26. package/common/routeConvention.ts +1 -0
  27. package/common/types.ts +17 -0
  28. package/constant/constantRegistry.ts +26 -6
  29. package/dictionary/base.dictionary.ts +8 -0
  30. package/dictionary/trans.ts +9 -1
  31. package/document/into.ts +5 -0
  32. package/fetch/client/fetchClient.ts +135 -31
  33. package/fetch/client/httpClient.ts +45 -0
  34. package/fetch/client/wsClient.ts +125 -16
  35. package/fetch/fetchType/buildFetch.type.ts +1 -0
  36. package/index.ts +243 -10
  37. package/package.json +1 -5
  38. package/server/akanApp.ts +5 -2
  39. package/server/akanServer.ts +44 -8
  40. package/server/artifact/builderRpc.ts +8 -3
  41. package/server/artifact/ipcTypes.ts +5 -2
  42. package/server/di/diLifecycle.ts +39 -3
  43. package/server/di/utils.ts +28 -1
  44. package/server/ed25519Key.ts +48 -0
  45. package/server/index.ts +1 -0
  46. package/server/machine/index.ts +2 -0
  47. package/server/machine/machineAccount.ts +27 -0
  48. package/server/machine/machineToken.ts +151 -0
  49. package/server/mcp/McpApps.ts +256 -0
  50. package/server/mcp/McpDispatcher.ts +31 -7
  51. package/server/mcp/McpRouter.ts +209 -46
  52. package/server/ops/opsToken.ts +3 -10
  53. package/server/resolver/database.resolver.ts +3 -0
  54. package/server/resolver/signal.resolver.ts +40 -3
  55. package/server/routeElementComposer.tsx +78 -2
  56. package/server/routeState.ts +6 -0
  57. package/server/routeTreeBuilder.ts +26 -9
  58. package/server/routing/apiRouter.ts +6 -3
  59. package/server/routing/roomReplay.ts +88 -0
  60. package/server/rscClient.tsx +53 -8
  61. package/server/rscWorker.tsx +141 -27
  62. package/server/rscWorkerHost.ts +18 -5
  63. package/server/sitemap.ts +14 -0
  64. package/server/ssrFromRscRenderer.tsx +12 -6
  65. package/server/ssrTypes.ts +3 -1
  66. package/server/systemPageDocument.tsx +38 -30
  67. package/server/types.tsx +2 -0
  68. package/server/webRouter.ts +74 -5
  69. package/service/injectInfo.ts +9 -1
  70. package/service/ipcTypes.ts +2 -1
  71. package/service/predefinedAdaptor/database.adaptor.ts +1 -146
  72. package/service/predefinedAdaptor/queue.adaptor.ts +44 -6
  73. package/service/predefinedAdaptor/queueBackoff.ts +12 -0
  74. package/service/predefinedAdaptor/solidQueue.adaptor.ts +17 -13
  75. package/service/predefinedAdaptor/sql/SqlDocumentStore.ts +44 -2
  76. package/service/predefinedAdaptor/sql/dialect/postgres.ts +3 -0
  77. package/service/predefinedAdaptor/sql/dialect/sqlite.ts +5 -2
  78. package/service/predefinedAdaptor/sql/search/fts5.ts +1 -1
  79. package/service/predefinedAdaptor/sql/types.ts +8 -6
  80. package/service/predefinedAdaptor/sql/values.ts +0 -23
  81. package/service/serve.ts +5 -1
  82. package/signal/agent.signal.ts +1 -1
  83. package/signal/base.signal.ts +2 -2
  84. package/signal/endpointIdempotency.ts +53 -0
  85. package/signal/internalArg.ts +14 -0
  86. package/signal/mcp/McpDocument.ts +38 -1
  87. package/signal/mcp/mcpProtocol.ts +18 -0
  88. package/signal/signalContext.ts +58 -30
  89. package/signal/signalRegistry.ts +14 -4
  90. package/signal/types.ts +18 -3
  91. package/store/agent/StoreSurfaceSource.ts +1 -1
  92. package/store/agentic/StToolBuilder.ts +3 -0
  93. package/test/conformance.ts +9 -33
  94. package/types/base/baseEnv.d.ts +0 -4
  95. package/types/base/primitiveRegistry.d.ts +1 -1
  96. package/types/client/csrLocation.d.ts +32 -0
  97. package/types/client/csrTypes.d.ts +40 -4
  98. package/types/client/frameConfig.d.ts +14 -2
  99. package/types/client/index.d.ts +3 -0
  100. package/types/client/native/external-view.d.ts +1 -0
  101. package/types/client/route/RootLayoutDefinition.d.ts +2 -1
  102. package/types/client/route/RouteHead.d.ts +13 -0
  103. package/types/client/route/index.d.ts +1 -0
  104. package/types/client/router.d.ts +6 -0
  105. package/types/client/rscNavigation.d.ts +4 -0
  106. package/types/client/viewportMeta.d.ts +18 -0
  107. package/types/client/webManifest.d.ts +4 -0
  108. package/types/common/PipelineNames.d.ts +6 -0
  109. package/types/common/PipelinePattern.d.ts +14 -0
  110. package/types/common/PipelinePlanSchema.d.ts +9 -0
  111. package/types/common/backoff.d.ts +10 -0
  112. package/types/common/index.d.ts +5 -0
  113. package/types/common/pipelinePlan.d.ts +224 -0
  114. package/types/common/types.d.ts +16 -0
  115. package/types/constant/constantRegistry.d.ts +5 -2
  116. package/types/dictionary/base.dictionary.d.ts +1 -1
  117. package/types/dictionary/dictionary.d.ts +8 -8
  118. package/types/document/into.d.ts +9 -0
  119. package/types/fetch/client/fetchClient.d.ts +31 -4
  120. package/types/fetch/client/httpClient.d.ts +8 -0
  121. package/types/fetch/client/wsClient.d.ts +26 -2
  122. package/types/fetch/fetchType/buildFetch.type.d.ts +1 -0
  123. package/types/index.d.ts +230 -9
  124. package/types/server/akanServer.d.ts +16 -1
  125. package/types/server/artifact/builderRpc.d.ts +7 -2
  126. package/types/server/artifact/ipcTypes.d.ts +5 -1
  127. package/types/server/di/utils.d.ts +1 -0
  128. package/types/server/ed25519Key.d.ts +13 -0
  129. package/types/server/index.d.ts +1 -0
  130. package/types/server/machine/index.d.ts +2 -0
  131. package/types/server/machine/machineAccount.d.ts +5 -0
  132. package/types/server/machine/machineToken.d.ts +29 -0
  133. package/types/server/machine.d.ts +1 -0
  134. package/types/server/mcp/McpApps.d.ts +50 -0
  135. package/types/server/mcp/McpDispatcher.d.ts +4 -1
  136. package/types/server/mcp/McpRouter.d.ts +4 -0
  137. package/types/server/resolver/signal.resolver.d.ts +2 -1
  138. package/types/server/routeElementComposer.d.ts +24 -4
  139. package/types/server/routeState.d.ts +4 -1
  140. package/types/server/routing/roomReplay.d.ts +24 -0
  141. package/types/server/rscWorkerHost.d.ts +5 -2
  142. package/types/server/sitemap.d.ts +2 -0
  143. package/types/server/ssrFromRscRenderer.d.ts +3 -3
  144. package/types/server/ssrTypes.d.ts +4 -1
  145. package/types/server/systemPageDocument.d.ts +2 -0
  146. package/types/server/types.d.ts +4 -1
  147. package/types/server/webRouter.d.ts +3 -1
  148. package/types/service/ipcTypes.d.ts +2 -0
  149. package/types/service/predefinedAdaptor/database.adaptor.d.ts +1 -24
  150. package/types/service/predefinedAdaptor/queue.adaptor.d.ts +10 -3
  151. package/types/service/predefinedAdaptor/queueBackoff.d.ts +4 -0
  152. package/types/service/predefinedAdaptor/solidQueue.adaptor.d.ts +3 -3
  153. package/types/service/predefinedAdaptor/sql/SqlDocumentStore.d.ts +6 -1
  154. package/types/service/predefinedAdaptor/sql/dialect/postgres.d.ts +1 -0
  155. package/types/service/predefinedAdaptor/sql/dialect/sqlite.d.ts +1 -0
  156. package/types/service/predefinedAdaptor/sql/search/fts5.d.ts +1 -1
  157. package/types/service/predefinedAdaptor/sql/types.d.ts +9 -5
  158. package/types/service/predefinedAdaptor/sql/values.d.ts +0 -3
  159. package/types/service/serve.d.ts +3 -0
  160. package/types/signal/endpointIdempotency.d.ts +7 -0
  161. package/types/signal/internalArg.d.ts +10 -0
  162. package/types/signal/mcp/McpDocument.d.ts +8 -0
  163. package/types/signal/mcp/mcpProtocol.d.ts +17 -0
  164. package/types/signal/signalContext.d.ts +5 -3
  165. package/types/signal/signalRegistry.d.ts +4 -4
  166. package/types/signal/types.d.ts +21 -1
  167. package/types/store/agentic/StToolBuilder.d.ts +2 -0
  168. package/types/test/conformance.d.ts +7 -10
  169. package/types/ui/Agent/Chat.d.ts +5 -1
  170. package/types/ui/Agent/EmbedApproval.d.ts +1 -0
  171. package/types/ui/Agent/index.d.ts +3 -0
  172. package/types/ui/Agent/useKeyboardFrame.d.ts +2 -0
  173. package/types/ui/Agent/useScreenActions.d.ts +18 -0
  174. package/types/ui/BottomSheet.d.ts +1 -0
  175. package/types/ui/Constant/Doc.d.ts +11 -17
  176. package/types/ui/Constant/index.d.ts +7 -2
  177. package/types/ui/Constant/schemaDoc.d.ts +11 -0
  178. package/types/ui/Dialog/Modal.d.ts +6 -1
  179. package/types/ui/Dialog/index.d.ts +1 -1
  180. package/types/ui/Dialog/modalSurface.d.ts +12 -0
  181. package/types/ui/Layout/BottomTab.d.ts +11 -2
  182. package/types/ui/Layout/FrameSlotFallback.d.ts +9 -0
  183. package/types/ui/Layout/Navbar.d.ts +4 -1
  184. package/types/ui/Layout/TopInset.d.ts +1 -1
  185. package/types/ui/Layout/index.d.ts +3 -3
  186. package/types/ui/Link/Action.d.ts +5 -1
  187. package/types/ui/Link/Anchor.d.ts +5 -3
  188. package/types/ui/Link/activePath.d.ts +13 -0
  189. package/types/ui/Link/index.d.ts +1 -1
  190. package/types/ui/Modal.d.ts +6 -1
  191. package/types/ui/Model/EditModal.d.ts +6 -1
  192. package/types/ui/Model/New.d.ts +6 -1
  193. package/types/ui/Model/ViewEditModal.d.ts +6 -1
  194. package/types/ui/Model/ViewModal.d.ts +6 -1
  195. package/types/ui/Model/newFormOrigin.d.ts +7 -0
  196. package/types/ui/Portal.d.ts +3 -1
  197. package/types/ui/Reference/origin.d.ts +12 -0
  198. package/types/ui/Signal/Doc.d.ts +23 -18
  199. package/types/ui/Signal/Listener.d.ts +2 -6
  200. package/types/ui/Signal/Object.d.ts +6 -10
  201. package/types/ui/Signal/Response.d.ts +3 -6
  202. package/types/ui/Signal/RestApi.d.ts +11 -15
  203. package/types/ui/Signal/WebSocket.d.ts +11 -21
  204. package/types/ui/Signal/endpointEntries.d.ts +8 -0
  205. package/types/ui/Signal/index.d.ts +35 -12
  206. package/types/ui/Signal/signalText.d.ts +178 -0
  207. package/types/ui/System/CSR.d.ts +2 -2
  208. package/types/ui/System/Client.d.ts +4 -3
  209. package/types/ui/System/Common.d.ts +27 -6
  210. package/types/ui/System/SSR.d.ts +6 -6
  211. package/types/ui/Tooltip.d.ts +4 -2
  212. package/types/ui/index.d.ts +2 -1
  213. package/types/ui/overlayLayer.d.ts +6 -0
  214. package/types/ui/overlayPosition.d.ts +17 -0
  215. package/types/vendor/@akanjs/native/packages/cli/src/api.d.ts +14 -3
  216. package/types/vendor/@akanjs/native/packages/cli/src/commands/update.d.ts +1 -1
  217. package/types/vendor/@akanjs/native/packages/cli/src/config.d.ts +30 -5
  218. package/types/vendor/@akanjs/native/packages/cli/src/lib/compat.d.ts +8 -0
  219. package/types/vendor/@akanjs/native/packages/cli/src/lib/desktop-server.d.ts +5 -0
  220. package/types/vendor/@akanjs/native/packages/cli/src/lib/distribution.d.ts +22 -0
  221. package/types/vendor/@akanjs/native/packages/cli/src/lib/project.d.ts +4 -0
  222. package/types/vendor/@akanjs/native/packages/cli/src/lib/publish.d.ts +16 -10
  223. package/types/vendor/@akanjs/native/packages/cli/src/lib/updates.d.ts +51 -7
  224. package/types/vendor/@akanjs/native/packages/cli/src/lib/vectors.d.ts +1 -1
  225. package/types/vendor/@akanjs/native/packages/cli/src/platforms/windows-installer.d.ts +7 -0
  226. package/types/vendor/@akanjs/native/packages/cli/src/platforms/windows.d.ts +5 -0
  227. package/types/vendor/@akanjs/native/packages/core/src/kernel.d.ts +36 -0
  228. package/types/vendor/@akanjs/native/packages/desktop/src/plugin.d.ts +2 -0
  229. package/types/vendor/@akanjs/native/packages/desktop/src/server.d.ts +11 -0
  230. package/types/vendor/@akanjs/native/plugins/external-view/src/desktop.d.ts +17 -0
  231. package/types/vendor/@akanjs/native/plugins/external-view/src/index.d.ts +132 -0
  232. package/types/vendor/@akanjs/native/plugins/external-view/src.d.ts +1 -0
  233. package/types/vendor/@akanjs/native/plugins/updates/src/index.d.ts +8 -0
  234. package/types/vendor/@akanjs/native/plugins/window/src/desktop.d.ts +4 -1
  235. package/types/vendor/@akanjs/native/plugins/window/src/index.d.ts +49 -0
  236. package/types/vendor/use-agentic/types.d.ts +2 -0
  237. package/types/webkit/CsrStack.d.ts +1 -1
  238. package/types/webkit/McpAppAgent.d.ts +14 -0
  239. package/types/webkit/McpAppApprovals.d.ts +8 -0
  240. package/types/webkit/McpAppBridge.d.ts +101 -0
  241. package/types/webkit/McpAppView.d.ts +21 -0
  242. package/types/webkit/index.d.ts +1 -0
  243. package/types/webkit/useLocation.d.ts +1 -1
  244. package/types/webkit/useVisualViewportFrame.d.ts +13 -0
  245. package/ui/Agent/Chat.tsx +29 -10
  246. package/ui/Agent/Composer.tsx +2 -1
  247. package/ui/Agent/EmbedApproval.tsx +17 -0
  248. package/ui/Agent/RichInput.tsx +1 -1
  249. package/ui/Agent/index.ts +2 -0
  250. package/ui/Agent/useKeyboardFrame.ts +10 -0
  251. package/ui/Agent/useScreenActions.ts +45 -0
  252. package/ui/BottomSheet.tsx +82 -53
  253. package/ui/Constant/Doc.tsx +113 -60
  254. package/ui/Constant/index.ts +2 -2
  255. package/ui/Constant/schemaDoc.ts +86 -26
  256. package/ui/Dialog/LegacyModal.tsx +53 -52
  257. package/ui/Dialog/Modal.tsx +93 -49
  258. package/ui/Dialog/modalSurface.ts +61 -0
  259. package/ui/DragAction.tsx +1 -1
  260. package/ui/DraggableList.tsx +1 -1
  261. package/ui/Dropdown.tsx +4 -6
  262. package/ui/KeyboardAvoiding.tsx +1 -1
  263. package/ui/Layout/BottomInset.tsx +20 -14
  264. package/ui/Layout/BottomTab.tsx +42 -16
  265. package/ui/Layout/FrameSlotFallback.tsx +59 -0
  266. package/ui/Layout/Navbar.tsx +37 -11
  267. package/ui/Layout/Sider.tsx +1 -1
  268. package/ui/Layout/TopInset.tsx +15 -14
  269. package/ui/Link/Action.tsx +15 -5
  270. package/ui/Link/Anchor.tsx +25 -13
  271. package/ui/Link/activePath.ts +25 -0
  272. package/ui/Link/index.tsx +1 -1
  273. package/ui/Load/Pagination.tsx +1 -1
  274. package/ui/Load/Units.tsx +1 -1
  275. package/ui/Loading/ProgressBar.tsx +1 -1
  276. package/ui/Modal.tsx +9 -0
  277. package/ui/Model/EditModal.tsx +16 -1
  278. package/ui/Model/New.tsx +25 -2
  279. package/ui/Model/NewWrapper_Client.tsx +2 -0
  280. package/ui/Model/ViewEditModal.tsx +9 -0
  281. package/ui/Model/ViewModal.tsx +16 -1
  282. package/ui/Model/newFormOrigin.ts +45 -0
  283. package/ui/Popconfirm.tsx +5 -7
  284. package/ui/Portal.tsx +4 -7
  285. package/ui/Reference/origin.ts +31 -0
  286. package/ui/ScreenNavigator.tsx +1 -1
  287. package/ui/Select.tsx +2 -7
  288. package/ui/Signal/Arg.tsx +2 -2
  289. package/ui/Signal/Doc.tsx +125 -63
  290. package/ui/Signal/Endpoint.tsx +11 -10
  291. package/ui/Signal/Listener.tsx +7 -10
  292. package/ui/Signal/Object.tsx +7 -14
  293. package/ui/Signal/Response.tsx +24 -24
  294. package/ui/Signal/RestApi.tsx +63 -52
  295. package/ui/Signal/WebSocket.tsx +65 -72
  296. package/ui/Signal/endpointEntries.ts +25 -0
  297. package/ui/Signal/index.ts +23 -6
  298. package/ui/Signal/signalText.ts +59 -0
  299. package/ui/System/CSR.tsx +34 -8
  300. package/ui/System/Client.tsx +36 -5
  301. package/ui/System/Common.tsx +76 -32
  302. package/ui/System/SSR.tsx +73 -31
  303. package/ui/Toast.tsx +1 -1
  304. package/ui/Tooltip.tsx +84 -30
  305. package/ui/index.ts +11 -1
  306. package/ui/overlayLayer.ts +25 -2
  307. package/ui/overlayPosition.ts +90 -0
  308. package/ui/recipe/inputRecipe.ts +8 -1
  309. package/ui/styles.css +152 -0
  310. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeActivity.kt +22 -2
  311. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeKernel.kt +37 -0
  312. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeUpdateReports.kt +169 -0
  313. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeUpdates.kt +110 -38
  314. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeVectors.kt +20 -0
  315. package/vendor/@akanjs/native/native/desktop/Cargo.lock +16 -16
  316. package/vendor/@akanjs/native/native/desktop/src/external.rs +651 -0
  317. package/vendor/@akanjs/native/native/desktop/src/json.rs +23 -0
  318. package/vendor/@akanjs/native/native/desktop/src/lib.rs +228 -5
  319. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeApp.swift +2 -1
  320. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeKernel.swift +47 -1
  321. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeUpdateReports.swift +145 -0
  322. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeUpdates.swift +112 -43
  323. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeVectors.swift +18 -0
  324. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeViewController.swift +24 -2
  325. package/vendor/@akanjs/native/packages/cli/src/api.ts +22 -6
  326. package/vendor/@akanjs/native/packages/cli/src/commands/build.ts +24 -8
  327. package/vendor/@akanjs/native/packages/cli/src/commands/update.ts +11 -9
  328. package/vendor/@akanjs/native/packages/cli/src/config.ts +35 -7
  329. package/vendor/@akanjs/native/packages/cli/src/lib/compat.ts +2 -0
  330. package/vendor/@akanjs/native/packages/cli/src/lib/configkeys.ts +6 -4
  331. package/vendor/@akanjs/native/packages/cli/src/lib/desktop-server.ts +11 -1
  332. package/vendor/@akanjs/native/packages/cli/src/lib/distribution.ts +73 -0
  333. package/vendor/@akanjs/native/packages/cli/src/lib/project.ts +15 -3
  334. package/vendor/@akanjs/native/packages/cli/src/lib/publish.ts +70 -23
  335. package/vendor/@akanjs/native/packages/cli/src/lib/updates.ts +159 -23
  336. package/vendor/@akanjs/native/packages/cli/src/lib/vectors.ts +2 -0
  337. package/vendor/@akanjs/native/packages/cli/src/platforms/android.ts +9 -4
  338. package/vendor/@akanjs/native/packages/cli/src/platforms/desktop-update.ts +1 -1
  339. package/vendor/@akanjs/native/packages/cli/src/platforms/desktop.ts +4 -2
  340. package/vendor/@akanjs/native/packages/cli/src/platforms/ios.ts +9 -4
  341. package/vendor/@akanjs/native/packages/cli/src/platforms/windows-installer.ts +25 -11
  342. package/vendor/@akanjs/native/packages/cli/src/platforms/windows.ts +14 -3
  343. package/vendor/@akanjs/native/packages/core/src/kernel.ts +49 -0
  344. package/vendor/@akanjs/native/packages/core/vectors/updates.json +31 -0
  345. package/vendor/@akanjs/native/packages/desktop/src/main.ts +3 -0
  346. package/vendor/@akanjs/native/packages/desktop/src/plugin.ts +2 -0
  347. package/vendor/@akanjs/native/packages/desktop/src/server.ts +70 -6
  348. package/vendor/@akanjs/native/plugins/external-view/native-plugin.json +23 -0
  349. package/vendor/@akanjs/native/plugins/external-view/src/desktop.ts +321 -0
  350. package/vendor/@akanjs/native/plugins/external-view/src/index.ts +106 -0
  351. package/vendor/@akanjs/native/plugins/updates/android/UpdatesPlugin.kt +133 -41
  352. package/vendor/@akanjs/native/plugins/updates/ios/UpdatesPlugin.swift +101 -36
  353. package/vendor/@akanjs/native/plugins/updates/native-plugin.json +4 -2
  354. package/vendor/@akanjs/native/plugins/updates/src/desktop.ts +15 -1
  355. package/vendor/@akanjs/native/plugins/updates/src/index.ts +7 -1
  356. package/vendor/@akanjs/native/plugins/window/native-plugin.json +4 -0
  357. package/vendor/@akanjs/native/plugins/window/src/desktop.ts +68 -1
  358. package/vendor/@akanjs/native/plugins/window/src/index.ts +47 -0
  359. package/vendor/use-agentic/ToolRunner.ts +8 -1
  360. package/vendor/use-agentic/types.ts +2 -0
  361. package/webkit/CsrRouteTable.ts +1 -0
  362. package/webkit/CsrStack.ts +9 -2
  363. package/webkit/McpAppAgent.ts +138 -0
  364. package/webkit/McpAppApprovals.ts +56 -0
  365. package/webkit/McpAppBridge.ts +291 -0
  366. package/webkit/McpAppView.ts +258 -0
  367. package/webkit/bootCsr.tsx +54 -5
  368. package/webkit/index.ts +1 -0
  369. package/webkit/useCsrValues.ts +16 -10
  370. package/webkit/useFrameRuntime.ts +10 -1
  371. package/webkit/useLocation.ts +4 -3
  372. package/webkit/useVisualViewportFrame.tsx +52 -0
  373. package/service/predefinedAdaptor/sql/driver/libsql.ts +0 -45
  374. package/types/service/predefinedAdaptor/sql/driver/libsql.d.ts +0 -20
  375. package/types/ui/Agent/useKeyboardInset.d.ts +0 -1
  376. package/types/ui/ServerPortal.d.ts +0 -15
  377. package/ui/Agent/useKeyboardInset.ts +0 -19
  378. package/ui/ServerPortal.tsx +0 -49
@@ -0,0 +1,490 @@
1
+ import { PipelineNames } from "./PipelineNames";
2
+ import { PipelinePattern } from "./PipelinePattern";
3
+ import {
4
+ type PipelineActionName,
5
+ type PipelineDiagnostic,
6
+ type PipelinePlan,
7
+ type PipelinePlanActionStep,
8
+ type PipelinePlanContext,
9
+ type PipelinePlanOtaStep,
10
+ type PipelinePlanPhase,
11
+ type PipelinePlanPost,
12
+ type PipelinePlanResult,
13
+ type PipelinePlanRetry,
14
+ type PipelinePlanShellStep,
15
+ type PipelinePlanSource,
16
+ type PipelinePlanStage,
17
+ type PipelinePlanStep,
18
+ pipelineActionNames,
19
+ pipelineActions,
20
+ pipelineMilestones,
21
+ pipelineOtaPlatforms,
22
+ pipelinePlanLimits,
23
+ pipelinePlanSlots,
24
+ pipelinePlanVersion,
25
+ pipelineTriggers,
26
+ } from "./pipelinePlan";
27
+
28
+ type JsonObject = Record<string, unknown>;
29
+
30
+ /** Strict: an unknown key, kind, action or version is refused, never ignored. Structure only, no executor policy. */
31
+ export class PipelinePlanSchema {
32
+ static readonly #stageIdPattern = /^[A-Za-z0-9][A-Za-z0-9_-]*(?:[:.][A-Za-z0-9][A-Za-z0-9_-]*)*$/;
33
+ static readonly #stepIdPattern = /^[A-Za-z0-9][A-Za-z0-9_.:/-]*$/;
34
+ static readonly #sha256Pattern = /^[0-9a-f]{64}$/;
35
+ static readonly #idChars = 256;
36
+ static readonly #textChars = 1024;
37
+ static readonly #maxSeconds = 86_400;
38
+ static readonly #shellKeys = [
39
+ "id",
40
+ "name",
41
+ "timeoutSeconds",
42
+ "retry",
43
+ "allowFailure",
44
+ "kind",
45
+ "run",
46
+ "cwd",
47
+ "env",
48
+ "secrets",
49
+ "skipExitCodes",
50
+ ] as const;
51
+ static readonly #actionKeys = [
52
+ "id",
53
+ "name",
54
+ "timeoutSeconds",
55
+ "retry",
56
+ "allowFailure",
57
+ "kind",
58
+ "action",
59
+ "actionVersion",
60
+ "with",
61
+ ] as const;
62
+
63
+ /** What an executor reads off `--out`: the size is checked before the text is parsed. */
64
+ static parseText(text: string): PipelinePlanResult {
65
+ const bytes = new TextEncoder().encode(text).length;
66
+ if (bytes > pipelinePlanLimits.planBytes)
67
+ throw new Error(`pipeline plan: ${bytes} bytes is over the ${pipelinePlanLimits.planBytes}-byte limit`);
68
+ let value: unknown;
69
+ try {
70
+ value = JSON.parse(text);
71
+ } catch (error) {
72
+ throw new Error(`pipeline plan: not JSON (${error instanceof Error ? error.message : String(error)})`);
73
+ }
74
+ return PipelinePlanSchema.parseResult(value);
75
+ }
76
+
77
+ static parseResult(value: unknown): PipelinePlanResult {
78
+ return new PipelinePlanSchema().#result(value);
79
+ }
80
+
81
+ static parse(value: unknown): PipelinePlan {
82
+ return new PipelinePlanSchema().#plan(value, "plan");
83
+ }
84
+
85
+ readonly #phaseIds = new Set<string>();
86
+ readonly #stageIds = new Set<string>();
87
+ readonly #stepIds = new Set<string>();
88
+ readonly #stepSecrets = new Set<string>();
89
+ #apps = new Set<string>();
90
+ #stageCount = 0;
91
+ #stepCount = 0;
92
+
93
+ #result(value: unknown): PipelinePlanResult {
94
+ const result = this.#object(value, "result", ["ok", "plan", "diagnostics"]);
95
+ const ok = this.#boolean(result.ok, "result.ok");
96
+ const diagnostics = this.#array(result.diagnostics, "result.diagnostics").map((item, idx) =>
97
+ this.#diagnostic(item, `result.diagnostics[${idx}]`),
98
+ );
99
+ if (ok) return { ok, plan: this.#plan(result.plan, "result.plan"), diagnostics };
100
+ if (result.plan !== null) this.#fail("result.plan", "must be null when ok is false");
101
+ if (!diagnostics.some((diagnostic) => diagnostic.severity === "error"))
102
+ this.#fail("result.diagnostics", "must hold an error when ok is false");
103
+ return { ok, plan: null, diagnostics };
104
+ }
105
+
106
+ #diagnostic(value: unknown, path: string): PipelineDiagnostic {
107
+ const diagnostic = this.#object(value, path, ["severity", "code", "message", "file", "path"]);
108
+ return {
109
+ severity: this.#oneOf(diagnostic.severity, `${path}.severity`, ["error", "warning"] as const),
110
+ code: this.#string(diagnostic.code, `${path}.code`),
111
+ message: this.#string(diagnostic.message, `${path}.message`, pipelinePlanLimits.shBytes),
112
+ file: this.#nullable(diagnostic.file, (file) => this.#string(file, `${path}.file`)),
113
+ path: this.#nullable(diagnostic.path, (where) => this.#string(where, `${path}.path`)),
114
+ };
115
+ }
116
+
117
+ #plan(value: unknown, path: string): PipelinePlan {
118
+ const plan = this.#object(value, path, [
119
+ "schemaVersion",
120
+ "sources",
121
+ "planner",
122
+ "context",
123
+ "appOrder",
124
+ "timeoutSeconds",
125
+ "requiredSecrets",
126
+ "phases",
127
+ "post",
128
+ ]);
129
+ if (plan.schemaVersion !== pipelinePlanVersion)
130
+ this.#fail(
131
+ `${path}.schemaVersion`,
132
+ `${JSON.stringify(plan.schemaVersion)} is not version ${pipelinePlanVersion}`,
133
+ );
134
+ const context = this.#context(plan.context, `${path}.context`);
135
+ this.#apps = new Set(context.apps);
136
+ const appOrder = this.#stringList(plan.appOrder, `${path}.appOrder`);
137
+ if (
138
+ appOrder.length !== context.apps.length ||
139
+ new Set(appOrder).size !== appOrder.length ||
140
+ appOrder.some((app) => !this.#apps.has(app))
141
+ )
142
+ this.#fail(`${path}.appOrder`, "must order exactly the apps of context.apps");
143
+ const planner = this.#object(plan.planner, `${path}.planner`, ["akanVersion"]);
144
+ const sources = this.#sources(plan.sources, `${path}.sources`);
145
+ const phases = this.#array(plan.phases, `${path}.phases`, pipelinePlanLimits.phases).map((phase, idx) =>
146
+ this.#phase(phase, `${path}.phases[${idx}]`),
147
+ );
148
+ const post = this.#post(plan.post, `${path}.post`);
149
+ const requiredSecrets = this.#secretList(plan.requiredSecrets, `${path}.requiredSecrets`);
150
+ if (
151
+ requiredSecrets.length !== this.#stepSecrets.size ||
152
+ requiredSecrets.some((name) => !this.#stepSecrets.has(name))
153
+ )
154
+ this.#fail(`${path}.requiredSecrets`, "must list exactly the secrets its steps name");
155
+ return {
156
+ schemaVersion: pipelinePlanVersion,
157
+ sources,
158
+ planner: { akanVersion: this.#string(planner.akanVersion, `${path}.planner.akanVersion`) },
159
+ context,
160
+ appOrder,
161
+ timeoutSeconds: this.#seconds(plan.timeoutSeconds, `${path}.timeoutSeconds`),
162
+ requiredSecrets,
163
+ phases,
164
+ post,
165
+ };
166
+ }
167
+
168
+ #sources(value: unknown, path: string): PipelinePlan["sources"] {
169
+ const sources = this.#object(value, path, ["workspace", "apps"]);
170
+ const apps = this.#object(sources.apps, `${path}.apps`);
171
+ return {
172
+ workspace: this.#nullable(sources.workspace, (source) => this.#source(source, `${path}.workspace`)),
173
+ apps: Object.fromEntries(
174
+ Object.entries(apps).map(([app, source]) => [app, this.#source(source, `${path}.apps.${app}`)]),
175
+ ),
176
+ };
177
+ }
178
+
179
+ #source(value: unknown, path: string): PipelinePlanSource {
180
+ const source = this.#object(value, path, ["file", "sha256", "declared"]);
181
+ const sha256 = this.#string(source.sha256, `${path}.sha256`);
182
+ if (!PipelinePlanSchema.#sha256Pattern.test(sha256)) this.#fail(`${path}.sha256`, "must be a lowercase sha256");
183
+ return {
184
+ file: this.#string(source.file, `${path}.file`),
185
+ sha256,
186
+ declared: this.#boolean(source.declared, `${path}.declared`),
187
+ };
188
+ }
189
+
190
+ #context(value: unknown, path: string): PipelinePlanContext {
191
+ const context = this.#object(value, path, ["branch", "env", "apps", "trigger", "buildNum", "commit"]);
192
+ const apps = this.#stringList(context.apps, `${path}.apps`);
193
+ if (new Set(apps).size !== apps.length) this.#fail(`${path}.apps`, "lists an app twice");
194
+ return {
195
+ branch: this.#string(context.branch, `${path}.branch`),
196
+ env: this.#string(context.env, `${path}.env`),
197
+ apps,
198
+ trigger: this.#oneOf(context.trigger, `${path}.trigger`, pipelineTriggers),
199
+ buildNum: this.#int(context.buildNum, `${path}.buildNum`, 0),
200
+ commit: this.#nullable(context.commit, (commit) => this.#string(commit, `${path}.commit`)),
201
+ };
202
+ }
203
+
204
+ #phase(value: unknown, path: string): PipelinePlanPhase {
205
+ const phase = this.#object(value, path, [
206
+ "id",
207
+ "name",
208
+ "description",
209
+ "slot",
210
+ "milestone",
211
+ "action",
212
+ "order",
213
+ "maxParallel",
214
+ "failFast",
215
+ "timeoutSeconds",
216
+ "stages",
217
+ ]);
218
+ const id = this.#string(phase.id, `${path}.id`);
219
+ const idError = PipelineNames.idError(id);
220
+ if (idError) this.#fail(`${path}.id`, idError);
221
+ if (this.#phaseIds.has(id)) this.#fail(`${path}.id`, `"${id}" is the id of another phase`);
222
+ this.#phaseIds.add(id);
223
+ const slot = this.#oneOf(phase.slot, `${path}.slot`, pipelinePlanSlots);
224
+ const action = this.#nullable(phase.action, (name) => this.#oneOf(name, `${path}.action`, pipelineActionNames));
225
+ const order = this.#oneOf(phase.order, `${path}.order`, ["parallel", "sequential"] as const);
226
+ if (action && slot !== action) this.#fail(`${path}.slot`, `a ${action} phase sits in the "${action}" slot`);
227
+ if (!action && (pipelineActionNames as readonly string[]).includes(slot))
228
+ this.#fail(`${path}.slot`, `the "${slot}" slot holds the ${slot} action phase only`);
229
+ if (action === "deploy" && order !== "sequential")
230
+ this.#fail(`${path}.order`, "a deploy phase runs its apps one at a time");
231
+ const stages = this.#array(phase.stages, `${path}.stages`).map((stage, idx) =>
232
+ this.#stage(stage, `${path}.stages[${idx}]`, action),
233
+ );
234
+ if (!stages.length) this.#fail(`${path}.stages`, "a phase holds at least one stage");
235
+ return {
236
+ id,
237
+ name: this.#string(phase.name, `${path}.name`, pipelinePlanLimits.nameChars),
238
+ description: this.#description(phase.description, `${path}.description`),
239
+ slot,
240
+ milestone: this.#oneOf(phase.milestone, `${path}.milestone`, pipelineMilestones),
241
+ action,
242
+ order,
243
+ maxParallel: this.#nullable(phase.maxParallel, (limit) => this.#int(limit, `${path}.maxParallel`, 1)),
244
+ failFast: this.#boolean(phase.failFast, `${path}.failFast`),
245
+ timeoutSeconds: this.#seconds(phase.timeoutSeconds, `${path}.timeoutSeconds`),
246
+ stages,
247
+ };
248
+ }
249
+
250
+ #stage(value: unknown, path: string, action: PipelineActionName | null): PipelinePlanStage {
251
+ const stage = this.#object(value, path, [
252
+ "id",
253
+ "name",
254
+ "description",
255
+ "app",
256
+ "milestone",
257
+ "skip",
258
+ "runtimeWhen",
259
+ "allowFailure",
260
+ "timeoutSeconds",
261
+ "steps",
262
+ ]);
263
+ this.#stageCount += 1;
264
+ if (this.#stageCount > pipelinePlanLimits.stages)
265
+ this.#fail(path, `a plan holds at most ${pipelinePlanLimits.stages} stages`);
266
+ const id = this.#string(stage.id, `${path}.id`, PipelinePlanSchema.#idChars);
267
+ if (!PipelinePlanSchema.#stageIdPattern.test(id)) this.#fail(`${path}.id`, `"${id}" is not a stage id`);
268
+ if (this.#stageIds.has(id)) this.#fail(`${path}.id`, `"${id}" is the id of another stage`);
269
+ this.#stageIds.add(id);
270
+ const app = this.#nullable(stage.app, (name) => this.#string(name, `${path}.app`));
271
+ if (app !== null && !this.#apps.has(app)) this.#fail(`${path}.app`, `"${app}" is not in context.apps`);
272
+ const steps = this.#array(stage.steps, `${path}.steps`).map((step, idx) =>
273
+ this.#step(step, `${path}.steps[${idx}]`),
274
+ );
275
+ if (!steps.length) this.#fail(`${path}.steps`, "a stage holds at least one step");
276
+ if (action) {
277
+ const [step] = steps;
278
+ if (steps.length !== 1 || step?.kind !== "action" || step.action !== action || step.with.app !== app)
279
+ this.#fail(`${path}.steps`, `a ${action} stage holds exactly one ${action} action, for the stage's own app`);
280
+ } else if (steps.some((step) => step.kind === "action"))
281
+ this.#fail(`${path}.steps`, "an action runs in its own action phase only");
282
+ return {
283
+ id,
284
+ name: this.#string(stage.name, `${path}.name`, pipelinePlanLimits.nameChars),
285
+ description: this.#description(stage.description, `${path}.description`),
286
+ app,
287
+ milestone: this.#oneOf(stage.milestone, `${path}.milestone`, pipelineMilestones),
288
+ skip: this.#nullable(stage.skip, (skip) => {
289
+ const reason = this.#object(skip, `${path}.skip`, ["reason"]).reason;
290
+ return { reason: this.#string(reason, `${path}.skip.reason`) };
291
+ }),
292
+ runtimeWhen: this.#nullable(stage.runtimeWhen, (when) => {
293
+ const changed = this.#object(when, `${path}.runtimeWhen`, ["changed"]).changed;
294
+ return { changed: this.#patterns(changed, `${path}.runtimeWhen.changed`) };
295
+ }),
296
+ allowFailure: this.#boolean(stage.allowFailure, `${path}.allowFailure`),
297
+ timeoutSeconds: this.#seconds(stage.timeoutSeconds, `${path}.timeoutSeconds`),
298
+ steps,
299
+ };
300
+ }
301
+
302
+ #step(value: unknown, path: string): PipelinePlanStep {
303
+ const kind = this.#oneOf(this.#object(value, path).kind, `${path}.kind`, ["sh", "action"] as const);
304
+ const step = this.#object(
305
+ value,
306
+ path,
307
+ kind === "sh" ? PipelinePlanSchema.#shellKeys : PipelinePlanSchema.#actionKeys,
308
+ );
309
+ this.#stepCount += 1;
310
+ if (this.#stepCount > pipelinePlanLimits.steps)
311
+ this.#fail(path, `a plan holds at most ${pipelinePlanLimits.steps} steps`);
312
+ const id = this.#string(step.id, `${path}.id`, PipelinePlanSchema.#idChars);
313
+ if (!PipelinePlanSchema.#stepIdPattern.test(id)) this.#fail(`${path}.id`, `"${id}" is not a step id`);
314
+ if (this.#stepIds.has(id)) this.#fail(`${path}.id`, `"${id}" is the id of another step`);
315
+ this.#stepIds.add(id);
316
+ const base = {
317
+ id,
318
+ name: this.#string(step.name, `${path}.name`, pipelinePlanLimits.nameChars),
319
+ timeoutSeconds: this.#seconds(step.timeoutSeconds, `${path}.timeoutSeconds`),
320
+ retry: this.#nullable(step.retry, (retry) => this.#retry(retry, `${path}.retry`)),
321
+ allowFailure: this.#boolean(step.allowFailure, `${path}.allowFailure`),
322
+ };
323
+ return kind === "sh" ? this.#shell(step, path, base) : this.#action(step, path, base);
324
+ }
325
+
326
+ #shell(
327
+ step: JsonObject,
328
+ path: string,
329
+ base: Omit<PipelinePlanShellStep, "kind" | "run" | "cwd" | "env" | "secrets" | "skipExitCodes">,
330
+ ): PipelinePlanShellStep {
331
+ const run = this.#string(step.run, `${path}.run`, Number.POSITIVE_INFINITY);
332
+ if (new TextEncoder().encode(run).length > pipelinePlanLimits.shBytes)
333
+ this.#fail(`${path}.run`, `a script is at most ${pipelinePlanLimits.shBytes} bytes`);
334
+ const cwd = this.#string(step.cwd, `${path}.cwd`);
335
+ if (cwd.startsWith("/") || cwd.startsWith("~") || cwd.includes("\\") || cwd.split("/").includes(".."))
336
+ this.#fail(`${path}.cwd`, `"${cwd}" is not a path inside the workspace`);
337
+ const env = this.#object(step.env, `${path}.env`);
338
+ for (const [name, envValue] of Object.entries(env)) {
339
+ const nameError = PipelineNames.envNameError(name);
340
+ if (nameError) this.#fail(`${path}.env`, nameError);
341
+ this.#string(envValue, `${path}.env.${name}`, pipelinePlanLimits.shBytes, { allowEmpty: true });
342
+ }
343
+ const secrets = this.#secretList(step.secrets, `${path}.secrets`);
344
+ for (const name of secrets) this.#stepSecrets.add(name);
345
+ const skipExitCodes = this.#array(step.skipExitCodes, `${path}.skipExitCodes`).map((code, idx) =>
346
+ this.#int(code, `${path}.skipExitCodes[${idx}]`, 1, 255),
347
+ );
348
+ if (new Set(skipExitCodes).size !== skipExitCodes.length) this.#fail(`${path}.skipExitCodes`, "lists a code twice");
349
+ return { ...base, kind: "sh", run, cwd, env: env as Record<string, string>, secrets, skipExitCodes };
350
+ }
351
+
352
+ #action(
353
+ step: JsonObject,
354
+ path: string,
355
+ base: Omit<PipelinePlanActionStep, "kind" | "action" | "actionVersion" | "with">,
356
+ ): PipelinePlanActionStep {
357
+ const action = this.#oneOf(step.action, `${path}.action`, pipelineActionNames);
358
+ if (step.actionVersion !== pipelineActions[action].version)
359
+ this.#fail(`${path}.actionVersion`, `${JSON.stringify(step.actionVersion)} is not a version of ${action}`);
360
+ const actionVersion = pipelineActions[action].version;
361
+ if (action === "ota")
362
+ return { ...base, kind: "action", action, actionVersion, with: this.#otaWith(step.with, path) };
363
+ const app = this.#object(step.with, `${path}.with`, ["app"]).app;
364
+ return { ...base, kind: "action", action, actionVersion, with: { app: this.#string(app, `${path}.with.app`) } };
365
+ }
366
+
367
+ #otaWith(value: unknown, path: string): PipelinePlanOtaStep["with"] {
368
+ const raw = this.#object(value, `${path}.with`, ["app", "targets", "platforms"]);
369
+ const targets = this.#stringList(raw.targets, `${path}.with.targets`);
370
+ const platforms = this.#array(raw.platforms, `${path}.with.platforms`).map((platform, idx) =>
371
+ this.#oneOf(platform, `${path}.with.platforms[${idx}]`, pipelineOtaPlatforms),
372
+ );
373
+ for (const [key, list] of [
374
+ ["targets", targets],
375
+ ["platforms", platforms],
376
+ ] as const) {
377
+ if (!list.length) this.#fail(`${path}.with.${key}`, "may not be empty");
378
+ if (new Set(list).size !== list.length) this.#fail(`${path}.with.${key}`, "lists one twice");
379
+ }
380
+ return { app: this.#string(raw.app, `${path}.with.app`), targets, platforms };
381
+ }
382
+
383
+ #post(value: unknown, path: string): PipelinePlanPost {
384
+ const post = this.#object(value, path, ["success", "failure", "canceled", "always"]);
385
+ const steps = (result: keyof PipelinePlanPost) =>
386
+ this.#array(post[result], `${path}.${result}`).map((step, idx) => {
387
+ const parsed = this.#step(step, `${path}.${result}[${idx}]`);
388
+ if (parsed.kind !== "sh") this.#fail(`${path}.${result}[${idx}]`, "a post step is a shell step");
389
+ return parsed;
390
+ });
391
+ return {
392
+ success: steps("success"),
393
+ failure: steps("failure"),
394
+ canceled: steps("canceled"),
395
+ always: steps("always"),
396
+ };
397
+ }
398
+
399
+ #retry(value: unknown, path: string): PipelinePlanRetry {
400
+ const retry = this.#object(value, path, ["attempts", "delaySeconds"]);
401
+ return {
402
+ attempts: this.#int(retry.attempts, `${path}.attempts`, 1, pipelinePlanLimits.retryAttempts),
403
+ delaySeconds: this.#int(retry.delaySeconds, `${path}.delaySeconds`, 0, pipelinePlanLimits.retryDelaySeconds),
404
+ };
405
+ }
406
+
407
+ #patterns(value: unknown, path: string) {
408
+ const patterns = this.#stringList(value, path);
409
+ const patternError = PipelinePattern.validate(patterns);
410
+ if (patternError) this.#fail(path, patternError);
411
+ return patterns;
412
+ }
413
+
414
+ #secretList(value: unknown, path: string) {
415
+ const names = this.#stringList(value, path);
416
+ for (const name of names) {
417
+ const nameError = PipelineNames.secretNameError(name);
418
+ if (nameError) this.#fail(path, nameError);
419
+ }
420
+ if (new Set(names).size !== names.length) this.#fail(path, "lists a secret twice");
421
+ return names;
422
+ }
423
+
424
+ #stringList(value: unknown, path: string) {
425
+ return this.#array(value, path).map((item, idx) => this.#string(item, `${path}[${idx}]`));
426
+ }
427
+
428
+ #description(value: unknown, path: string) {
429
+ return this.#nullable(value, (text) => this.#string(text, path, pipelinePlanLimits.descriptionChars));
430
+ }
431
+
432
+ #seconds(value: unknown, path: string) {
433
+ return this.#nullable(value, (seconds) => this.#int(seconds, path, 1, PipelinePlanSchema.#maxSeconds));
434
+ }
435
+
436
+ #nullable<T>(value: unknown, parse: (value: unknown) => T): T | null {
437
+ return value === null ? null : parse(value);
438
+ }
439
+
440
+ #object(value: unknown, path: string, keys?: readonly string[]): JsonObject {
441
+ if (typeof value !== "object" || value === null || Array.isArray(value)) this.#fail(path, "must be an object");
442
+ const object = value as JsonObject;
443
+ if (!keys) return object;
444
+ for (const key of Object.keys(object)) if (!keys.includes(key)) this.#fail(path, `"${key}" is not a known key`);
445
+ for (const key of keys) if (!(key in object)) this.#fail(path, `"${key}" is missing`);
446
+ return object;
447
+ }
448
+
449
+ #array(value: unknown, path: string, max = Number.POSITIVE_INFINITY): unknown[] {
450
+ if (!Array.isArray(value)) this.#fail(path, "must be an array");
451
+ const items = value as unknown[];
452
+ if (items.length > max) this.#fail(path, `holds at most ${max} items`);
453
+ return items;
454
+ }
455
+
456
+ #string(
457
+ value: unknown,
458
+ path: string,
459
+ max: number = PipelinePlanSchema.#textChars,
460
+ { allowEmpty = false }: { allowEmpty?: boolean } = {},
461
+ ): string {
462
+ if (typeof value !== "string") this.#fail(path, "must be a string");
463
+ const text = value as string;
464
+ if (!allowEmpty && !text) this.#fail(path, "may not be empty");
465
+ if (text.length > max) this.#fail(path, `is longer than ${max} characters`);
466
+ return text;
467
+ }
468
+
469
+ #boolean(value: unknown, path: string): boolean {
470
+ if (typeof value !== "boolean") this.#fail(path, "must be a boolean");
471
+ return value as boolean;
472
+ }
473
+
474
+ #int(value: unknown, path: string, min: number, max = Number.MAX_SAFE_INTEGER): number {
475
+ if (typeof value !== "number" || !Number.isInteger(value)) this.#fail(path, "must be an integer");
476
+ const number = value as number;
477
+ if (number < min || number > max) this.#fail(path, `must be between ${min} and ${max}`);
478
+ return number;
479
+ }
480
+
481
+ #oneOf<T extends string>(value: unknown, path: string, options: readonly T[]): T {
482
+ if (typeof value !== "string" || !(options as readonly string[]).includes(value))
483
+ this.#fail(path, `${JSON.stringify(value)} is not one of ${options.join(", ")}`);
484
+ return value as T;
485
+ }
486
+
487
+ #fail(path: string, reason: string): never {
488
+ throw new Error(`pipeline plan ${path}: ${reason}`);
489
+ }
490
+ }
@@ -0,0 +1,14 @@
1
+ export interface BackoffPolicy {
2
+ /** The first wait in ms; each attempt in a row doubles it. */
3
+ min?: number;
4
+ max?: number;
5
+ /** The share of each wait drawn at random, 0 to 1, so callers one outage dropped together come back apart. */
6
+ jitter?: number;
7
+ }
8
+
9
+ export class Backoff {
10
+ static delay(attempt: number, { min = 1_000, max = 30_000, jitter = 0.5 }: BackoffPolicy = {}) {
11
+ const ceiling = Math.min(max, min * 2 ** Math.max(0, attempt - 1));
12
+ return Math.round(ceiling * (1 - Math.min(1, Math.max(0, jitter)) * Math.random()));
13
+ }
14
+ }
package/common/index.ts CHANGED
@@ -7,6 +7,7 @@ export {
7
7
  legacyAuthTokenKey,
8
8
  readAuthToken,
9
9
  } from "./authToken";
10
+ export { Backoff, type BackoffPolicy } from "./backoff";
10
11
  export { CodeAgentClient, type CodeAgentTransport } from "./CodeAgentClient";
11
12
  export { CodeTranscript, type CodeTranscriptPart } from "./CodeTranscript";
12
13
  export { capitalize, lowerlize } from "./capitalize";
@@ -127,7 +128,45 @@ export {
127
128
  } from "./mcpExposure";
128
129
  export { deepObjectify, objectify, plainFieldsOf } from "./objectify";
129
130
  export { pathGet, pathGetLoose, pathSet, toPathSegments } from "./objectPath";
131
+ export { PipelineNames } from "./PipelineNames";
132
+ export { PipelinePattern } from "./PipelinePattern";
133
+ export { PipelinePlanSchema } from "./PipelinePlanSchema";
130
134
  export { formatPhone, isPhoneNumber } from "./phone";
135
+ export {
136
+ type PipelineActionName,
137
+ type PipelineDiagnostic,
138
+ type PipelineMilestone,
139
+ type PipelineOtaPlatform,
140
+ type PipelinePlan,
141
+ type PipelinePlanActionStep,
142
+ type PipelinePlanAppActionStep,
143
+ type PipelinePlanContext,
144
+ type PipelinePlanOtaStep,
145
+ type PipelinePlanPhase,
146
+ type PipelinePlanPost,
147
+ type PipelinePlanResult,
148
+ type PipelinePlanRetry,
149
+ type PipelinePlanShellStep,
150
+ type PipelinePlanSlot,
151
+ type PipelinePlanSource,
152
+ type PipelinePlanStage,
153
+ type PipelinePlanStep,
154
+ type PipelineSkip,
155
+ type PipelineTrigger,
156
+ pipelineActionNames,
157
+ pipelineActions,
158
+ pipelineEnvNamePattern,
159
+ pipelineIdPattern,
160
+ pipelineMilestones,
161
+ pipelineOtaPlatforms,
162
+ pipelinePlanLimits,
163
+ pipelinePlanSlots,
164
+ pipelinePlanVersion,
165
+ pipelineReservedEnv,
166
+ pipelineRuntimeEnv,
167
+ pipelineSecretNamePattern,
168
+ pipelineTriggers,
169
+ } from "./pipelinePlan";
131
170
  export { type RouteLayer, RouteLayering } from "./RouteLayering";
132
171
  export { randomPick, randomPicks } from "./randomPick";
133
172
  export { hostFromRequest, isJsonContentType, originFromRequest } from "./requestOrigin";