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
@@ -19,6 +19,7 @@ export type FetchProxySignalInput<
19
19
  > = {
20
20
  handler: Record<string, unknown>;
21
21
  serializedSignal: Record<string, SerializedSignal>;
22
+ ownSerializedSignal?: Record<string, SerializedSignal>;
22
23
  _FetchType: FetchType;
23
24
  _SliceMetaObj: SliceMetaObj;
24
25
  };
package/index.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  import type { AkanNativeConfig } from "./vendor/@akanjs/native/packages/cli/src/config.ts";
2
- import type { AkanI18nConfig } from "akanjs/common";
2
+ import type {
3
+ AkanI18nConfig,
4
+ PipelineActionName,
5
+ PipelineMilestone,
6
+ PipelineOtaPlatform,
7
+ PipelineTrigger,
8
+ } from "akanjs/common";
3
9
  import type { AkanImageConfig } from "akanjs/server";
4
10
 
5
11
  export const archs = ["amd64", "arm64"] as const;
@@ -126,12 +132,18 @@ export interface AkanNativeDeepLinks {
126
132
  */
127
133
  export interface AkanNativeUpdatesConfig {
128
134
  /**
129
- * A static base URL, https in a release build: `<url>/<os>-<arch>/<channel>.json` (desktop) or `<url>/<platform>/…`
130
- * (a phone's web bundle).
135
+ * A static base URL, https in a release build, with no query: `<url>/<os>-<arch>/<channel>.json` (desktop) or
136
+ * `<url>/<platform>/<channel>/<nativeApi>.json` (a phone's web bundle, one envelope per binary generation).
131
137
  */
132
138
  url: string;
133
- /** The update key's public half, the raw 32-byte Ed25519 key in base64 (`akan update-keygen` prints it). */
134
- publicKey: string;
139
+ /**
140
+ * The keys a phone binary trusts, raw 32-byte Ed25519 public keys in base64 (`akan update-keygen` prints one), 1 to
141
+ * 3: the online signing key first, offline spares after it, since a key may revoke only keys listed before it. A
142
+ * desktop app trusts the first.
143
+ */
144
+ publicKeys?: string[];
145
+ /** The one-key form of `publicKeys`. */
146
+ publicKey?: string;
135
147
  /**
136
148
  * The manifest the app follows, e.g. a "pilot" target's "pilot". Default: the backend env the app is built for
137
149
  * (`main`, `develop`, `debug`, `local`).
@@ -139,6 +151,11 @@ export interface AkanNativeUpdatesConfig {
139
151
  channel?: string;
140
152
  /** How long a newly applied release has to call notifyReady() before it is rolled back, ms. Default 10000. */
141
153
  readyTimeout?: number;
154
+ /**
155
+ * Where a phone posts what became of each release (downloaded, applied, confirmed, rolled back, failed) at its next
156
+ * launch or return to the foreground, so rollback rates are visible. Left out, nothing is sent.
157
+ */
158
+ report?: { url: string };
142
159
  }
143
160
 
144
161
  export interface AkanNativeIosConfig {
@@ -182,6 +199,23 @@ export interface AkanNativeDesktopServerConfig {
182
199
  * The server's own bundle must not import them. The image is unchanged.
183
200
  */
184
201
  omit?: string[];
202
+ /**
203
+ * The server bundles `env/env.server.<env>.<profile>.ts` in place of `env/env.server.<env>.ts`, so the environment's
204
+ * own file and its secrets stay off the computers the app is installed on. The build refuses a profile file that holds
205
+ * a secret-named value.
206
+ */
207
+ profile?: string;
208
+ /** What the server mounts, as `AKAN_MODULES`: names, or `@edge` for every module whose `serve()` lists edge. */
209
+ modules?: string[];
210
+ /**
211
+ * Variables the server starts with over the image's, written into the app where anyone on the computer reads them:
212
+ * the build refuses a secret-named one, and those the launcher or the stage sets.
213
+ */
214
+ env?: Record<string, string>;
215
+ /** Crashes in a row before the app gives up on its server, 5 unless named; `"forever"` for a screen nobody attends. */
216
+ restart?: "forever" | number;
217
+ /** Asks the running server's health route every `intervalMs` (10 s) and restarts it after `failures` (3) missed. */
218
+ watchdog?: boolean | { intervalMs?: number; failures?: number };
185
219
  }
186
220
 
187
221
  export interface AkanNativeDesktopConfig {
@@ -189,7 +223,8 @@ export interface AkanNativeDesktopConfig {
189
223
  indexPath?: string;
190
224
  /**
191
225
  * The desktop app carries the app's server (API only, database mode single, on loopback) and its pages call
192
- * nothing else: `true`, or `{ omit }` to carry it without some of the image's packages. `build-desktop`,
226
+ * nothing else: `true`, or `{ omit, profile, modules }` to carry it without some of the image's packages, with a
227
+ * secret-free env, or with only some modules. `build-desktop`,
193
228
  * `start-desktop` and `publish-update` all read it, and an installed app refuses a release that carries a server
194
229
  * when it has none, or none when it has one.
195
230
  */
@@ -200,13 +235,23 @@ export interface AkanNativeDesktopConfig {
200
235
  * app nobody attends. `"errorPage"` (default): one reload, then an error page, and a quit for the browser.
201
236
  */
202
237
  recovery?: "errorPage" | "reload";
203
- /** The main window from its first frame: borderless fullscreen, and no taskbar button (Windows, Linux). */
204
- window?: { fullscreen?: boolean; skipTaskbar?: boolean };
238
+ /**
239
+ * The main window from its first frame: borderless fullscreen, no taskbar button (Windows, Linux), and no title
240
+ * bar or border (`frameless`, a kiosk drawn at an exact size).
241
+ */
242
+ window?: { fullscreen?: boolean; skipTaskbar?: boolean; frameless?: boolean };
205
243
  /**
206
244
  * Windows: `"auto"` answers getDisplayMedia() with the first screen at once, no picker or gesture — remote
207
245
  * support on an unattended screen; it covers every media request, so not for an app that asks for a camera.
208
246
  */
209
247
  screenCapture?: "picker" | "auto";
248
+ /**
249
+ * Windows installer: `"bootstrapper"` (default) carries Microsoft's small setup that downloads the WebView2 Runtime
250
+ * where none is installed; `"standalone"` carries the whole runtime (~200 MB) for a PC offline at install.
251
+ */
252
+ webview2?: "bootstrapper" | "standalone";
253
+ /** Windows: who publishes the app, as the installed app's Publisher and its executable's company name (default: the app name). */
254
+ publisher?: string;
210
255
  /**
211
256
  * macOS: entitlements of the app's executable beyond what it gets by itself — the JIT's under the hardened runtime and
212
257
  * the camera's or microphone's when a usage text asks for it — e.g. `com.apple.security.cs.disable-library-validation`
@@ -264,11 +309,18 @@ export interface AkanNativeSettings {
264
309
  icon?: string | { image: string; backgroundColor?: string };
265
310
  /** A PNG shown centered at launch, or the launch screen's color, image and when it hides. */
266
311
  splash?: string | NonNullable<AkanNativeConfig["splash"]>;
312
+ /** A window's and an external view's color before its page paints (and the splash's default): one, or `{ light, dark }`. Default white / black. */
313
+ backgroundColor?: string | { light: string; dark: string };
267
314
  permissions?: NativePermission[];
268
315
  /** Native runtime plugins beyond the ones the permissions bring: a builtin id (`"iap"`) or a folder, from the app's. */
269
316
  plugins?: string[];
270
317
  deepLinks?: AkanNativeDeepLinks;
271
318
  updates?: Partial<AkanNativeUpdatesConfig>;
319
+ /**
320
+ * The web inspector (Safari's, `chrome://inspect`) in a release build too, as a debug build always has it: for an
321
+ * internal test target only, since anyone holding the device can then read and drive the page.
322
+ */
323
+ devtools?: boolean;
272
324
  ios?: AkanNativeIosConfig;
273
325
  android?: AkanNativeAndroidConfig;
274
326
  desktop?: AkanNativeDesktopConfig;
@@ -429,12 +481,180 @@ export interface LibConfigContext {
429
481
  readonly type: "lib";
430
482
  }
431
483
 
484
+ export type PipelineDuration = number | `${number}s` | `${number}m` | `${number}h`;
485
+
486
+ /** In the `PipelinePattern` dialect of `akanjs/common`; a leading `!` excludes. */
487
+ export type PipelineGlob = string | readonly string[];
488
+
489
+ /** Every key given must hold. `branch` and `trigger` are decided by the planner, `changed` by the executor. */
490
+ export interface PipelineWhen {
491
+ branch?: PipelineGlob;
492
+ trigger?: PipelineTrigger | readonly PipelineTrigger[];
493
+ /** Paths changed since the branch's newest successful build; an unknown baseline counts as changed. */
494
+ changed?: PipelineGlob;
495
+ }
496
+
497
+ export interface PipelineStepInput {
498
+ sh: string;
499
+ id?: string;
500
+ name?: string;
501
+ /** Relative to the workspace root, never above it. */
502
+ cwd?: string;
503
+ env?: Record<string, string>;
504
+ secrets?: readonly string[];
505
+ timeout?: PipelineDuration;
506
+ /** Total attempts. */
507
+ retry?: number | { attempts: number; delay?: PipelineDuration };
508
+ allowFailure?: boolean;
509
+ skipExitCodes?: readonly number[];
510
+ }
511
+
512
+ export type PipelineStepLike = string | PipelineStepInput;
513
+
514
+ /** `timeout` and `allowFailure` cover the whole stage, every parallel branch and per-app copy included. */
515
+ export interface PipelineStageBase {
516
+ id?: string;
517
+ description?: string;
518
+ milestone?: PipelineMilestone;
519
+ when?: PipelineWhen;
520
+ timeout?: PipelineDuration;
521
+ allowFailure?: boolean;
522
+ }
523
+
524
+ export interface PipelineShellStageInput extends PipelineStageBase {
525
+ name: string;
526
+ /** Exactly one of `sh` and `steps`. */
527
+ sh?: string;
528
+ steps?: readonly PipelineStepLike[];
529
+ env?: Record<string, string>;
530
+ secrets?: readonly string[];
531
+ /** For each step that names no `retry` of its own. */
532
+ retry?: PipelineStepInput["retry"];
533
+ use?: never;
534
+ parallel?: never;
535
+ matrix?: never;
536
+ }
537
+
538
+ /** No action parameters yet: rollout wait and prepull stay the executor's settings. */
539
+ export interface PipelineActionStageInput extends PipelineStageBase {
540
+ use: Exclude<PipelineActionName, "ota">;
541
+ name?: string;
542
+ retry?: number;
543
+ targets?: never;
544
+ platforms?: never;
545
+ sh?: never;
546
+ steps?: never;
547
+ parallel?: never;
548
+ matrix?: never;
549
+ }
550
+
551
+ /**
552
+ * An over-the-air update of the app's native web bundle, packed per target and platform for the executor to sign and
553
+ * publish. Every target named must declare `native.updates`.
554
+ */
555
+ export interface PipelineOtaStageInput extends PipelineStageBase {
556
+ use: "ota";
557
+ name?: string;
558
+ retry?: number;
559
+ /** Default: every native target that declares `native.updates`. */
560
+ targets?: readonly string[];
561
+ /** Default: both. */
562
+ platforms?: readonly PipelineOtaPlatform[];
563
+ sh?: never;
564
+ steps?: never;
565
+ parallel?: never;
566
+ matrix?: never;
567
+ }
568
+
569
+ export type AppPipelineStageInput = PipelineActionStageInput | PipelineOtaStageInput | PipelineShellStageInput;
570
+
571
+ export interface AppPipelineInput {
572
+ schemaVersion?: 1;
573
+ /** This app's stages in order, the actions it takes included. */
574
+ stages: readonly AppPipelineStageInput[];
575
+ env?: Record<string, string>;
576
+ /** Apps whose turn comes before this one's where apps run one at a time (deploy). Apps not in the run are ignored. */
577
+ after?: readonly string[];
578
+ }
579
+
580
+ export interface PipelineContext {
581
+ readonly branch: string;
582
+ readonly env: string;
583
+ /** Apps this run builds. */
584
+ readonly apps: readonly string[];
585
+ /** Every app in this checkout: a subspace sees its slice only. */
586
+ readonly workspaceApps: readonly string[];
587
+ readonly trigger: PipelineTrigger;
588
+ readonly buildNum: number;
589
+ readonly commit: string | null;
590
+ }
591
+
592
+ export interface AppPipelineContext extends PipelineContext {
593
+ readonly app: string;
594
+ }
595
+
596
+ /** Read by `akan pipeline` alone: the app config loader drops it, so it never reaches `akan.app.json`. */
597
+ export type AppPipelineConfig = AppPipelineInput | ((ctx: AppPipelineContext) => AppPipelineInput);
598
+
599
+ /** What an app without a `pipeline` runs. */
600
+ export const defaultAppPipeline = {
601
+ stages: [{ use: "build" }, { use: "docker" }, { use: "deploy" }],
602
+ } as const satisfies AppPipelineInput;
603
+
604
+ /** One copy per app of the run, each with AKAN_CI_APP; `when.app` narrows the apps. */
605
+ export interface PipelineMatrixStageInput extends Omit<PipelineShellStageInput, "matrix" | "when"> {
606
+ matrix: "apps";
607
+ maxParallel?: number;
608
+ when?: PipelineWhen & { app?: PipelineGlob };
609
+ }
610
+
611
+ export interface PipelineParallelStageInput extends PipelineStageBase {
612
+ name: string;
613
+ parallel: readonly PipelineShellStageInput[];
614
+ maxParallel?: number;
615
+ /** Cancel the other branches when one fails. */
616
+ failFast?: boolean;
617
+ env?: Record<string, string>;
618
+ secrets?: readonly string[];
619
+ use?: never;
620
+ sh?: never;
621
+ steps?: never;
622
+ matrix?: never;
623
+ }
624
+
625
+ export type WorkspacePipelineStageInput =
626
+ | PipelineShellStageInput
627
+ | PipelineMatrixStageInput
628
+ | PipelineParallelStageInput;
629
+
630
+ export interface PipelinePostInput {
631
+ success?: readonly PipelineStepLike[];
632
+ failure?: readonly PipelineStepLike[];
633
+ canceled?: readonly PipelineStepLike[];
634
+ always?: readonly PipelineStepLike[];
635
+ }
636
+
637
+ export interface WorkspacePipelineInput {
638
+ schemaVersion?: 1;
639
+ /** For every step of the run, app stages included. */
640
+ env?: Record<string, string>;
641
+ timeout?: PipelineDuration;
642
+ /** Before any app stage. */
643
+ before?: readonly WorkspacePipelineStageInput[];
644
+ /** After every app's last stage. */
645
+ after?: readonly WorkspacePipelineStageInput[];
646
+ post?: PipelinePostInput;
647
+ }
648
+
649
+ export type WorkspacePipelineConfig = WorkspacePipelineInput | ((ctx: PipelineContext) => WorkspacePipelineInput);
650
+
432
651
  export type AppConfigInput = Omit<DeepPartial<AppConfigResult>, "docker" | "web" | "bin" | "native"> & {
433
652
  docker?: DockerOption;
434
653
  web?: AkanWebOption;
435
654
  bin?: AkanBinConfig;
436
655
  native?: AkanNativeAppConfig;
437
656
  plugins?: AkanPlugin[];
657
+ pipeline?: AppPipelineConfig;
438
658
  };
439
659
  export type LibConfigInput = Omit<DeepPartial<LibConfigResult>, "bin"> & {
440
660
  bin?: AkanBinConfig;
@@ -446,11 +666,11 @@ export interface SubspaceDeclaration {
446
666
  repo: string;
447
667
  /** Apps this subspace serves. Libraries are never listed — they are derived from each app's closure. */
448
668
  apps: string[];
449
- /** The subspace's own `AKAN_WORKSPACE_ID`, not this workspace's; only `akan subspace upload-env` reads it. */
669
+ /** The subspace's own `AKAN_WORKSPACE_ID`, not this workspace's: `akan subspace upload-env` and `--subspace` read it. */
450
670
  workspaceId?: string;
451
671
  }
452
672
 
453
- /** `akan.subspace.ts`: the repos this workspace mirrors to, on whichever branch the workspace is on. */
673
+ /** The repos this workspace mirrors to, on whichever branch the workspace is on. */
454
674
  export interface SubspaceConfigInput {
455
675
  /** A feature branch is refused: pushing it would copy this workspace's branch namespace into every customer repo. */
456
676
  pushableBranches?: string[];
@@ -459,6 +679,19 @@ export interface SubspaceConfigInput {
459
679
  subspaces: SubspaceDeclaration[];
460
680
  }
461
681
 
682
+ /** The workspace root's `akan.config.ts`. It never reaches a subspace, and app or lib settings are refused in it. */
683
+ /** The cloud a workspace's CLI talks to when a command names no `--host`: a self-hosted akasys, say. */
684
+ export interface WorkspaceCloudConfig {
685
+ /** The cloud's origin, e.g. `https://cloud.example.com`. Default: Akan Cloud. */
686
+ host?: string;
687
+ }
688
+
689
+ export interface WorkspaceConfig {
690
+ subspace?: SubspaceConfigInput;
691
+ pipeline?: WorkspacePipelineConfig;
692
+ cloud?: WorkspaceCloudConfig;
693
+ }
694
+
462
695
  export type AppConfig = AppConfigInput | ((app: AppConfigContext) => AppConfigInput);
463
696
  export type LibConfig = LibConfigInput | ((lib: LibConfigContext) => LibConfigInput);
464
697
  export type AkanConfigFile = object;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akanjs",
3
- "version": "3.0.2",
3
+ "version": "3.1.0-rc.0",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -233,7 +233,6 @@
233
233
  },
234
234
  "peerDependencies": {
235
235
  "@happy-dom/global-registrator": "^20.11.2",
236
- "@libsql/client": "^0.17.3",
237
236
  "@playwright/test": "^1.60.0",
238
237
  "@react-spring/web": "^10.1.0",
239
238
  "@use-gesture/react": "^10.3.1",
@@ -258,9 +257,6 @@
258
257
  "@happy-dom/global-registrator": {
259
258
  "optional": true
260
259
  },
261
- "@libsql/client": {
262
- "optional": true
263
- },
264
260
  "@playwright/test": {
265
261
  "optional": true
266
262
  },
package/server/akanApp.ts CHANGED
@@ -346,6 +346,7 @@ export class AkanApp {
346
346
  ...this.#childEnv(idx, role),
347
347
  AKAN_CHILD_SOCKET: upstream.http.socketPath,
348
348
  AKAN_CHILD_WS_PORT: upstream.ws ? String(upstream.ws.port) : "",
349
+ ...(this.#printChildStderr || Logger.isNdjson ? {} : { AKAN_CHILD_STDERR_HIDDEN: "1" }),
349
350
  },
350
351
  ipc: (message) => this.#handleMessage(idx, message as AkanIpcMessage, proc),
351
352
  stdout: "pipe",
@@ -626,7 +627,7 @@ export class AkanApp {
626
627
  static readonly #immutableArtifacts = [
627
628
  { prefix: "/_akan/client/", root: "client", strip: "/_akan/client/".length, type: "application/javascript" },
628
629
  { prefix: "/_akan/styles/", root: "", strip: "/_akan/".length, type: "text/css; charset=utf-8" },
629
- { prefix: "/_akan/fonts/", root: "", strip: "/_akan/".length, type: "font/woff2" },
630
+ { prefix: "/_akan/fonts/", root: "", strip: "/_akan/".length, type: "font/woff2", anyOrigin: true },
630
631
  ] as const;
631
632
 
632
633
  async #serveImmutableArtifact(req: Request, url: URL): Promise<Response | null> {
@@ -640,6 +641,7 @@ export class AkanApp {
640
641
  return this.#fileResponse(req, filePath, {
641
642
  contentType: file.type || artifact.type,
642
643
  cacheControl: "public, max-age=31536000, immutable",
644
+ anyOrigin: "anyOrigin" in artifact,
643
645
  });
644
646
  }
645
647
 
@@ -975,10 +977,11 @@ export class AkanApp {
975
977
  async #fileResponse(
976
978
  req: Request,
977
979
  filePath: string,
978
- options: { contentType: string; cacheControl?: string },
980
+ options: { contentType: string; cacheControl?: string; anyOrigin?: boolean },
979
981
  ): Promise<Response> {
980
982
  const headers = new Headers({ "Content-Type": options.contentType });
981
983
  if (options.cacheControl) headers.set("Cache-Control", options.cacheControl);
984
+ if (options.anyOrigin) headers.set("Access-Control-Allow-Origin", "*");
982
985
  headers.set("X-Content-Type-Options", "nosniff");
983
986
  headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
984
987
  return await encodedFileResponse(req, filePath, options.contentType, headers);
@@ -46,6 +46,7 @@ import { SignalResolver } from "./resolver";
46
46
  import { type ApiRouteInputs, ApiRouter } from "./routing/apiRouter";
47
47
  import type { AppWsData } from "./routing/appWsData";
48
48
  import { HostAllowlist } from "./routing/hostAllowlist";
49
+ import { RoomReplay } from "./routing/roomReplay";
49
50
  import { createSoloAppRoutes } from "./routing/soloAppRoutes";
50
51
  import {
51
52
  getWebConfigFromEnv,
@@ -105,6 +106,16 @@ export interface McpServerOption {
105
106
  rateLimit?: McpRateLimitOption | false;
106
107
  /** Characters a page prompt may attach before its lists are cut; 60,000 by default. `AKAN_MCP_PROMPT_BUDGET`. */
107
108
  promptBudget?: number;
109
+ /**
110
+ * MCP Apps: a `.prompt()` page is a tool as well, whose result a host speaking the extension renders from the CSR
111
+ * shell; an endpoint kept off the shelf by `mcp: false` stays callable by that view. `true` by default. `AKAN_MCP_APPS`.
112
+ */
113
+ apps?: boolean;
114
+ /**
115
+ * Speak the modern `2026-07-28` revision (`server/discover`) beside the legacy ones. On unless MCP Apps renders views,
116
+ * since claude.ai renders a view only for a server it reached through `initialize`. `AKAN_MCP_MODERN`.
117
+ */
118
+ modern?: boolean;
108
119
  }
109
120
 
110
121
  interface AkanAppPrepared {
@@ -172,6 +183,7 @@ export class AkanServer {
172
183
  #lastMetrics: AkanMetricsReport = {};
173
184
  #stopping: Promise<void> | null = null;
174
185
  #parentGone: boolean = false;
186
+ #schedules = true;
175
187
  #orphanExiting = false;
176
188
  constructor(
177
189
  name = "AkanServer",
@@ -188,6 +200,8 @@ export class AkanServer {
188
200
  this.logger = new Logger(name);
189
201
  this.libs = libs;
190
202
  this.env = { ...env };
203
+
204
+ if (AkanServer.#isEdge(this.env) && !AkanServer.#isEnvEnabled("AKAN_MCP", "AKAN_PUBLIC_MCP")) this.mcp = false;
191
205
  this.openapi = options?.openapi ?? this.openapi;
192
206
 
193
207
  EndpointRateLimit.reset();
@@ -467,15 +481,18 @@ export class AkanServer {
467
481
  return;
468
482
  }
469
483
  const publishData: WebsocketPublishData = { type: "pub", roomId, data };
470
- server?.publish(roomId, JSON.stringify(publishData));
471
- wsServer?.publish(roomId, JSON.stringify(publishData));
484
+ const subscribed = (server?.subscriberCount(roomId) ?? 0) + (wsServer?.subscriberCount(roomId) ?? 0) > 0;
485
+ const frame = roomReplay.frameOf(publishData, subscribed);
486
+ server?.publish(roomId, frame);
487
+ wsServer?.publish(roomId, frame);
472
488
  };
473
- SignalResolver.setLocalPublish(localPublish, websocket, this.#di.live);
489
+ const roomReplay = new RoomReplay({ vouches: this.#solo });
490
+ SignalResolver.setLocalPublish(localPublish, websocket, this.#di.live, roomReplay);
474
491
  this.#localPublish = localPublish;
475
492
 
476
493
  this.status = "running";
477
494
  this.#metricsTimer ??= ProcessMetricsCollector.startReporting(() => this.#reportMetrics());
478
- this.#di.registerSchedule(this.serverMode);
495
+ if (this.#schedules) this.#di.registerSchedule(this.serverMode);
479
496
  this.logger.verbose(`🚀 ${this.name} is running on ${unix ? `unix://${unix}` : `port ${port}`}`);
480
497
  const wsPort = this.#wsServer?.port;
481
498
  this.#sendReady({
@@ -488,12 +505,17 @@ export class AkanServer {
488
505
  healthPath: "/_akan/app/child-health",
489
506
  crossSite: CrossSiteGuard.option(),
490
507
  });
491
- await this.#di.runSchedulerInit();
508
+ if (this.#schedules) await this.#di.runSchedulerInit();
492
509
  ShutdownManager.register(this.logger, () => this.stop());
493
510
  return this;
494
511
  }
495
512
 
496
- async start({ listen, web }: { listen?: boolean; web?: AkanWebOption } = {}) {
513
+ /**
514
+ * `listen: false` serves no HTTP and still runs the internals, as a batch replica does; `schedules: false` runs
515
+ * none of them (init, interval, cron, queue workers), as a test or a script wants.
516
+ */
517
+ async start({ listen, web, schedules }: { listen?: boolean; web?: AkanWebOption; schedules?: boolean } = {}) {
518
+ this.#schedules = schedules ?? true;
497
519
  const isNoListenCommand = process.env.AKAN_COMMAND_TYPE === "script" || process.env.AKAN_COMMAND_TYPE === "console";
498
520
  const shouldListen = (listen ?? !isNoListenCommand) && this.serverMode !== "batch";
499
521
 
@@ -508,7 +530,7 @@ export class AkanServer {
508
530
  if (!isNoListenCommand) {
509
531
  Logger.role = this.serverMode;
510
532
  this.#metricsTimer ??= ProcessMetricsCollector.startReporting(() => this.#reportMetrics());
511
- this.#di.registerSchedule(this.serverMode);
533
+ if (this.#schedules) this.#di.registerSchedule(this.serverMode);
512
534
  await this.#startLogTransport();
513
535
  this.#sendReady({
514
536
  type: "ready",
@@ -516,7 +538,7 @@ export class AkanServer {
516
538
  replicaIdx: Number(process.env.AKAN_REPLICA_IDX ?? 0),
517
539
  role: this.serverMode,
518
540
  });
519
- await this.#di.runSchedulerInit();
541
+ if (this.#schedules) await this.#di.runSchedulerInit();
520
542
  ShutdownManager.register(this.logger, () => this.stop());
521
543
  }
522
544
  return this;
@@ -672,6 +694,8 @@ export class AkanServer {
672
694
  readOnly: this.mcpReadOnly,
673
695
  auth: this.mcpAuth,
674
696
  pagePrompts: webRouter?.pagePrompts(),
697
+ apps: this.mcpOption.apps !== false,
698
+ appShell: this.mcpOption.apps === false ? undefined : webRouter?.mcpAppShell(),
675
699
  })
676
700
  : null;
677
701
  const mcpRoutes: HttpRoutes = mcpRouter?.createRoutes() ?? {};
@@ -823,6 +847,10 @@ export class AkanServer {
823
847
  );
824
848
  }
825
849
 
850
+ static #isEdge(env: BackendEnv) {
851
+ return ((env as { operationMode?: string }).operationMode ?? process.env.AKAN_PUBLIC_OPERATION_MODE) === "edge";
852
+ }
853
+
826
854
  static #isEnvEnabled(...names: string[]) {
827
855
  return names.some((name) => process.env[name] === "true" || process.env[name] === "1");
828
856
  }
@@ -864,11 +892,19 @@ export class AkanServer {
864
892
  ...(Number.isInteger(promptBudget) && promptBudget > 0 ? { promptBudget } : {}),
865
893
  ...(process.env.AKAN_MCP_LANGUAGE ? { language: process.env.AKAN_MCP_LANGUAGE } : {}),
866
894
  ...(AkanServer.#isEnvOff("AKAN_MCP_LEGACY_TEXT") ? { legacyTextBlock: false } : {}),
895
+ ...(AkanServer.#isEnvOff("AKAN_MCP_APPS") ? { apps: false } : {}),
896
+ ...AkanServer.#mcpModernFromEnv(),
867
897
  ...AkanServer.#mcpOutputSchemaFromEnv(),
868
898
  ...AkanServer.#mcpRateLimitFromEnv(),
869
899
  };
870
900
  }
871
901
 
902
+ static #mcpModernFromEnv(): Pick<McpServerOption, "modern"> {
903
+ const raw = process.env.AKAN_MCP_MODERN;
904
+ if (raw === "true" || raw === "1") return { modern: true };
905
+ return AkanServer.#isEnvOff("AKAN_MCP_MODERN") ? { modern: false } : {};
906
+ }
907
+
872
908
  static #mcpRateLimitFromEnv(): Pick<McpServerOption, "rateLimit"> {
873
909
  const raw = process.env.AKAN_MCP_RATE_LIMIT?.trim().toLowerCase();
874
910
  if (raw === "off" || raw === "false" || raw === "0") return { rateLimit: false };
@@ -104,9 +104,14 @@ export class BuilderRpc {
104
104
  };
105
105
  }
106
106
 
107
- /** Arms dev CSR, which the builder skips by default (a full browser build per save), and keeps it in sync after. */
108
- async buildCsr(reason: string): Promise<void> {
109
- await this.#request<void>(`build-csr (${reason})`, (id) => this.#send({ type: "build-csr", id, reason }));
107
+ /**
108
+ * Arms dev CSR, which the builder skips by default (a full browser build per save), and keeps it in sync after.
109
+ * `shell` arms nothing: it asks for an MCP Apps view's single-file build, rebuilt only once a save moved past it.
110
+ */
111
+ async buildCsr(reason: string, { shell = false }: { shell?: boolean } = {}): Promise<void> {
112
+ await this.#request<void>(`build-csr (${reason})`, (id) =>
113
+ this.#send({ type: "build-csr", id, reason, ...(shell ? { shell } : {}) }),
114
+ );
110
115
  }
111
116
 
112
117
  static #timeoutMs(): number {
@@ -70,8 +70,11 @@ export type BuilderRes =
70
70
  | { type: "build-route-res"; id: number; ok: true; data: BuildRouteResultPayload }
71
71
  | { type: "build-route-res"; id: number; ok: false; error: string };
72
72
 
73
- /** Sent by the first `/__csr` or `?csr=true` request (a device WebView in mobile dev) to arm the lazy dev CSR build. */
74
- export type BuilderCsrReq = { type: "build-csr"; id: number; reason: string };
73
+ /**
74
+ * Sent by the first `/__csr` or `?csr=true` request (a device WebView in mobile dev) to arm the lazy dev CSR build.
75
+ * `shell` asks once for the single-file build an MCP Apps view boots from, whatever the dev CSR mode, and arms nothing.
76
+ */
77
+ export type BuilderCsrReq = { type: "build-csr"; id: number; reason: string; shell?: boolean };
75
78
 
76
79
  export type BuilderCsrRes =
77
80
  | { type: "build-csr-res"; id: number; ok: true }