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,132 @@
1
+ import { type FileRef } from "../../../packages/core/src/index.ts";
2
+ /**
3
+ * A third-party page shown first-party inside an app window, for signage: a scoreboard, a menu board. The view is a
4
+ * webview of its own laid over the window's page, which cannot draw over it — hide the view to show the page.
5
+ *
6
+ * Nothing of the app reaches the view: no bridge, no init script of the app, no app scheme. It keeps its own browser
7
+ * profile (cookies, storage, cache), so `clearData` never touches the app's, and it navigates only to `allowOrigins`;
8
+ * popups, downloads and device permissions are refused. Listing the plugin in `native.plugins` is what lets an app
9
+ * open one.
10
+ *
11
+ * Windows has every method. macOS (14 or later, for its separate profile) has all but `sendKey`, `setMuted` and
12
+ * `capture`, and sends no `loadFailed` or `consoleMessage`. Linux, iOS and Android: UNSUPPORTED.
13
+ */
14
+ export type ExternalViewBounds = "fill" | {
15
+ x: number;
16
+ y: number;
17
+ width: number;
18
+ height: number;
19
+ };
20
+ export type ExternalViewConsoleLevel = "debug" | "info" | "warn" | "error";
21
+ export interface ExternalViewOpenOptions {
22
+ /** Names the view in every later call: letters, digits, `-` and `_`. */
23
+ id: string;
24
+ url: string;
25
+ /** The origins it may navigate to (`https://host[:port]`); `url` must be on one. */
26
+ allowOrigins: string[];
27
+ /** Logical pixels in the window's content area; "fill" (default) follows the window's size. */
28
+ bounds?: ExternalViewBounds;
29
+ /** Runs at the start of every top document, before the page's own scripts; read what it keeps with `evaluate`. */
30
+ initScript?: string;
31
+ muted?: boolean;
32
+ /** Media plays with sound without a gesture first (default true): nobody taps a signage screen. */
33
+ autoplay?: boolean;
34
+ /** Sends the page's console as `consoleMessage` from this level up (`true` is "warn"); off by default. */
35
+ console?: boolean | ExternalViewConsoleLevel;
36
+ /** The window it is laid over; the calling page's window by default. */
37
+ window?: number;
38
+ }
39
+ export interface ExternalViewState {
40
+ id: string;
41
+ window: number;
42
+ url: string;
43
+ visible: boolean;
44
+ /** Times its web process ended and the view loaded its page again. */
45
+ restarts: number;
46
+ }
47
+ export interface ExternalViewApi {
48
+ /** Opens the view, or brings an open one with this id to these options (a page that mounts again finds it). */
49
+ open(args: ExternalViewOpenOptions): Promise<ExternalViewState>;
50
+ /** Rejects NOT_ALLOWED for a URL on none of its `allowOrigins`. */
51
+ navigate(args: {
52
+ id: string;
53
+ url: string;
54
+ }): Promise<void>;
55
+ reload(args: {
56
+ id: string;
57
+ }): Promise<void>;
58
+ close(args: {
59
+ id: string;
60
+ }): Promise<void>;
61
+ list(): Promise<ExternalViewState[]>;
62
+ setVisible(args: {
63
+ id: string;
64
+ visible: boolean;
65
+ }): Promise<void>;
66
+ setBounds(args: {
67
+ id: string;
68
+ bounds: ExternalViewBounds;
69
+ }): Promise<void>;
70
+ /** The script's completion value; a promise is not awaited. An exception answers `null`: catch it in the script. */
71
+ evaluate(args: {
72
+ id: string;
73
+ script: string;
74
+ }): Promise<{
75
+ value: unknown;
76
+ }>;
77
+ /** A trusted key press (`{ key: "z", code: "KeyZ" }`), whether or not the view has the focus. Windows only. */
78
+ sendKey(args: {
79
+ id: string;
80
+ key: string;
81
+ code: string;
82
+ }): Promise<void>;
83
+ /** The view's own sound only; the system volume is the volume plugin's. Windows only. */
84
+ setMuted(args: {
85
+ id: string;
86
+ muted: boolean;
87
+ }): Promise<void>;
88
+ /** Clears the view's cookies, storage and cache; the app's own stay. */
89
+ clearData(args: {
90
+ id: string;
91
+ }): Promise<void>;
92
+ /** A PNG of the view's content, not of the screen. Windows only. */
93
+ capture(args: {
94
+ id: string;
95
+ }): Promise<FileRef & {
96
+ width?: number;
97
+ height?: number;
98
+ }>;
99
+ }
100
+ export interface ExternalViewEvents {
101
+ load: {
102
+ id: string;
103
+ state: "started" | "finished";
104
+ url: string;
105
+ };
106
+ /**
107
+ * A navigation that failed. `errorCode`: `http<status>` for a server's 4xx or 5xx page, else WebView2's own
108
+ * (`hostNameNotResolved`, `cannotConnect`, `timeout`, `certificate`, `disconnected`, …; a refused connection is
109
+ * `unknown`). Windows only.
110
+ */
111
+ loadFailed: {
112
+ id: string;
113
+ url: string;
114
+ errorCode: string;
115
+ };
116
+ /** Its web process ended; the view loads its page again by itself, sooner the first times. */
117
+ gone: {
118
+ id: string;
119
+ reason: string;
120
+ restarts: number;
121
+ };
122
+ /** `dropped`: messages left out before this one, past the rate cap. Windows only. */
123
+ consoleMessage: {
124
+ id: string;
125
+ level: ExternalViewConsoleLevel;
126
+ text: string;
127
+ url?: string;
128
+ line?: number;
129
+ dropped?: number;
130
+ };
131
+ }
132
+ export declare const externalView: import("../../../packages/core/src/plugin.ts").Plugin<ExternalViewApi, ExternalViewEvents>;
@@ -0,0 +1 @@
1
+ export * from "./src/index.d.ts";
@@ -63,6 +63,14 @@ export interface UpdatesApi {
63
63
  * releases; the running app stays, and a trial keeps its record.
64
64
  */
65
65
  reset(): Promise<void>;
66
+ /**
67
+ * Desktop: the manifest this app reads from now on, over the built `updates.channel` until set back with `null` —
68
+ * a server that moves this device between a pilot and a stable channel. A release older than the running one is
69
+ * never taken, so a device leaving a pilot channel stays on its pilot build until the other channel passes it.
70
+ */
71
+ setChannel(args: {
72
+ channel: string | null;
73
+ }): Promise<void>;
66
74
  }
