akanjs 3.1.0-rc.2 → 3.1.0-rc.21

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 (392) hide show
  1. package/base/baseEnv.ts +5 -2
  2. package/client/device.ts +1 -1
  3. package/client/frameConfig.ts +2 -2
  4. package/client/href.ts +35 -0
  5. package/client/index.ts +1 -0
  6. package/client/makePageProto.tsx +3 -2
  7. package/client/router.ts +6 -4
  8. package/client/rscNavigation.ts +1 -1
  9. package/client/transitionTypes.ts +0 -4
  10. package/client/translator.ts +16 -0
  11. package/client/types.ts +3 -2
  12. package/client/viewportMeta.ts +23 -8
  13. package/client/webManifest.ts +5 -3
  14. package/common/TrustedProxy.ts +14 -0
  15. package/common/codeAgentWire.ts +8 -1
  16. package/common/index.ts +1 -0
  17. package/common/interpolateTranslation.ts +17 -3
  18. package/common/isEmail.ts +1 -1
  19. package/common/localeConfig.ts +10 -4
  20. package/common/markdownSpans.ts +1 -1
  21. package/common/restClient.ts +3 -1
  22. package/common/routeConvention.ts +4 -4
  23. package/common/trimSlashes.ts +11 -0
  24. package/common/types.ts +1 -1
  25. package/constant/fieldInfo.ts +2 -2
  26. package/constant/fieldPlan.ts +80 -0
  27. package/constant/index.ts +3 -0
  28. package/constant/inputParser.ts +148 -0
  29. package/constant/invalidInputError.ts +13 -0
  30. package/constant/serialize.ts +36 -20
  31. package/constant/types.ts +1 -1
  32. package/constant/via.ts +2 -0
  33. package/dictionary/base.dictionary.ts +4 -0
  34. package/dictionary/trans.ts +8 -0
  35. package/document/database.ts +3 -6
  36. package/document/documentSchema.ts +1 -1
  37. package/document/noDocumentError.ts +6 -1
  38. package/fetch/client/fetchClient.ts +2 -1
  39. package/fetch/client/sliceInitHandle.ts +2 -3
  40. package/fetch/fetchType/appliedReturn.type.ts +3 -1
  41. package/fetch/types.ts +4 -2
  42. package/index.ts +2 -0
  43. package/package.json +31 -21
  44. package/server/akanApp.ts +15 -3
  45. package/server/akanServer.ts +34 -14
  46. package/server/artifact/routeClientCache.ts +4 -5
  47. package/server/artifact/routeSeedIndexStore.ts +3 -20
  48. package/server/artifact/routeSeedMatcher.ts +70 -0
  49. package/server/console.ts +1 -1
  50. package/server/di/diLifecycle.ts +16 -7
  51. package/server/imageOptimizer.ts +1 -1
  52. package/server/index.ts +1 -0
  53. package/server/machine/machineAccount.ts +28 -3
  54. package/server/machine/machineToken.ts +27 -3
  55. package/server/mcp/McpDispatcher.ts +2 -3
  56. package/server/mcp/McpExecutionContext.ts +9 -3
  57. package/server/migration/docPath.ts +121 -0
  58. package/server/migration/index.ts +15 -0
  59. package/server/migration/migrationChangeLog.ts +86 -0
  60. package/server/migration/migrationChanges.ts +70 -0
  61. package/server/migration/migrationCommand.ts +179 -0
  62. package/server/migration/migrationContext.ts +53 -0
  63. package/server/migration/migrationDefinition.ts +87 -0
  64. package/server/migration/migrationError.ts +45 -0
  65. package/server/migration/migrationLedger.ts +172 -0
  66. package/server/migration/migrationLock.ts +103 -0
  67. package/server/migration/migrationParams.ts +122 -0
  68. package/server/migration/migrationPulse.ts +39 -0
  69. package/server/migration/migrationRunner.ts +525 -0
  70. package/server/migration/migrationScope.ts +93 -0
  71. package/server/migration/migrationTable.ts +258 -0
  72. package/server/migration/migrations.ts +57 -0
  73. package/server/ops/opsCommand.ts +30 -1
  74. package/server/resolver/CascadeRunner.ts +15 -2
  75. package/server/resolver/signal.resolver.ts +35 -55
  76. package/server/routeState.ts +0 -6
  77. package/server/rscClient.tsx +22 -37
  78. package/server/rscNavigationState.ts +3 -5
  79. package/server/rscScrollRestoration.ts +116 -0
  80. package/server/rscWorker.tsx +12 -19
  81. package/server/sitemap.ts +4 -4
  82. package/server/tunnel/TunnelAgent.ts +9 -1
  83. package/server/webRouter.ts +17 -2
  84. package/service/agent.service.ts +21 -1
  85. package/service/endpointCacheKeys.ts +35 -0
  86. package/service/index.ts +1 -0
  87. package/service/injectInfo.ts +2 -2
  88. package/service/predefinedAdaptor/anthropicLlm.ts +37 -17
  89. package/service/predefinedAdaptor/database.adaptor.ts +15 -0
  90. package/service/predefinedAdaptor/documentTransfer.ts +50 -0
  91. package/service/predefinedAdaptor/endpointCacheControl.adaptor.ts +19 -0
  92. package/service/predefinedAdaptor/index.ts +1 -0
  93. package/service/predefinedAdaptor/llm.adaptor.ts +7 -0
  94. package/service/predefinedAdaptor/openaiDialect.ts +53 -17
  95. package/service/predefinedAdaptor/openaiLlm.ts +1 -1
  96. package/service/predefinedAdaptor/sql/MigrationTables.ts +90 -0
  97. package/service/predefinedAdaptor/sql/RawDocumentTable.ts +200 -0
  98. package/service/predefinedAdaptor/sql/SqlDocumentStore.ts +6 -2
  99. package/service/predefinedAdaptor/sql/SqliteInsightSession.ts +4 -1
  100. package/service/predefinedAdaptor/sql/dialect/postgres.ts +0 -1
  101. package/service/predefinedAdaptor/sql/dialect/sqlite.ts +0 -1
  102. package/service/predefinedAdaptor/sql/types.ts +3 -1
  103. package/service/predefinedAdaptor/storage.adaptor.ts +19 -0
  104. package/signal/endpointCache.ts +23 -7
  105. package/signal/endpointErrorContract.ts +37 -0
  106. package/signal/endpointIdempotency.ts +5 -3
  107. package/signal/endpointInfo.ts +4 -1
  108. package/signal/endpointRateLimit.ts +6 -2
  109. package/signal/exception.ts +4 -1
  110. package/signal/index.ts +1 -0
  111. package/signal/mcp/McpDocument.ts +16 -1
  112. package/signal/mcp/McpUriTemplate.ts +1 -1
  113. package/signal/middlewareChain.ts +105 -0
  114. package/signal/openapi/openapi.ts +46 -2
  115. package/signal/serializer/fetch.serializer.ts +1 -0
  116. package/signal/signalContext.ts +110 -82
  117. package/signal/slice.ts +2 -2
  118. package/signal/trace.ts +8 -2
  119. package/signal/types.ts +13 -0
  120. package/store/action.ts +102 -42
  121. package/store/agent/ScreenImage.ts +166 -0
  122. package/store/agent/ScreenReader.ts +2 -1
  123. package/store/agent/StoreSurfaceSource.ts +41 -2
  124. package/store/agent/index.ts +2 -1
  125. package/store/databaseStateNames.ts +1 -0
  126. package/store/formUploadOf.ts +41 -0
  127. package/store/index.ts +1 -0
  128. package/store/liveInsert.ts +2 -2
  129. package/store/state.ts +9 -1
  130. package/store/stateBuilder.ts +8 -2
  131. package/store/storeInstance.ts +12 -3
  132. package/store/withSelector.ts +2 -2
  133. package/types/client/href.d.ts +11 -0
  134. package/types/client/index.d.ts +1 -0
  135. package/types/client/rscNavigation.d.ts +1 -1
  136. package/types/client/transitionTypes.d.ts +0 -2
  137. package/types/client/translator.d.ts +2 -0
  138. package/types/common/codeAgentWire.d.ts +7 -0
  139. package/types/common/index.d.ts +1 -0
  140. package/types/common/trimSlashes.d.ts +2 -0
  141. package/types/common/types.d.ts +1 -1
  142. package/types/constant/fieldInfo.d.ts +2 -2
  143. package/types/constant/fieldPlan.d.ts +33 -0
  144. package/types/constant/index.d.ts +3 -0
  145. package/types/constant/inputParser.d.ts +11 -0
  146. package/types/constant/invalidInputError.d.ts +8 -0
  147. package/types/constant/types.d.ts +1 -1
  148. package/types/dictionary/base.dictionary.d.ts +1 -1
  149. package/types/dictionary/dictionary.d.ts +3 -3
  150. package/types/dictionary/trans.d.ts +3 -0
  151. package/types/document/database.d.ts +2 -3
  152. package/types/document/documentSchema.d.ts +1 -1
  153. package/types/document/noDocumentError.d.ts +6 -1
  154. package/types/fetch/fetchType/appliedReturn.type.d.ts +3 -1
  155. package/types/fetch/types.d.ts +2 -2
  156. package/types/index.d.ts +5 -0
  157. package/types/server/akanServer.d.ts +1 -1
  158. package/types/server/artifact/routeSeedMatcher.d.ts +8 -0
  159. package/types/server/di/diLifecycle.d.ts +1 -0
  160. package/types/server/index.d.ts +1 -0
  161. package/types/server/machine/machineAccount.d.ts +1 -0
  162. package/types/server/machine/machineToken.d.ts +9 -0
  163. package/types/server/migration/docPath.d.ts +20 -0
  164. package/types/server/migration/index.d.ts +15 -0
  165. package/types/server/migration/migrationChangeLog.d.ts +27 -0
  166. package/types/server/migration/migrationChanges.d.ts +27 -0
  167. package/types/server/migration/migrationCommand.d.ts +33 -0
  168. package/types/server/migration/migrationContext.d.ts +28 -0
  169. package/types/server/migration/migrationDefinition.d.ts +42 -0
  170. package/types/server/migration/migrationError.d.ts +15 -0
  171. package/types/server/migration/migrationLedger.d.ts +51 -0
  172. package/types/server/migration/migrationLock.d.ts +34 -0
  173. package/types/server/migration/migrationParams.d.ts +41 -0
  174. package/types/server/migration/migrationPulse.d.ts +15 -0
  175. package/types/server/migration/migrationRunner.d.ts +93 -0
  176. package/types/server/migration/migrationScope.d.ts +42 -0
  177. package/types/server/migration/migrationTable.d.ts +52 -0
  178. package/types/server/migration/migrations.d.ts +12 -0
  179. package/types/server/migration.d.ts +1 -0
  180. package/types/server/ops/opsCommand.d.ts +10 -1
  181. package/types/server/routeState.d.ts +1 -4
  182. package/types/server/rscNavigationState.d.ts +2 -3
  183. package/types/server/rscScrollRestoration.d.ts +14 -0
  184. package/types/server/sitemap.d.ts +1 -1
  185. package/types/service/agent.service.d.ts +2 -0
  186. package/types/service/endpointCacheKeys.d.ts +8 -0
  187. package/types/service/index.d.ts +1 -0
  188. package/types/service/injectInfo.d.ts +2 -2
  189. package/types/service/predefinedAdaptor/anthropicLlm.d.ts +9 -4
  190. package/types/service/predefinedAdaptor/database.adaptor.d.ts +8 -1
  191. package/types/service/predefinedAdaptor/documentTransfer.d.ts +1 -0
  192. package/types/service/predefinedAdaptor/endpointCacheControl.adaptor.d.ts +9 -0
  193. package/types/service/predefinedAdaptor/index.d.ts +1 -0
  194. package/types/service/predefinedAdaptor/llm.adaptor.d.ts +7 -0
  195. package/types/service/predefinedAdaptor/openaiDialect.d.ts +20 -5
  196. package/types/service/predefinedAdaptor/sql/MigrationTables.d.ts +17 -0
  197. package/types/service/predefinedAdaptor/sql/RawDocumentTable.d.ts +38 -0
  198. package/types/service/predefinedAdaptor/sql/types.d.ts +1 -0
  199. package/types/service/predefinedAdaptor/storage.adaptor.d.ts +8 -0
  200. package/types/signal/endpointCache.d.ts +2 -0
  201. package/types/signal/endpointErrorContract.d.ts +10 -0
  202. package/types/signal/endpointIdempotency.d.ts +1 -0
  203. package/types/signal/endpointRateLimit.d.ts +1 -1
  204. package/types/signal/exception.d.ts +4 -1
  205. package/types/signal/index.d.ts +1 -0
  206. package/types/signal/middlewareChain.d.ts +11 -0
  207. package/types/signal/signalContext.d.ts +2 -6
  208. package/types/signal/slice.d.ts +1 -1
  209. package/types/signal/trace.d.ts +1 -1
  210. package/types/signal/types.d.ts +12 -0
  211. package/types/store/action.d.ts +2 -0
  212. package/types/store/agent/ScreenImage.d.ts +27 -0
  213. package/types/store/agent/StoreSurfaceSource.d.ts +1 -1
  214. package/types/store/agent/index.d.ts +2 -1
  215. package/types/store/databaseStateNames.d.ts +1 -0
  216. package/types/store/formUploadOf.d.ts +9 -0
  217. package/types/store/index.d.ts +1 -0
  218. package/types/store/state.d.ts +7 -1
  219. package/types/store/stateBuilder.d.ts +2 -1
  220. package/types/store/storeInstance.d.ts +2 -2
  221. package/types/store/withSelector.d.ts +1 -1
  222. package/types/ui/Agent/Composer.d.ts +2 -0
  223. package/types/ui/Agent/Menu.d.ts +2 -0
  224. package/types/ui/CsrImage.d.ts +2 -0
  225. package/types/ui/Data/CardList.d.ts +1 -1
  226. package/types/ui/Data/Dashboard.d.ts +1 -1
  227. package/types/ui/Data/Insight.d.ts +1 -1
  228. package/types/ui/Data/Item.d.ts +2 -2
  229. package/types/ui/Data/ListContainer.d.ts +1 -1
  230. package/types/ui/Data/Pagination.d.ts +1 -1
  231. package/types/ui/Data/TableList.d.ts +1 -1
  232. package/types/ui/Field/Relation.d.ts +13 -10
  233. package/types/ui/Field/index.d.ts +4 -4
  234. package/types/ui/Field/useRelationOptions.d.ts +3 -1
  235. package/types/ui/Field/useRelationWindow.d.ts +14 -0
  236. package/types/ui/Image.d.ts +3 -1
  237. package/types/ui/Load/View.d.ts +1 -1
  238. package/types/ui/Pagination.d.ts +1 -1
  239. package/types/ui/Signal/Arg.d.ts +1 -1
  240. package/types/ui/System/CSR.d.ts +1 -1
  241. package/types/ui/System/Client.d.ts +1 -1
  242. package/types/ui/System/SSR.d.ts +1 -1
  243. package/types/vendor/@akanjs/native/packages/core/src/plugin.d.ts +3 -3
  244. package/types/vendor/@akanjs/native/packages/desktop/src/page-veto.d.ts +1 -1
  245. package/types/vendor/@akanjs/native/packages/desktop/src/plugin.d.ts +1 -1
  246. package/types/vendor/@akanjs/native/plugins/auth-session/src/desktop.d.ts +2 -2
  247. package/types/vendor/@akanjs/native/plugins/auth-session/src/index.d.ts +1 -1
  248. package/types/vendor/@akanjs/native/plugins/autostart/src/desktop.d.ts +2 -2
  249. package/types/vendor/@akanjs/native/plugins/autostart/src/index.d.ts +1 -1
  250. package/types/vendor/@akanjs/native/plugins/badge/src/desktop.d.ts +1 -1
  251. package/types/vendor/@akanjs/native/plugins/badge/src/index.d.ts +1 -1
  252. package/types/vendor/@akanjs/native/plugins/badge/src/web.d.ts +1 -1
  253. package/types/vendor/@akanjs/native/plugins/biometric/src/index.d.ts +1 -1
  254. package/types/vendor/@akanjs/native/plugins/camera/src/desktop.d.ts +1 -1
  255. package/types/vendor/@akanjs/native/plugins/camera/src/index.d.ts +1 -1
  256. package/types/vendor/@akanjs/native/plugins/camera/src/web.d.ts +1 -1
  257. package/types/vendor/@akanjs/native/plugins/clipboard/src/desktop.d.ts +2 -2
  258. package/types/vendor/@akanjs/native/plugins/clipboard/src/index.d.ts +1 -1
  259. package/types/vendor/@akanjs/native/plugins/clipboard/src/web.d.ts +1 -1
  260. package/types/vendor/@akanjs/native/plugins/contacts/src/index.d.ts +1 -1
  261. package/types/vendor/@akanjs/native/plugins/device/src/desktop.d.ts +2 -2
  262. package/types/vendor/@akanjs/native/plugins/device/src/index.d.ts +1 -1
  263. package/types/vendor/@akanjs/native/plugins/device/src/web.d.ts +1 -1
  264. package/types/vendor/@akanjs/native/plugins/dialog/src/desktop.d.ts +1 -1
  265. package/types/vendor/@akanjs/native/plugins/dialog/src/index.d.ts +1 -1
  266. package/types/vendor/@akanjs/native/plugins/dialog/src/web.d.ts +1 -1
  267. package/types/vendor/@akanjs/native/plugins/dock/src/desktop.d.ts +1 -1
  268. package/types/vendor/@akanjs/native/plugins/dock/src/index.d.ts +1 -1
  269. package/types/vendor/@akanjs/native/plugins/file-picker/src/desktop.d.ts +2 -2
  270. package/types/vendor/@akanjs/native/plugins/file-picker/src/web.d.ts +1 -1
  271. package/types/vendor/@akanjs/native/plugins/filesystem/src/desktop.d.ts +2 -2
  272. package/types/vendor/@akanjs/native/plugins/filesystem/src/web.d.ts +1 -1
  273. package/types/vendor/@akanjs/native/plugins/haptics/src/index.d.ts +1 -1
  274. package/types/vendor/@akanjs/native/plugins/haptics/src/web.d.ts +1 -1
  275. package/types/vendor/@akanjs/native/plugins/http/src/desktop.d.ts +2 -2
  276. package/types/vendor/@akanjs/native/plugins/http/src/web.d.ts +1 -1
  277. package/types/vendor/@akanjs/native/plugins/keep-awake/src/desktop.d.ts +2 -2
  278. package/types/vendor/@akanjs/native/plugins/keep-awake/src/index.d.ts +1 -1
  279. package/types/vendor/@akanjs/native/plugins/keep-awake/src/web.d.ts +1 -1
  280. package/types/vendor/@akanjs/native/plugins/opener/src/desktop.d.ts +2 -2
  281. package/types/vendor/@akanjs/native/plugins/opener/src/index.d.ts +1 -1
  282. package/types/vendor/@akanjs/native/plugins/opener/src/web.d.ts +1 -1
  283. package/types/vendor/@akanjs/native/plugins/preferences/src/desktop.d.ts +1 -1
  284. package/types/vendor/@akanjs/native/plugins/preferences/src/index.d.ts +1 -1
  285. package/types/vendor/@akanjs/native/plugins/preferences/src/web.d.ts +1 -1
  286. package/types/vendor/@akanjs/native/plugins/secure-storage/src/desktop.d.ts +2 -2
  287. package/types/vendor/@akanjs/native/plugins/secure-storage/src/index.d.ts +1 -1
  288. package/types/vendor/@akanjs/native/plugins/share/src/index.d.ts +1 -1
  289. package/types/vendor/@akanjs/native/plugins/share/src/web.d.ts +1 -1
  290. package/types/vendor/@akanjs/native/plugins/single-instance/src/desktop.d.ts +2 -2
  291. package/types/vendor/@akanjs/native/plugins/splash-screen/src/index.d.ts +1 -1
  292. package/types/vendor/@akanjs/native/plugins/splash-screen/src/web.d.ts +1 -1
  293. package/types/vendor/@akanjs/native/plugins/sqlite/src/desktop.d.ts +2 -2
  294. package/types/vendor/@akanjs/native/plugins/toast/src/index.d.ts +1 -1
  295. package/types/vendor/@akanjs/native/plugins/toast/src/web.d.ts +1 -1
  296. package/types/vendor/@akanjs/native/plugins/window/src/index.d.ts +2 -2
  297. package/types/vendor/@akanjs/native/plugins/window-state/src/desktop.d.ts +2 -2
  298. package/types/vendor/@akanjs/native/plugins/window-state/src/index.d.ts +1 -1
  299. package/types/vendor/use-agentic/Compaction.d.ts +3 -1
  300. package/types/vendor/use-agentic/Reference.d.ts +9 -1
  301. package/types/vendor/use-agentic/ToolOutput.d.ts +6 -1
  302. package/types/vendor/use-agentic/ToolReturn.d.ts +18 -0
  303. package/types/vendor/use-agentic/Transcript.d.ts +7 -0
  304. package/types/vendor/use-agentic/index.d.ts +1 -0
  305. package/types/vendor/use-agentic/types.d.ts +6 -0
  306. package/types/webkit/useDebounce.d.ts +1 -1
  307. package/ui/Agent/Chat.tsx +1 -0
  308. package/ui/Agent/Composer.tsx +2 -0
  309. package/ui/Agent/Menu.tsx +5 -1
  310. package/ui/Agent/agentSessionOf.ts +15 -8
  311. package/ui/Agent/mentionDraft.ts +2 -3
  312. package/ui/Agent/useReferenceMenu.ts +1 -0
  313. package/ui/Agent/useSlashMenu.ts +1 -0
  314. package/ui/Clipboard.tsx +1 -0
  315. package/ui/CsrImage.tsx +3 -1
  316. package/ui/Data/CardList.tsx +1 -1
  317. package/ui/Data/Dashboard.tsx +1 -1
  318. package/ui/Data/Insight.tsx +1 -1
  319. package/ui/Data/Item.tsx +5 -2
  320. package/ui/Data/ListContainer.tsx +2 -2
  321. package/ui/Data/Pagination.tsx +1 -1
  322. package/ui/Data/TableList.tsx +1 -1
  323. package/ui/DraggableList.tsx +1 -0
  324. package/ui/Field/Collection.tsx +4 -0
  325. package/ui/Field/Relation.tsx +33 -14
  326. package/ui/Field/useRelationOptions.ts +33 -5
  327. package/ui/Field/useRelationWindow.ts +50 -0
  328. package/ui/Image.tsx +4 -4
  329. package/ui/Input.tsx +1 -0
  330. package/ui/Layout/Sider.tsx +1 -1
  331. package/ui/Link/Anchor.tsx +7 -5
  332. package/ui/Load/Units.tsx +17 -7
  333. package/ui/Load/View.tsx +2 -2
  334. package/ui/Model/Edit.tsx +1 -1
  335. package/ui/Model/EditModal.tsx +11 -5
  336. package/ui/Model/New.tsx +1 -1
  337. package/ui/Model/SureToRemove.tsx +1 -0
  338. package/ui/Model/ViewEditModal.tsx +17 -5
  339. package/ui/Model/ViewModal.tsx +2 -2
  340. package/ui/ObjectId.tsx +5 -1
  341. package/ui/Pagination.tsx +1 -1
  342. package/ui/Signal/Arg.tsx +1 -3
  343. package/ui/Signal/Doc.tsx +5 -1
  344. package/ui/System/CSR.tsx +1 -1
  345. package/ui/System/Client.tsx +1 -1
  346. package/ui/System/Reconnect.tsx +1 -1
  347. package/ui/System/SSR.tsx +3 -36
  348. package/ui/ToggleSelect.tsx +2 -0
  349. package/ui/styles.css +10 -103
  350. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeBridge.swift +3 -2
  351. package/vendor/@akanjs/native/packages/cli/src/lib/addons.ts +4 -1
  352. package/vendor/@akanjs/native/packages/cli/src/lib/apk.ts +2 -2
  353. package/vendor/@akanjs/native/packages/cli/src/lib/codegen.ts +1 -1
  354. package/vendor/@akanjs/native/packages/cli/src/lib/csp.ts +4 -3
  355. package/vendor/@akanjs/native/packages/cli/src/lib/googleservices.ts +7 -1
  356. package/vendor/@akanjs/native/packages/cli/src/lib/hmr.ts +8 -5
  357. package/vendor/@akanjs/native/packages/cli/src/lib/html.ts +18 -3
  358. package/vendor/@akanjs/native/packages/cli/src/lib/manifestmerge.ts +1 -1
  359. package/vendor/@akanjs/native/packages/cli/src/lib/plist.ts +2 -4
  360. package/vendor/@akanjs/native/packages/cli/src/lib/toolchains.ts +1 -1
  361. package/vendor/@akanjs/native/packages/cli/src/lib/updates.ts +10 -4
  362. package/vendor/@akanjs/native/packages/cli/src/lib/xml.ts +4 -3
  363. package/vendor/@akanjs/native/packages/cli/src/platforms/android.ts +3 -3
  364. package/vendor/@akanjs/native/packages/core/src/kernel.ts +3 -3
  365. package/vendor/@akanjs/native/packages/core/src/live.ts +1 -0
  366. package/vendor/@akanjs/native/packages/core/src/plugin.ts +5 -3
  367. package/vendor/@akanjs/native/packages/desktop/src/host.ts +13 -5
  368. package/vendor/@akanjs/native/packages/desktop/src/lifecycle.ts +1 -0
  369. package/vendor/@akanjs/native/packages/desktop/src/page-veto.ts +1 -1
  370. package/vendor/@akanjs/native/packages/desktop/src/plugin.ts +4 -1
  371. package/vendor/@akanjs/native/plugins/camera/src/web.ts +3 -3
  372. package/vendor/@akanjs/native/plugins/file-picker/src/index.ts +4 -1
  373. package/vendor/@akanjs/native/plugins/local-notifications/src/web.ts +1 -1
  374. package/vendor/@akanjs/native/plugins/secure-storage/src/desktop.ts +1 -1
  375. package/vendor/@akanjs/native/plugins/share/src/options.ts +1 -1
  376. package/vendor/@akanjs/native/plugins/single-instance/src/desktop.ts +3 -2
  377. package/vendor/@akanjs/native/plugins/updates/src/desktop.ts +4 -1
  378. package/vendor/@akanjs/native/plugins/window/src/index.ts +2 -2
  379. package/vendor/use-agentic/Compaction.ts +38 -7
  380. package/vendor/use-agentic/Reference.ts +16 -9
  381. package/vendor/use-agentic/ToolOutput.ts +25 -3
  382. package/vendor/use-agentic/ToolReturn.ts +32 -0
  383. package/vendor/use-agentic/ToolRunner.ts +15 -13
  384. package/vendor/use-agentic/Transcript.ts +38 -2
  385. package/vendor/use-agentic/WIRE.md +20 -0
  386. package/vendor/use-agentic/index.ts +1 -0
  387. package/vendor/use-agentic/types.ts +6 -0
  388. package/webkit/McpAppAgent.ts +12 -2
  389. package/webkit/RenderLayer.tsx +23 -4
  390. package/webkit/useDebounce.ts +23 -14
  391. package/client/viewTransition.ts +0 -10
  392. package/types/client/viewTransition.d.ts +0 -3