67
75
  export interface UpdatesEvents {
68
76
  progress: UpdateProgress;
@@ -1,6 +1,9 @@
1
1
  import { type DesktopContext } from "../../../packages/desktop/src/plugin.ts";
2
- import type { DragDropEvent, WindowApi, WindowEvents } from "./index.ts";
2
+ import type { Display } from "../../screen/src/index.ts";
3
+ import type { DragDropEvent, PlaceOnDisplayOptions, WindowApi, WindowEvents } from "./index.ts";
3
4
  /** Regular files among the dropped paths, served at /__akan_native/file/<id>; folders and unreadable paths are left out. */
4
5
  export declare function droppedFiles(ctx: Pick<DesktopContext, "registerFile">, paths: string[]): NonNullable<DragDropEvent["files"]>;
6
+ export declare function displayOf(displays: Display[], args: PlaceOnDisplayOptions | undefined): Display;
7
+ export declare function placement(display: Display, args: PlaceOnDisplayOptions | undefined): Record<string, unknown>;
5
8
  declare const _default: import("../../../packages/desktop/src/plugin.ts").DesktopPlugin<WindowApi, WindowEvents>;
6
9
  export default _default;
@@ -27,6 +27,26 @@ export interface CreateWindowOptions {
27
27
  /** Default: offset from the focused window, like new documents on macOS. */
28
28
  x?: number;
29
29
  y?: number;
30
+ /** No title bar or border, from the first frame: a kiosk drawn at an exact size. */
31
+ frameless?: boolean;
32
+ }
33
+ /** A display of `screen.getDisplays()` and where on it the window goes. */
34
+ export interface PlaceOnDisplayOptions {
35
+ /** The display's `id`. */
36
+ display?: number;
37
+ /** Or its place in that list; 0 is the primary display. */
38
+ index?: number;
39
+ /** From the display's top-left corner, the window's frame; left out, the whole display. */
40
+ bounds?: {
41
+ x: number;
42
+ y: number;
43
+ width: number;
44
+ height: number;
45
+ };
46
+ /** "logical" (default): CSS px at that display's own scale. "physical": its device pixels, as a panel is specified. */
47
+ unit?: "logical" | "physical";
48
+ /** Borderless fullscreen on that display, in place of `bounds`. */
49
+ fullscreen?: boolean;
30
50
  }
31
51
  /** `window`: which window an op acts on. Default: the window of the page that calls. */
32
52
  type On = {
@@ -57,6 +77,30 @@ export interface WindowApi {
57
77
  setAlwaysOnTop(args: {
58
78
  value: boolean;
59
79
  } & On): Promise<WindowState>;
80
+ /** Shows or hides the title bar and border. */
81
+ setDecorations(args: {
82
+ value: boolean;
83
+ } & On): Promise<WindowState>;
84
+ /**
85
+ * Hides the pointer while it is over this window, as a kiosk screen does — over its external views too, on
86
+ * Windows; elsewhere on the desktop it still shows.
87
+ */
88
+ setCursorVisible(args: {
89
+ value: boolean;
90
+ } & On): Promise<WindowState>;
91
+ /**
92
+ * The smallest inner size, logical pixels; left out, none. The default is 320×240, which an LED board drawn at
93
+ * its device size (640×128 ÷ the display's `scale`) is below.
94
+ */
95
+ setMinSize(args: {
96
+ width?: number;
97
+ height?: number;
98
+ } & On): Promise<WindowState>;
99
+ /**
100
+ * Puts the window on one display, however the displays' scales differ. Bounds below the minimum size lower it to
101
+ * fit. NOT_FOUND for a display that is not connected.
102
+ */
103
+ placeOnDisplay(args: PlaceOnDisplayOptions & On): Promise<WindowState>;
60
104
  show(args?: On): Promise<WindowState>;
61
105
  hide(args?: On): Promise<WindowState>;
62
106
  focus(args?: On): Promise<WindowState>;
@@ -147,6 +191,11 @@ export interface WindowHandle {
147
191
  toggleMaximize(): Promise<WindowState>;
148
192
  setFullscreen(value: boolean): Promise<WindowState>;
149
193
  setAlwaysOnTop(value: boolean): Promise<WindowState>;
194
+ setDecorations(value: boolean): Promise<WindowState>;
195
+ setCursorVisible(value: boolean): Promise<WindowState>;
196
+ /** Left out: no minimum. */
197
+ setMinSize(width?: number, height?: number): Promise<WindowState>;
198
+ placeOnDisplay(options: PlaceOnDisplayOptions): Promise<WindowState>;
150
199
  show(): Promise<WindowState>;
151
200
  hide(): Promise<WindowState>;
152
201
  focus(): Promise<WindowState>;
@@ -30,6 +30,8 @@ interface ToolEntryBase {
30
30
  settle?: boolean;
31
31
  confirm?: ToolConfirm;
32
32
  guard?: ToolGuard;
33
+ /** What a person reads for the action in the host's own UI, a command palette; never sent to the model. */
34
+ label?: () => string | undefined;
33
35
  }
34
36
  export interface ToolActionEntry extends ToolEntryBase {
35
37
  run: (args: Record<string, unknown>) => unknown;
@@ -1,4 +1,4 @@
1
- import type { CsrNavigationPhase, CsrStackEntry, History, Location } from "akanjs/client";
1
+ import { type CsrNavigationPhase, type CsrStackEntry, type History, type Location } from "akanjs/client";
2
2
  interface CsrStackState {
3
3
  history: History;
4
4
  location: Location;
@@ -0,0 +1,14 @@
1
+ import { type AgenticSurface } from "../vendor/use-agentic.d.ts";
2
+ import { McpAppApprovals } from "./McpAppApprovals.d.ts";
3
+ import type { McpAppBridge, McpAppTool, McpToolResultLike } from "./McpAppBridge.d.ts";
4
+ export declare class McpAppAgent {
5
+ #private;
6
+ static readonly settleMs = 500;
7
+ static readonly contextLimit = 20000;
8
+ static readonly approvalMs = 25000;
9
+ constructor(bridge: McpAppBridge, surface?: AgenticSurface, approvals?: McpAppApprovals);
10
+ start(): void;
11
+ tools(): McpAppTool[];
12
+ call(name: string, args: Record<string, unknown>, signal: AbortSignal): Promise<McpToolResultLike>;
13
+ context(): string;
14
+ }
@@ -0,0 +1,8 @@
1
+ import type { PendingApproval, ToolApprovalRequest } from "../vendor/use-agentic.d.ts";
2
+ export declare class McpAppApprovals {
3
+ #private;
4
+ static get shared(): McpAppApprovals;
5
+ subscribe: (listener: () => void) => () => void;
6
+ current: () => PendingApproval | null;
7
+ ask({ callId, name, args, message }: ToolApprovalRequest, signal: AbortSignal): Promise<true | string>;
8
+ }
@@ -0,0 +1,101 @@
1
+ import { type FetchBridge } from "akanjs/fetch";
2
+ export interface McpToolResultLike {
3
+ content?: {
4
+ type: string;
5
+ text?: string;
6
+ }[];
7
+ structuredContent?: unknown;
8
+ isError?: boolean;
9
+ _meta?: Record<string, unknown>;
10
+ }
11
+ export interface McpAppTool {
12
+ name: string;
13
+ description?: string;
14
+ inputSchema: Record<string, unknown>;
15
+ annotations?: {
16
+ readOnlyHint?: boolean;
17
+ destructiveHint?: boolean;
18
+ openWorldHint?: boolean;
19
+ };
20
+ }
21
+ export interface McpAppToolServer {
22
+ list: () => McpAppTool[];
23
+ call: (name: string, args: Record<string, unknown>, signal: AbortSignal) => Promise<McpToolResultLike>;
24
+ }
25
+ export interface McpHostCapabilities {
26
+ openLinks?: object;
27
+ downloadFile?: object;
28
+ updateModelContext?: {
29
+ text?: object;
30
+ };
31
+ serverTools?: {
32
+ listChanged?: boolean;
33
+ };
34
+ }
35
+ export type McpDownloadContent = {
36
+ type: "resource";
37
+ resource: {
38
+ uri: string;
39
+ mimeType?: string;
40
+ text?: string;
41
+ blob?: string;
42
+ };
43
+ } | {
44
+ type: "resource_link";
45
+ uri: string;
46
+ name: string;
47
+ mimeType?: string;
48
+ };
49
+ export interface McpHostContext {
50
+ theme?: "light" | "dark";
51
+ displayMode?: "inline" | "fullscreen" | "pip";
52
+ locale?: string;
53
+ timeZone?: string;
54
+ containerDimensions?: {
55
+ width?: number;
56
+ height?: number;
57
+ maxWidth?: number;
58
+ maxHeight?: number;
59
+ };
60
+ styles?: {
61
+ variables?: Record<string, string | undefined>;
62
+ };
63
+ }
64
+ interface McpAppSnapshotRecord {
65
+ key: string;
66
+ args: Record<string, unknown>;
67
+ value: unknown;
68
+ }
69
+ export type McpAppStart = {
70
+ ok: true;
71
+ href: string;
72
+ snapshot: McpAppSnapshotRecord[];
73
+ account: Record<string, unknown> | null;
74
+ } | {
75
+ ok: false;
76
+ message: string;
77
+ };
78
+ export declare class McpAppBridge {
79
+ #private;
80
+ static readonly protocolVersion = "2026-01-26";
81
+ static readonly initializeTimeoutMs = 15000;
82
+ constructor();
83
+ get hostContext(): McpHostContext;
84
+ get hostCapabilities(): McpHostCapabilities;
85
+ /** Whether the host asked for the view's own tools, which is the only sign it offers them to its model. */
86
+ get toolsListed(): boolean;
87
+ connect(): Promise<McpAppStart>;
88
+ onHostContext(listener: (context: McpHostContext) => void): () => boolean;
89
+ request(method: string, params: Record<string, unknown>, { timeoutMs }?: {
90
+ timeoutMs?: number;
91
+ }): Promise<unknown>;
92
+ notify(method: string, params: Record<string, unknown>): void;
93
+ callTool(name: string, args: Record<string, unknown>): Promise<McpToolResultLike>;
94
+ openLink(url: string): Promise<void>;
95
+ downloadFile(contents: McpDownloadContent[]): Promise<void>;
96
+ updateModelContext(text: string): Promise<void>;
97
+ serveTools(server: McpAppToolServer): void;
98
+ toolsChanged(): void;
99
+ fetchBridge(snapshot: McpAppSnapshotRecord[]): FetchBridge;
100
+ }
101
+ export {};
@@ -0,0 +1,21 @@
1
+ import type { McpAppBridge } from "./McpAppBridge.d.ts";
2
+ export declare class McpAppView {
3
+ #private;
4
+ static readonly contentGap = 24;
5
+ static readonly hostTokens: {
6
+ readonly "--color-background-primary": readonly ["--background", "--card", "--popover"];
7
+ readonly "--color-background-secondary": readonly ["--muted"];
8
+ readonly "--color-text-primary": readonly ["--foreground", "--card-foreground", "--popover-foreground"];
9
+ readonly "--color-text-secondary": readonly ["--muted-foreground"];
10
+ readonly "--color-border-primary": readonly ["--border", "--input"];
11
+ readonly "--color-ring-primary": readonly ["--ring"];
12
+ readonly "--font-sans": readonly ["--font-sans"];
13
+ readonly "--font-mono": readonly ["--font-mono"];
14
+ };
15
+ constructor(bridge: McpAppBridge);
16
+ /** `href` in the host's language when the app speaks it: the page run used the server's MCP language. */
17
+ static localize(href: string, locale: string | undefined, locales: readonly string[]): string;
18
+ mount(): void;
19
+ /** In place of the app, for a result that names no screen: the host still sizes the view to what it shows. */
20
+ showUnavailable(message: string): void;
21
+ }
@@ -19,3 +19,4 @@ export { usePageTool } from "./usePageTool.d.ts";
19
19
  export type { ScreenScopeItem } from "./useScreenScope.d.ts";
20
20
  export { useScreenScope } from "./useScreenScope.d.ts";
21
21
  export { useThrottle } from "./useThrottle.d.ts";
22
+ export { useVisualViewportFrame, type VisualViewportFrame } from "./useVisualViewportFrame.d.ts";
@@ -1,4 +1,4 @@
1
- import type { Location, RouteGuide } from "akanjs/client";
1
+ import { type Location, type RouteGuide } from "akanjs/client";
2
2
  interface UseLocationOptions {
3
3
  rootRouteGuide: RouteGuide;
4
4
  }
@@ -0,0 +1,13 @@
1
+ export interface VisualViewportFrame {
2
+ /** The on-screen keyboard's height over the layout viewport's bottom; 0 while it is closed. */
3
+ keyboardHeight: number;
4
+ /** The visible rectangle's height and its scroll offset from the layout viewport's top, in CSS px. */
5
+ height: number;
6
+ offsetTop: number;
7
+ }
8
+ /**
9
+ * The visible part of the page while the on-screen keyboard is up, on the web. Only `visualViewport` reports the
10
+ * keyboard: `dvh` tracks the browser's own chrome, and iOS pans the visual viewport to the field instead of shrinking
11
+ * the page, so a fixed bottom bar stays behind the keyboard until it is placed at `offsetTop + height`.
12
+ */
13
+ export declare const useVisualViewportFrame: () => VisualViewportFrame;
package/ui/Agent/Chat.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { cn, usePage } from "akanjs/client";
2
+ import { cn, isMobileDevice, usePage } from "akanjs/client";
3
3
  import { AgentPrompts, type AgentVisualOption } from "akanjs/store";
4
4
  import {
5
5
  type KeyboardEvent as ReactKeyboardEvent,
@@ -41,7 +41,7 @@ import { type QueuedMessage, useChatQueue } from "./useChatQueue";
41
41
  import { useChatReferences } from "./useChatReferences";
42
42
  import { useChatVoice } from "./useChatVoice";
43
43
  import { useDraftRecall } from "./useDraftRecall";
44
- import { useKeyboardInset } from "./useKeyboardInset";
44
+ import { useKeyboardFrame } from "./useKeyboardFrame";
45
45
  import { type ReferenceSource, useReferenceMenu } from "./useReferenceMenu";
46
46
  import { useSlashMenu } from "./useSlashMenu";
47
47
  import type { VoiceEngine } from "./voice";
@@ -79,6 +79,10 @@ export interface ChatProps {
79
79
  /** `false` leaves Cmd/Ctrl+L to the browser. */
80
80
  shortcut?: boolean;
81
81
  launcherClassName?: string;
82
+ /** The corner the launcher sits in; it clears the page's bottom chrome and safe area either way. */
83
+ launcherPlacement?: "right" | "left";
84
+ /** Draws no launcher below this breakpoint; the panel still opens from the shortcut or a controlled `open`. */
85
+ hideLauncherBelow?: "sm" | "md" | "lg";
82
86
  panelClassName?: string;
83
87
  /** Shown in place of the intro line while the transcript is empty. */
84
88
  intro?: ReactNode;
@@ -106,7 +110,13 @@ const isApplePlatform = () => {
106
110
  return /Mac|iPhone|iPad|iPod/i.test(data?.platform || navigator.platform || navigator.userAgent);
107
111
  };
108
112
 
109
- const launcherLayer = "fixed right-4 bottom-4 z-[150]";
113
+ const launcherLayer =
114
+ "fixed bottom-[calc(var(--akan-bottom-inset,0px)+max(var(--akan-bottom-safe-area,0px),env(safe-area-inset-bottom,0px))+1rem)] z-[80]";
115
+ const launcherSides = {
116
+ right: "right-[calc(env(safe-area-inset-right,0px)+1rem)]",
117
+ left: "left-[calc(env(safe-area-inset-left,0px)+1rem)]",
118
+ } as const;
119
+ const launcherHiddenBelow = { sm: "max-sm:hidden", md: "max-md:hidden", lg: "max-lg:hidden" } as const;
110
120
 
111
121
  const panelLayer = "fixed inset-0 z-[150] sm:inset-auto sm:right-4 sm:bottom-4";
112
122
  const panelSize =
@@ -132,6 +142,8 @@ export const DefaultChat = ({
132
142
  inline = false,
133
143
  shortcut = true,
134
144
  launcherClassName,
145
+ launcherPlacement = "right",
146
+ hideLauncherBelow,
135
147
  panelClassName,
136
148
  intro,
137
149
  header,
@@ -200,7 +212,7 @@ export const DefaultChat = ({
200
212
  const sticky = useRef(true);
201
213
  const returning = useRef(false);
202
214
  const read = useRef(session.messages.length);
203
- const keyboardInset = useKeyboardInset();
215
+ const keyboardFrame = useKeyboardFrame();
204
216
  const [overlay, setOverlay] = useState<HTMLElement | null>(null);
205
217
  useEffect(() => {
206
218
  setOverlay(document.body);
@@ -210,7 +222,7 @@ export const DefaultChat = ({
210
222
  if (sticky.current) listRef.current?.scrollTo({ top: listRef.current.scrollHeight });
211
223
  }, [version, open]);
212
224
  useEffect(() => {
213
- if (!shortcut) return;
225
+ if (!shortcut || globalThis.__AKAN_EMBED__) return;
214
226
  const apple = isApplePlatform();
215
227
  setHotkey(apple ? { label: "⌘ L", keys: "Meta+L" } : { label: "Ctrl+L", keys: "Control+L" });
216
228
  const onKeyDown = (event: KeyboardEvent) => {
@@ -232,7 +244,8 @@ export const DefaultChat = ({
232
244
  returning.current = false;
233
245
  return;
234
246
  }
235
- focusComposer();
247
+
248
+ if (!isMobileDevice()) focusComposer();
236
249
  }, [open, session.pendingQuestion?.callId]);
237
250
  useEffect(
238
251
  () => () => {
@@ -401,12 +414,19 @@ export const DefaultChat = ({
401
414
 
402
415
  const context = useMemo(() => session.context, [version]);
403
416
  const unread = open ? 0 : Math.max(0, session.messages.length - read.current);
404
- const layer = (surface: ReactNode) => (inline ? surface : overlay ? createPortal(surface, overlay) : null);
417
+
418
+ const layer = (surface: ReactNode) =>
419
+ globalThis.__AKAN_EMBED__ ? null : inline ? surface : overlay ? createPortal(surface, overlay) : null;
405
420
  if (!open)
406
421
  return launcher
407
422
  ? layer(
408
423
  <Launcher
409
- className={cn(!inline && launcherLayer, className, launcherClassName)}
424
+ className={cn(
425
+ !inline && [launcherLayer, launcherSides[launcherPlacement]],
426
+ hideLauncherBelow && launcherHiddenBelow[hideLauncherBelow],
427
+ className,
428
+ launcherClassName,
429
+ )}
410
430
  hotkey={hotkey}
411
431
  label={l("base.agent")}
412
432
  buttonRef={launcherRef}
@@ -428,8 +448,7 @@ export const DefaultChat = ({
428
448
  panelClassName,
429
449
  )}
430
450
  role="dialog"
431
-
432
- style={inline ? undefined : { paddingBottom: keyboardInset || undefined }}
451
+ style={inline ? undefined : keyboardFrame}
433
452
  {...files.dropProps}
434
453
  >
435
454
  {chrome ? (
@@ -72,7 +72,8 @@ export const DefaultComposer = ({
72
72
  }: ComposerProps) => {
73
73
  const { l } = usePage();
74
74
  const surface = useUiRecipe("input") ?? inputRecipe;
75
- const field = surface({ kind: "area", size: "sm" }, "max-h-32 flex-1 resize-none py-1.5");
75
+
76
+ const field = surface({ kind: "area", size: "sm" }, "max-h-32 flex-1 resize-none py-1.5 pointer-coarse:text-base");
76
77
  const placeholder = session.pendingQuestion
77
78
  ? l("base.agentAnswer")
78
79
  : session.isRunning
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { useSyncExternalStore } from "react";
3
+ import { createPortal } from "react-dom";
4
+ import { McpAppApprovals } from "../../webkit/McpAppApprovals";
5
+ import Approval from "./Approval";
6
+
7
+ export const EmbedApproval = () => {
8
+ const approvals = McpAppApprovals.shared;
9
+ const pending = useSyncExternalStore(approvals.subscribe, approvals.current, () => null);
10
+ if (!pending) return null;
11
+ return createPortal(
12
+ <div data-akan-embed-overlay="" className="fixed inset-x-0 bottom-0 z-[100] bg-background shadow-lg">
13
+ <Approval approval={pending} />
14
+ </div>,
15
+ document.body,
16
+ );
17
+ };
@@ -135,7 +135,7 @@ export const RichInput = ({
135
135
  suppressContentEditableWarning
136
136
  />
137
137
  {draft ? null : (
138
- <span className="pointer-events-none absolute inset-0 select-none px-3 py-1.5 text-foreground/40 text-sm">
138
+ <span className="pointer-events-none absolute inset-0 select-none px-3 py-1.5 pointer-coarse:text-base text-foreground/40 text-sm">
139
139
  {placeholder}
140
140
  </span>
141
141
  )}
package/ui/Agent/index.ts CHANGED
@@ -4,6 +4,7 @@ import { Guide } from "./Guide";
4
4
  import { History } from "./History";
5
5
  import { Chat } from "./index_";
6
6
  import { Skip } from "./Skip";
7
+ import { useScreenActions } from "./useScreenActions";
7
8
  import { Zone } from "./Zone";
8
9
 
9
10
  export const Agent = {
@@ -19,4 +20,5 @@ export const Agent = {
19
20
  Tool,
20
21
  Transcript,
21
22
  Zone,
23
+ useScreenActions,
22
24
  };
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import { useVisualViewportFrame } from "akanjs/webkit";
3
+ import type { CSSProperties } from "react";
4
+
5
+ export const useKeyboardFrame = (): CSSProperties | undefined => {
6
+ const { keyboardHeight, height, offsetTop } = useVisualViewportFrame();
7
+ if (!keyboardHeight) return undefined;
8
+ if (window.matchMedia("(width < 40rem)").matches) return { top: offsetTop, bottom: "auto", height };
9
+ return { paddingBottom: keyboardHeight };
10
+ };
@@ -0,0 +1,45 @@
1
+ "use client";
2
+ import { useEffect, useReducer } from "react";
3
+ import { AgenticSurface } from "../../vendor/use-agentic";
4
+
5
+ export interface ScreenAction {
6
+ name: string;
7
+ description?: string;
8
+ /** The tool's `label` (`st.tool(name, { label })`): what to show a person, in their language. */
9
+ label?: string;
10
+ /** A `remove*` tool, or one that declares `confirm`: ask the person before `run`. */
11
+ needsConfirm: boolean;
12
+ /** Runs the control's own handler, as its click does; refuses as the tool's guard does. */
13
+ run: () => Promise<void>;
14
+ }
15
+
16
+ /**
17
+ * The actions the current screen publishes that need no argument — what a command palette can offer, and exactly
18
+ * what the agent can do here. A person's pick is not recorded as an agent call.
19
+ */
20
+ export const useScreenActions = ({ surface = AgenticSurface.shared }: { surface?: AgenticSurface } = {}) => {
21
+ const [, refresh] = useReducer((version: number) => version + 1, 0);
22
+ useEffect(() => surface.subscribe(refresh), [surface]);
23
+ return surface
24
+ .snapshot()
25
+ .tools.filter((tool) => {
26
+ const required = tool.parameters?.required;
27
+ return !Array.isArray(required) || required.length === 0;
28
+ })
29
+ .map((tool): ScreenAction => {
30
+ const label = surface.tool(tool.name)?.label?.();
31
+ return {
32
+ name: tool.name,
33
+ ...(tool.description ? { description: tool.description } : {}),
34
+ ...(label ? { label } : {}),
35
+ needsConfirm: tool.needsConfirm,
36
+ run: async () => {
37
+ const entry = surface.tool(tool.name);
38
+ if (!entry || !("run" in entry) || !entry.run) return;
39
+ const verdict = entry.guard?.({}) ?? true;
40
+ if (verdict !== true) throw new Error(verdict);
41
+ await entry.run({});
42
+ },
43
+ };
44
+ });
45
+ };