@@ -2,8 +2,6 @@ import { createElement, type ReactNode, startTransition, type Usable, use, useLa
2
2
  import { hydrateRoot } from "react-dom/client";
3
3
  import { createFromReadableStream } from "react-server-dom-webpack/client.browser";
4
4
  import type {} from "../client/rscNavigation";
5
- import { transitionTypes, viewTransitionClassOf } from "../client/transitionTypes";
6
- import { addTransitionType } from "../client/viewTransition";
7
5
  import {
8
6
  type AkanHeadSnapshotV1,
9
7
  type AkanRouterStateV1,
@@ -34,6 +32,7 @@ import {
34
32
  rememberRscCacheNode,
35
33
  resolveCachedRscPatchNavigation,
36
34
  } from "./rscNavigationState";
35
+ import { RscScrollRestoration } from "./rscScrollRestoration";
37
36
  import { commitAkanSegmentOutletPatch, resetAkanSegmentOutletPatches } from "./rscSegmentOutlet";
38
37
 
39
38
  type InlineRscChunk = [1, string] | [3, string];
@@ -156,14 +155,12 @@ function commitRscPatchNavigation({
156
155
  target,
157
156
  patch,
158
157
  replace,
159
- scrollToTop,
160
- bumpScrollToTop,
158
+ requestScroll,
161
159
  }: {
162
160
  target: string;
163
161
  patch: Extract<RscFetchResult, { type: "patched" }>;
164
162
  replace?: boolean;
165
- scrollToTop?: boolean;
166
- bumpScrollToTop?: () => void;
163
+ requestScroll?: () => void;
167
164
  }): boolean {
168
165
  const patchThenable = patch.patchedNode.thenable;
169
166
  if (!patchThenable) throw new Error("[rscClient] validated RSC patch is missing a thenable");
@@ -182,7 +179,7 @@ function commitRscPatchNavigation({
182
179
  return;
183
180
  }
184
181
  commitHistory(target, replace);
185
- if (scrollToTop) bumpScrollToTop?.();
182
+ requestScroll?.();
186
183
  } catch {
187
184
  if (headApplied) rollbackPreparedAkanHeadSnapshotPatch(preparedHeadPatch);
188
185
  if (outletCommitted) resetAkanSegmentOutletPatches();
@@ -197,10 +194,12 @@ function akanHistoryState(replace: boolean, shallow = false) {
197
194
  const idx = (window.history.state as { __akanRouter?: { idx?: unknown } } | null)?.__akanRouter?.idx;
198
195
  const current = Number.isInteger(idx) ? (idx as number) : 0;
199
196
  const shallowState = shallow ? { shallow: true, rendered: renderedHref } : {};
200
- return { __akanRouter: { idx: replace ? current : current + 1, ...shallowState } };
197
+ const scrollState = replace ? scrollRestoration.replaceEntry() : scrollRestoration.pushEntry();
198
+ return { __akanRouter: { idx: replace ? current : current + 1, ...scrollState, ...shallowState } };
201
199
  }
202
200
 
203
201
  let renderedHref = normalizeHref(window.location.href);
202
+ const scrollRestoration = new RscScrollRestoration();
204
203
  const pathnameOf = (href: string) => new URL(href).pathname;
205
204
 
206
205
  function commitHistory(target: string, replace: boolean | undefined) {
@@ -209,13 +208,6 @@ function commitHistory(target: string, replace: boolean | undefined) {
209
208
  renderedHref = target;
210
209
  }
211
210
 
212
- function viewTransitionTypeOf(transition: string | undefined, push: boolean): string | null {
213
- const type = transitionTypes.find((candidate) => candidate === transition);
214
- if (!type || type === "none") return null;
215
- if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) return null;
216
- return viewTransitionClassOf(type, push ? "push" : "pop");
217
- }
218
-
219
211
  /** Writes the entry without asking the server for the page; only a change that keeps the rendered path qualifies. */
220
212
  function navigateShallow(target: string, replace: boolean | undefined): boolean {
221
213
  if (pathnameOf(target) !== pathnameOf(renderedHref)) return false;
@@ -336,12 +328,11 @@ function rememberPatchedRouteState(tree: RscSegmentCacheNode, patchedNode: RscSe
336
328
 
337
329
  function Root(): ReactNode {
338
330
  const [thenable, setThenable] = useState<RscThenable>(initialThenable);
339
- const [scrollToTopTick, setScrollToTopTick] = useState(0);
331
+ const [scrollRequest, setScrollRequest] = useState<{ scrollY: number } | null>(null);
340
332
 
341
333
  useLayoutEffect(() => {
342
- if (!scrollToTopTick) return;
343
- window.scrollTo(0, 0);
344
- }, [scrollToTopTick]);
334
+ if (scrollRequest) scrollRestoration.scrollTo(scrollRequest.scrollY);
335
+ }, [scrollRequest]);
345
336
 
346
337
  globalThis.__AKAN_RSC_CLEAR_CACHE__ = () => {
347
338
  rscCache.clear();
@@ -419,7 +410,8 @@ function Root(): ReactNode {
419
410
  if (options.shallow && navigateShallow(normalizeHref(href), options.replace)) return;
420
411
  const navId = ++navigationSeq;
421
412
  const target = normalizeHref(href);
422
- const scrollToTop = options.scrollToTop ?? true;
413
+ const scrollY = options.scrollY ?? ((options.scrollToTop ?? true) ? 0 : undefined);
414
+ const requestScroll = scrollY === undefined ? undefined : () => setScrollRequest({ scrollY });
423
415
  try {
424
416
  let nextNode = rscCache.get(target);
425
417
  const servedFromCache = !!nextNode;
@@ -447,8 +439,7 @@ function Root(): ReactNode {
447
439
  target,
448
440
  patch: replayedPatch,
449
441
  replace: options.replace,
450
- scrollToTop,
451
- bumpScrollToTop: () => setScrollToTopTick((tick) => tick + 1),
442
+ requestScroll,
452
443
  })
453
444
  ) {
454
445
  currentCommitFromCache = true;
@@ -473,8 +464,7 @@ function Root(): ReactNode {
473
464
  target,
474
465
  patch: fetched,
475
466
  replace: options.replace,
476
- scrollToTop,
477
- bumpScrollToTop: () => setScrollToTopTick((tick) => tick + 1),
467
+ requestScroll,
478
468
  })
479
469
  ) {
480
470
  currentCommitFromCache = false;
@@ -516,11 +506,6 @@ function Root(): ReactNode {
516
506
  });
517
507
 
518
508
  await nextNode.thenable;
519
-
520
- const viewTransitionType = viewTransitionTypeOf(
521
- options.pop ? currentRouterState?.transition : nextNode.routerState?.transition,
522
- !options.pop,
523
- );
524
509
  const committed = commitLatestRscNavigation({
525
510
  cache: rscCache,
526
511
  href: target,
@@ -528,10 +513,6 @@ function Root(): ReactNode {
528
513
  maxEntries: MAX_RSC_CACHE_ENTRIES,
529
514
  startTransition,
530
515
  commitThenable: (node) => {
531
- if (viewTransitionType && addTransitionType) {
532
- addTransitionType("akan-nav");
533
- addTransitionType(viewTransitionType);
534
- }
535
516
  currentCommitFromCache = servedFromCache;
536
517
  resetAkanSegmentOutletPatches();
537
518
  setThenable(node.thenable);
@@ -539,8 +520,7 @@ function Root(): ReactNode {
539
520
  updateHistory: () => {
540
521
  commitHistory(target, options.replace);
541
522
  },
542
- scrollToTop,
543
- bumpScrollToTop: () => setScrollToTopTick((tick) => tick + 1),
523
+ requestScroll,
544
524
  navId,
545
525
  getCurrentNavId: () => navigationSeq,
546
526
  });
@@ -559,13 +539,15 @@ function Root(): ReactNode {
559
539
  window.addEventListener("popstate", (event) => {
560
540
  const here = normalizeHref(window.location.href);
561
541
  const entry = (event.state as { __akanRouter?: { shallow?: boolean; rendered?: string } } | null)?.__akanRouter;
542
+ const scrollY = scrollRestoration.traverseTo(event.state);
562
543
 
563
544
  const keepsPage = (entry?.shallow ? entry.rendered : here) === renderedHref;
564
545
 
565
546
  if (!keepsPage)
566
547
  void globalThis
567
- .__AKAN_RSC_NAVIGATE__?.(window.location.href, { replace: true, scrollToTop: false, pop: true })
548
+ .__AKAN_RSC_NAVIGATE__?.(window.location.href, { replace: true, scrollToTop: false, scrollY })
568
549
  ?.catch((error: unknown) => hardNavigateAfterRscFailure(window.location.href, true, error));
550
+ else if (scrollY !== undefined) scrollRestoration.scrollTo(scrollY);
569
551
  window.setTimeout(() => {
570
552
  if (globalThis.__AKAN_DEV_SYNC_NAVIGATION_APPLYING__) return;
571
553
  const href = globalThis.__AKAN_GET_SYNC_ROUTE_HREF__?.(window.location.href) ?? window.location.href;
@@ -573,5 +555,8 @@ window.addEventListener("popstate", (event) => {
573
555
  }, 0);
574
556
  });
575
557
 
576
- const hydrate = () => hydrateRoot(document, createElement(Root));
558
+ const hydrate = () => {
559
+ hydrateRoot(document, createElement(Root));
560
+ scrollRestoration.restoreDocumentLoad();
561
+ };
577
562
  void Promise.resolve(initialThenable).then(hydrate, hydrate);
@@ -312,8 +312,7 @@ interface CommitRscNavigationInput<T> {
312
312
  startTransition: (callback: () => void) => void;
313
313
  commitThenable: (thenable: T) => void;
314
314
  updateHistory?: () => void;
315
- scrollToTop?: boolean;
316
- bumpScrollToTop?: () => void;
315
+ requestScroll?: () => void;
317
316
  }
318
317
 
319
318
  export function commitRscNavigation<T>({
@@ -324,14 +323,13 @@ export function commitRscNavigation<T>({
324
323
  startTransition,
325
324
  commitThenable,
326
325
  updateHistory,
327
- scrollToTop,
328
- bumpScrollToTop,
326
+ requestScroll,
329
327
  }: CommitRscNavigationInput<T>): void {
330
328
  rememberRscCacheEntry(cache, href, thenable, maxEntries);
331
329
  startTransition(() => {
332
330
  commitThenable(thenable);
333
331
  updateHistory?.();
334
- if (scrollToTop) bumpScrollToTop?.();
332
+ requestScroll?.();
335
333
  });
336
334
  }
337
335
 
@@ -0,0 +1,116 @@
1
+ const RESTORE_WINDOW_MS = 2000;
2
+ const PERSIST_DELAY_MS = 200;
3
+ const userScrollEvents = ["wheel", "touchstart", "keydown", "pointerdown"] as const;
4
+
5
+ interface AkanEntryState {
6
+ key?: unknown;
7
+ scrollY?: unknown;
8
+ }
9
+
10
+ export class RscScrollRestoration {
11
+ #positions = new Map<string, number>();
12
+ #key: string;
13
+ #manual: boolean = false;
14
+ #persistTimer: ReturnType<typeof setTimeout> | null = null;
15
+ #cancelPending: (() => void) | null = null;
16
+
17
+ constructor() {
18
+ this.#key = RscScrollRestoration.#entryOf(window.history.state).key ?? RscScrollRestoration.#mintKey();
19
+
20
+ window.addEventListener("scroll", () => this.#schedulePersist(), { passive: true });
21
+ window.addEventListener("pagehide", () => {
22
+ if (this.#persistTimer) this.#persist();
23
+ });
24
+ }
25
+
26
+ pushEntry(): { key: string } {
27
+ this.#settle();
28
+ this.#manual = true;
29
+ window.history.scrollRestoration = "manual";
30
+ this.#positions.set(this.#key, window.scrollY);
31
+ this.#persist();
32
+ this.#key = RscScrollRestoration.#mintKey();
33
+ return { key: this.#key };
34
+ }
35
+
36
+ replaceEntry(): { key: string; scrollY?: number } {
37
+ const { scrollY } = RscScrollRestoration.#entryOf(window.history.state);
38
+ return { key: this.#key, ...(scrollY === undefined ? {} : { scrollY }) };
39
+ }
40
+
41
+ traverseTo(state: unknown): number | undefined {
42
+ this.#settle();
43
+ this.#positions.set(this.#key, window.scrollY);
44
+ const entry = RscScrollRestoration.#entryOf(state);
45
+ if (entry.key) {
46
+ this.#key = entry.key;
47
+ return this.#positions.get(entry.key) ?? entry.scrollY;
48
+ }
49
+
50
+ this.#key = RscScrollRestoration.#mintKey();
51
+ RscScrollRestoration.#writeEntry({ key: this.#key });
52
+ return undefined;
53
+ }
54
+
55
+ scrollTo(scrollY: number) {
56
+ this.#cancelPending?.();
57
+ window.scrollTo(0, scrollY);
58
+ if (scrollY === 0 || typeof ResizeObserver === "undefined") return;
59
+
60
+ const observer = new ResizeObserver(() => {
61
+ if (Math.abs(window.scrollY - scrollY) > 1) window.scrollTo(0, scrollY);
62
+ });
63
+ const timer = setTimeout(() => cancel(), RESTORE_WINDOW_MS);
64
+ const cancel = () => {
65
+ observer.disconnect();
66
+ clearTimeout(timer);
67
+ for (const type of userScrollEvents) window.removeEventListener(type, cancel, true);
68
+ if (this.#cancelPending === cancel) this.#cancelPending = null;
69
+ };
70
+ for (const type of userScrollEvents) window.addEventListener(type, cancel, { capture: true, passive: true });
71
+ observer.observe(document.body);
72
+ this.#cancelPending = cancel;
73
+ }
74
+
75
+ restoreDocumentLoad() {
76
+ if (window.history.scrollRestoration !== "manual") return;
77
+ this.#manual = true;
78
+ const { scrollY } = RscScrollRestoration.#entryOf(window.history.state);
79
+ if (scrollY !== undefined) this.scrollTo(scrollY);
80
+ }
81
+
82
+ #schedulePersist() {
83
+ if (!this.#manual) return;
84
+ if (this.#persistTimer) clearTimeout(this.#persistTimer);
85
+ this.#persistTimer = setTimeout(() => this.#persist(), PERSIST_DELAY_MS);
86
+ }
87
+
88
+ #persist() {
89
+ if (this.#persistTimer) clearTimeout(this.#persistTimer);
90
+ this.#persistTimer = null;
91
+ RscScrollRestoration.#writeEntry({ key: this.#key, scrollY: window.scrollY });
92
+ }
93
+
94
+ #settle() {
95
+ this.#cancelPending?.();
96
+ if (this.#persistTimer) clearTimeout(this.#persistTimer);
97
+ this.#persistTimer = null;
98
+ }
99
+
100
+ static #entryOf(state: unknown): { key?: string; scrollY?: number } {
101
+ const entry = (state as { __akanRouter?: AkanEntryState } | null)?.__akanRouter;
102
+ return {
103
+ key: typeof entry?.key === "string" ? entry.key : undefined,
104
+ scrollY: typeof entry?.scrollY === "number" && Number.isFinite(entry.scrollY) ? entry.scrollY : undefined,
105
+ };
106
+ }
107
+
108
+ static #writeEntry(fields: AkanEntryState) {
109
+ const state = (window.history.state ?? {}) as { __akanRouter?: object };
110
+ window.history.replaceState({ ...state, __akanRouter: { ...state.__akanRouter, ...fields } }, "");
111
+ }
112
+
113
+ static #mintKey() {
114
+ return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;
115
+ }
116
+ }
@@ -491,18 +491,11 @@ export class RscRenderer {
491
491
  const beforeLoadedKeys = RouteTreeBuilder.getCacheStats().loadedModuleKeys;
492
492
  const cacheDecision = match ? this.#getResultCacheEntry(request, urlObj) : { entry: null };
493
493
  const cacheEntry = cacheDecision.entry;
494
- const targetFrame = match
495
- ? await RouteElementComposer.resolveSsrFramePathRoute({
496
- pathRoute: match.pathRoute,
497
- basePath: this.#getBasePath(urlObj),
498
- })
499
- : null;
500
494
  const targetRouterState = match
501
495
  ? createAkanRouterState({
502
496
  pathRoute: match.pathRoute,
503
497
  href: urlObj.href,
504
498
  buildId: this.#pagesBundleBuildId,
505
- transition: targetFrame?.pageState.transition,
506
499
  })
507
500
  : null;
508
501
  const searchParams = parseSearchParams(urlObj.search);
@@ -886,8 +879,11 @@ export class RscRenderer {
886
879
  } = {},
887
880
  ): Promise<FlightRenderResult> {
888
881
  const controlRef: { current: RenderControl | null } = { current: null };
882
+
883
+ let isCancelling = false;
889
884
  const stream = await renderToReadableStream(element, clientManifest, {
890
885
  onError: (error) => {
886
+ if (isCancelling || (options.requestId && this.#cancelledRenderRequests.has(options.requestId))) return;
891
887
  if (isAkanRedirectError(error)) {
892
888
  const { location, method, status } = error;
893
889
  controlRef.current = { type: "redirect", location, method, status };
@@ -934,6 +930,11 @@ export class RscRenderer {
934
930
  reportedTheme = theme;
935
931
  this.#send({ type: "theme", requestId: options.requestId, theme });
936
932
  };
933
+ const cancelWith = async (control: RenderControl | null, cancelled: boolean): Promise<FlightRenderResult> => {
934
+ isCancelling = true;
935
+ await reader.cancel();
936
+ return { chunks, bytes, chunksCount, control, lateControlSent, cancelled };
937
+ };
937
938
  const readProbe = () => {
938
939
  if (!controlRef.current && options.notFoundProbe?.hit) controlRef.current = { type: "not-found" };
939
940
  };
@@ -960,26 +961,18 @@ export class RscRenderer {
960
961
  };
961
962
  try {
962
963
  for (;;) {
963
- if (options.requestId && this.#cancelledRenderRequests.has(options.requestId)) {
964
- await reader.cancel();
965
- return { chunks, bytes, chunksCount, control: null, lateControlSent, cancelled: true };
966
- }
964
+ if (options.requestId && this.#cancelledRenderRequests.has(options.requestId))
965
+ return await cancelWith(null, true);
967
966
  const { value, done } = await reader.read();
968
967
  readProbe();
969
- if (controlRef.current && !sentChunk) {
970
- await reader.cancel();
971
- return { chunks, bytes, chunksCount, control: controlRef.current, lateControlSent, cancelled: false };
972
- }
968
+ if (controlRef.current && !sentChunk) return await cancelWith(controlRef.current, false);
973
969
  if (controlRef.current && sentChunk) sendLateControl();
974
970
  if (done) break;
975
971
 
976
972
  if (!sentChunk && options.requestId) {
977
973
  await new Promise((resolve) => setTimeout(resolve, 0));
978
974
  readProbe();
979
- if (controlRef.current) {
980
- await reader.cancel();
981
- return { chunks, bytes, chunksCount, control: controlRef.current, lateControlSent, cancelled: false };
982
- }
975
+ if (controlRef.current) return await cancelWith(controlRef.current, false);
983
976
  }
984
977
  const chunk = value instanceof Uint8Array ? value : new Uint8Array(value as ArrayBufferLike);
985
978
  bytes += chunk.byteLength;
package/server/sitemap.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AkanI18nConfig } from "akanjs/common";
1
+ import { type AkanI18nConfig, trimSlashes, trimTrailingSlashes } from "akanjs/common";
2
2
  import type { RouteSeedEntry } from "./artifact";
3
3
 
4
4
  export interface DefaultSitemapOptions {
@@ -24,7 +24,7 @@ export function createDefaultSitemapXml({ origin, basePath, entries, i18n }: Def
24
24
  }
25
25
 
26
26
  export function createDefaultSitemapUrls({ origin, basePath, entries, i18n }: DefaultSitemapOptions): string[] {
27
- const normalizedOrigin = origin.replace(/\/+$/, "");
27
+ const normalizedOrigin = trimTrailingSlashes(origin);
28
28
  const normalizedBasePath = normalizeSegment(basePath ?? "");
29
29
  const paths = entries.flatMap((entry) => expandStaticRoute(entry.pattern, normalizedBasePath, i18n.locales));
30
30
  return paths.map((pathname) => `${normalizedOrigin}${pathname}`);
@@ -66,12 +66,12 @@ function expandStaticRoute(pattern: string, basePath: string, locales: readonly
66
66
  }
67
67
 
68
68
  function normalizePathname(pathname: string): string {
69
- const trimmed = pathname.trim().replace(/\/+$/, "");
69
+ const trimmed = trimTrailingSlashes(pathname.trim());
70
70
  return trimmed ? `/${trimmed.replace(/^\/+/, "")}` : "/";
71
71
  }
72
72
 
73
73
  function normalizeSegment(value: string): string {
74
- return value.trim().replace(/^\/+|\/+$/g, "");
74
+ return trimSlashes(value.trim());
75
75
  }
76
76
 
77
77
  function encodePathSegment(value: string): string {
@@ -38,6 +38,8 @@ const backoffMs = [1_000, 2_000, 4_000, 8_000, 15_000];
38
38
 
39
39
  const coldAttemptLimit = 10;
40
40
 
41
+ const heartbeatRangeMs = { min: 1_000, max: 300_000 } as const;
42
+
41
43
  /** Dials out to the gateway, so its machine needs no public address, no inbound port and no NAT traversal. */
42
44
  export class TunnelAgent {
43
45
  readonly #options: TunnelAgentOptions;
@@ -123,7 +125,7 @@ export class TunnelAgent {
123
125
  this.#everReady = true;
124
126
 
125
127
  this.#attempts = 0;
126
- this.#startHeartbeat(frame.heartbeatMs || tunnelWireContract.defaultHeartbeatMs);
128
+ this.#startHeartbeat(TunnelAgent.#heartbeatOf(frame.heartbeatMs));
127
129
  this.#grow();
128
130
  this.logger.info(`Tunnel ready: ${frame.urls.join(", ")}`);
129
131
  onReady(frame);
@@ -202,6 +204,12 @@ export class TunnelAgent {
202
204
  this.#heartbeat = null;
203
205
  }
204
206
 
207
+ static #heartbeatOf(requestedMs: number) {
208
+ return requestedMs >= heartbeatRangeMs.min && requestedMs <= heartbeatRangeMs.max
209
+ ? requestedMs
210
+ : tunnelWireContract.defaultHeartbeatMs;
211
+ }
212
+
205
213
  #say(frame: TunnelControlFromAgent) {
206
214
  if (this.#ws?.readyState !== WebSocket.OPEN) return;
207
215
  this.#ws.send(JSON.stringify(frame));
@@ -242,7 +242,7 @@ export function normalizeRscTargetUrlForHostBasePath(
242
242
  if (routeMatches(normalized)) return { url: normalized, basePath: candidate };
243
243
  }
244
244
 
245
- return { url: targetUrl, basePath: basePath ?? targetBasePath };
245
+ return { url: targetUrl, basePath: targetBasePath };
246
246
  }
247
247
 
248
248
  export interface SsrRoutesInputs {
@@ -367,6 +367,7 @@ export class WebRouter {
367
367
  const localCsrDir = path.join(process.cwd(), "csr");
368
368
  const csrOutputDir = fs.existsSync(localCsrDir) ? localCsrDir : path.join(this.#artifactDir, "csr");
369
369
  const publicDir = path.join(process.env.AKAN_APP_DIR ?? path.dirname(Bun.main), "public");
370
+ const shippedPublicFiles = this.#prodMode ? WebRouter.#shippedFiles(publicDir) : null;
370
371
  const imageCacheDir = path.join(this.#artifactDir, "image-cache");
371
372
  const imageOptimizer = new ImageOptimizer({
372
373
  publicDir,
@@ -566,7 +567,7 @@ export class WebRouter {
566
567
  }
567
568
 
568
569
  const filePath = resolveStaticPath(publicDir, url.pathname);
569
- if (filePath && (await Bun.file(filePath).exists())) {
570
+ if (filePath && (await WebRouter.#isPublicFile(filePath, url.pathname, shippedPublicFiles))) {
570
571
  this.#requestStats.staticAsset += 1;
571
572
  const contentType = Bun.file(filePath).type || "application/octet-stream";
572
573
  return WebRouter.#fileResponse(req, filePath, {
@@ -1116,6 +1117,20 @@ export class WebRouter {
1116
1117
  this.#logger.warn(`[csr] ${message}`);
1117
1118
  return new Response(message, { status: 404, headers: { "Content-Type": "text/plain; charset=utf-8" } });
1118
1119
  }
1120
+
1121
+ static async #isPublicFile(filePath: string, pathname: string, shipped: Set<string> | null) {
1122
+ if (shipped && !path.extname(pathname)) return shipped.has(filePath);
1123
+ return await Bun.file(filePath).exists();
1124
+ }
1125
+
1126
+ static #shippedFiles(dir: string): Set<string> {
1127
+ const files = new Set<string>();
1128
+ if (!fs.existsSync(dir)) return files;
1129
+ const scan = new Bun.Glob("**/*").scanSync({ cwd: dir, onlyFiles: true, dot: true, followSymlinks: true });
1130
+ for (const relative of scan) files.add(path.resolve(dir, relative));
1131
+ return files;
1132
+ }
1133
+
1119
1134
  static #injectBeforeBodyEnd(html: string, snippet: string): string {
1120
1135
  const matches = [...html.matchAll(/<\/body\s*>/gi)];
1121
1136
  const last = matches.at(-1);
@@ -3,6 +3,7 @@ import type {
3
3
  AgentWireAttachment,
4
4
  AgentWireMessage,
5
5
  AgentWireReference,
6
+ AgentWireToolResult,
6
7
  LlmAccepts,
7
8
  LlmTurnRequest,
8
9
  } from "./predefinedAdaptor/llm.adaptor";
@@ -104,12 +105,21 @@ export class AgentService extends serve("agent" as const, ({ plug }) => ({
104
105
 
105
106
  /** Swaps an attachment the provider cannot read for a note; dropped silently, it is guessed at from its name. */
106
107
  static readable(request: LlmTurnRequest, accepts: LlmAccepts | undefined): LlmTurnRequest {
107
- if (!request.messages.some((message) => message.attachments?.length)) return request;
108
+ if (!request.messages.some(AgentService.carriesFiles)) return request;
108
109
  const messages = request.messages.map((message) => AgentService.readableMessage(message, accepts ?? {}));
109
110
  return { ...request, messages };
110
111
  }
111
112
 
113
+ private static carriesFiles(message: AgentWireMessage): boolean {
114
+ return !!message.attachments?.length || !!message.toolResults?.some((result) => result.attachments?.length);
115
+ }
116
+
112
117
  private static readableMessage(message: AgentWireMessage, accepts: LlmAccepts): AgentWireMessage {
118
+ if (message.role === "tool")
119
+ return {
120
+ ...message,
121
+ toolResults: (message.toolResults ?? []).map((result) => AgentService.readableResult(result, accepts)),
122
+ };
113
123
  const { attachments = [], ...rest } = message;
114
124
  if (!attachments.length) return message;
115
125
  const kept = attachments.filter((attachment) => AgentService.isReadable(attachment, accepts));
@@ -122,6 +132,16 @@ export class AgentService extends serve("agent" as const, ({ plug }) => ({
122
132
  };
123
133
  }
124
134
 
135
+ private static readableResult(result: AgentWireToolResult, accepts: LlmAccepts): AgentWireToolResult {
136
+ if (!result.attachments?.length) return result;
137
+ const attachments = result.attachments.map((attachment) =>
138
+ AgentService.isReadable(attachment, accepts)
139
+ ? attachment
140
+ : { name: attachment.name, mimeType: attachment.mimeType, text: AgentService.note(attachment) },
141
+ );
142
+ return { ...result, attachments };
143
+ }
144
+
125
145
  private static isReadable(attachment: AgentWireAttachment, accepts: LlmAccepts): boolean {
126
146
  if (attachment.text) return true;
127
147
  if (!attachment.data && !attachment.url) return false;
@@ -0,0 +1,35 @@
1
+ import { dayjs } from "akanjs/base";
2
+ import type { CacheAdaptor } from "./predefinedAdaptor/cache.adaptor";
3
+
4
+ export class EndpointCacheKeys {
5
+ static readonly topic = "cache";
6
+ static readonly generationTtlMs = 86_400_000;
7
+ static readonly #generationTopic = "cacheGeneration";
8
+
9
+ static async entryKey(cache: Pick<CacheAdaptor, "get" | "setIfAbsent">, endpoint: string, args: unknown[]) {
10
+ return `${endpoint}:${await EndpointCacheKeys.#generation(cache, endpoint)}:${JSON.stringify(args)}`;
11
+ }
12
+
13
+ static async invalidate(
14
+ cache: Pick<CacheAdaptor, "get" | "set" | "setIfAbsent" | "delete">,
15
+ endpoint: string,
16
+ args?: unknown[],
17
+ ) {
18
+ if (args) await cache.delete(EndpointCacheKeys.topic, await EndpointCacheKeys.entryKey(cache, endpoint, args));
19
+ else
20
+ await cache.set(EndpointCacheKeys.#generationTopic, endpoint, crypto.randomUUID(), EndpointCacheKeys.#expiry());
21
+ }
22
+
23
+ static async #generation(cache: Pick<CacheAdaptor, "get" | "setIfAbsent">, endpoint: string) {
24
+ const current = await cache.get<string>(EndpointCacheKeys.#generationTopic, endpoint);
25
+ if (current !== undefined) return current;
26
+ const fresh = crypto.randomUUID();
27
+ if (await cache.setIfAbsent(EndpointCacheKeys.#generationTopic, endpoint, fresh, EndpointCacheKeys.#expiry()))
28
+ return fresh;
29
+ return (await cache.get<string>(EndpointCacheKeys.#generationTopic, endpoint)) ?? fresh;
30
+ }
31
+
32
+ static #expiry() {
33
+ return { expireAt: dayjs().add(EndpointCacheKeys.generationTtlMs, "millisecond") };
34
+ }
35
+ }
package/service/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./adapt";
2
2
  export * from "./agent.service";
3
3
  export * from "./base.service";
4
+ export * from "./endpointCacheKeys";
4
5
  export * from "./injectInfo";
5
6
  export * from "./ipcTypes";
6
7
  export * from "./liveSyncHub";
@@ -91,8 +91,8 @@ export const getDefaultLiveRegistry = (): LiveRegistry => ({
91
91
  export class InjectInfo<
92
92
  Type extends InjectType = any,
93
93
  ReturnType = any,
94
- Env extends { [key: string]: any } = never,
95
- FieldValue = never,
94
+ _Env extends { [key: string]: any } = never,
95
+ _FieldValue = never,
96
96
  > {
97
97
  readonly type: Type;
98
98
  readonly generateFactory: (options: any) => ReturnType;