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.
- package/base/baseEnv.ts +5 -2
- package/client/device.ts +1 -1
- package/client/frameConfig.ts +2 -2
- package/client/href.ts +35 -0
- package/client/index.ts +1 -0
- package/client/makePageProto.tsx +3 -2
- package/client/router.ts +6 -4
- package/client/rscNavigation.ts +1 -1
- package/client/transitionTypes.ts +0 -4
- package/client/translator.ts +16 -0
- package/client/types.ts +3 -2
- package/client/viewportMeta.ts +23 -8
- package/client/webManifest.ts +5 -3
- package/common/TrustedProxy.ts +14 -0
- package/common/codeAgentWire.ts +8 -1
- package/common/index.ts +1 -0
- package/common/interpolateTranslation.ts +17 -3
- package/common/isEmail.ts +1 -1
- package/common/localeConfig.ts +10 -4
- package/common/markdownSpans.ts +1 -1
- package/common/restClient.ts +3 -1
- package/common/routeConvention.ts +4 -4
- package/common/trimSlashes.ts +11 -0
- package/common/types.ts +1 -1
- package/constant/fieldInfo.ts +2 -2
- package/constant/fieldPlan.ts +80 -0
- package/constant/index.ts +3 -0
- package/constant/inputParser.ts +148 -0
- package/constant/invalidInputError.ts +13 -0
- package/constant/serialize.ts +36 -20
- package/constant/types.ts +1 -1
- package/constant/via.ts +2 -0
- package/dictionary/base.dictionary.ts +4 -0
- package/dictionary/trans.ts +8 -0
- package/document/database.ts +3 -6
- package/document/documentSchema.ts +1 -1
- package/document/noDocumentError.ts +6 -1
- package/fetch/client/fetchClient.ts +2 -1
- package/fetch/client/sliceInitHandle.ts +2 -3
- package/fetch/fetchType/appliedReturn.type.ts +3 -1
- package/fetch/types.ts +4 -2
- package/index.ts +2 -0
- package/package.json +31 -21
- package/server/akanApp.ts +15 -3
- package/server/akanServer.ts +34 -14
- package/server/artifact/routeClientCache.ts +4 -5
- package/server/artifact/routeSeedIndexStore.ts +3 -20
- package/server/artifact/routeSeedMatcher.ts +70 -0
- package/server/console.ts +1 -1
- package/server/di/diLifecycle.ts +16 -7
- package/server/imageOptimizer.ts +1 -1
- package/server/index.ts +1 -0
- package/server/machine/machineAccount.ts +28 -3
- package/server/machine/machineToken.ts +27 -3
- package/server/mcp/McpDispatcher.ts +2 -3
- package/server/mcp/McpExecutionContext.ts +9 -3
- package/server/migration/docPath.ts +121 -0
- package/server/migration/index.ts +15 -0
- package/server/migration/migrationChangeLog.ts +86 -0
- package/server/migration/migrationChanges.ts +70 -0
- package/server/migration/migrationCommand.ts +179 -0
- package/server/migration/migrationContext.ts +53 -0
- package/server/migration/migrationDefinition.ts +87 -0
- package/server/migration/migrationError.ts +45 -0
- package/server/migration/migrationLedger.ts +172 -0
- package/server/migration/migrationLock.ts +103 -0
- package/server/migration/migrationParams.ts +122 -0
- package/server/migration/migrationPulse.ts +39 -0
- package/server/migration/migrationRunner.ts +525 -0
- package/server/migration/migrationScope.ts +93 -0
- package/server/migration/migrationTable.ts +258 -0
- package/server/migration/migrations.ts +57 -0
- package/server/ops/opsCommand.ts +30 -1
- package/server/resolver/CascadeRunner.ts +15 -2
- package/server/resolver/signal.resolver.ts +35 -55
- package/server/routeState.ts +0 -6
- package/server/rscClient.tsx +22 -37
- package/server/rscNavigationState.ts +3 -5
- package/server/rscScrollRestoration.ts +116 -0
- package/server/rscWorker.tsx +12 -19
- package/server/sitemap.ts +4 -4
- package/server/tunnel/TunnelAgent.ts +9 -1
- package/server/webRouter.ts +17 -2
- package/service/agent.service.ts +21 -1
- package/service/endpointCacheKeys.ts +35 -0
- package/service/index.ts +1 -0
- package/service/injectInfo.ts +2 -2
- package/service/predefinedAdaptor/anthropicLlm.ts +37 -17
- package/service/predefinedAdaptor/database.adaptor.ts +15 -0
- package/service/predefinedAdaptor/documentTransfer.ts +50 -0
- package/service/predefinedAdaptor/endpointCacheControl.adaptor.ts +19 -0
- package/service/predefinedAdaptor/index.ts +1 -0
- package/service/predefinedAdaptor/llm.adaptor.ts +7 -0
- package/service/predefinedAdaptor/openaiDialect.ts +53 -17
- package/service/predefinedAdaptor/openaiLlm.ts +1 -1
- package/service/predefinedAdaptor/sql/MigrationTables.ts +90 -0
- package/service/predefinedAdaptor/sql/RawDocumentTable.ts +200 -0
- package/service/predefinedAdaptor/sql/SqlDocumentStore.ts +6 -2
- package/service/predefinedAdaptor/sql/SqliteInsightSession.ts +4 -1
- package/service/predefinedAdaptor/sql/dialect/postgres.ts +0 -1
- package/service/predefinedAdaptor/sql/dialect/sqlite.ts +0 -1
- package/service/predefinedAdaptor/sql/types.ts +3 -1
- package/service/predefinedAdaptor/storage.adaptor.ts +19 -0
- package/signal/endpointCache.ts +23 -7
- package/signal/endpointErrorContract.ts +37 -0
- package/signal/endpointIdempotency.ts +5 -3
- package/signal/endpointInfo.ts +4 -1
- package/signal/endpointRateLimit.ts +6 -2
- package/signal/exception.ts +4 -1
- package/signal/index.ts +1 -0
- package/signal/mcp/McpDocument.ts +16 -1
- package/signal/mcp/McpUriTemplate.ts +1 -1
- package/signal/middlewareChain.ts +105 -0
- package/signal/openapi/openapi.ts +46 -2
- package/signal/serializer/fetch.serializer.ts +1 -0
- package/signal/signalContext.ts +110 -82
- package/signal/slice.ts +2 -2
- package/signal/trace.ts +8 -2
- package/signal/types.ts +13 -0
- package/store/action.ts +102 -42
- package/store/agent/ScreenImage.ts +166 -0
- package/store/agent/ScreenReader.ts +2 -1
- package/store/agent/StoreSurfaceSource.ts +41 -2
- package/store/agent/index.ts +2 -1
- package/store/databaseStateNames.ts +1 -0
- package/store/formUploadOf.ts +41 -0
- package/store/index.ts +1 -0
- package/store/liveInsert.ts +2 -2
- package/store/state.ts +9 -1
- package/store/stateBuilder.ts +8 -2
- package/store/storeInstance.ts +12 -3
- package/store/withSelector.ts +2 -2
- package/types/client/href.d.ts +11 -0
- package/types/client/index.d.ts +1 -0
- package/types/client/rscNavigation.d.ts +1 -1
- package/types/client/transitionTypes.d.ts +0 -2
- package/types/client/translator.d.ts +2 -0
- package/types/common/codeAgentWire.d.ts +7 -0
- package/types/common/index.d.ts +1 -0
- package/types/common/trimSlashes.d.ts +2 -0
- package/types/common/types.d.ts +1 -1
- package/types/constant/fieldInfo.d.ts +2 -2
- package/types/constant/fieldPlan.d.ts +33 -0
- package/types/constant/index.d.ts +3 -0
- package/types/constant/inputParser.d.ts +11 -0
- package/types/constant/invalidInputError.d.ts +8 -0
- package/types/constant/types.d.ts +1 -1
- package/types/dictionary/base.dictionary.d.ts +1 -1
- package/types/dictionary/dictionary.d.ts +3 -3
- package/types/dictionary/trans.d.ts +3 -0
- package/types/document/database.d.ts +2 -3
- package/types/document/documentSchema.d.ts +1 -1
- package/types/document/noDocumentError.d.ts +6 -1
- package/types/fetch/fetchType/appliedReturn.type.d.ts +3 -1
- package/types/fetch/types.d.ts +2 -2
- package/types/index.d.ts +5 -0
- package/types/server/akanServer.d.ts +1 -1
- package/types/server/artifact/routeSeedMatcher.d.ts +8 -0
- package/types/server/di/diLifecycle.d.ts +1 -0
- package/types/server/index.d.ts +1 -0
- package/types/server/machine/machineAccount.d.ts +1 -0
- package/types/server/machine/machineToken.d.ts +9 -0
- package/types/server/migration/docPath.d.ts +20 -0
- package/types/server/migration/index.d.ts +15 -0
- package/types/server/migration/migrationChangeLog.d.ts +27 -0
- package/types/server/migration/migrationChanges.d.ts +27 -0
- package/types/server/migration/migrationCommand.d.ts +33 -0
- package/types/server/migration/migrationContext.d.ts +28 -0
- package/types/server/migration/migrationDefinition.d.ts +42 -0
- package/types/server/migration/migrationError.d.ts +15 -0
- package/types/server/migration/migrationLedger.d.ts +51 -0
- package/types/server/migration/migrationLock.d.ts +34 -0
- package/types/server/migration/migrationParams.d.ts +41 -0
- package/types/server/migration/migrationPulse.d.ts +15 -0
- package/types/server/migration/migrationRunner.d.ts +93 -0
- package/types/server/migration/migrationScope.d.ts +42 -0
- package/types/server/migration/migrationTable.d.ts +52 -0
- package/types/server/migration/migrations.d.ts +12 -0
- package/types/server/migration.d.ts +1 -0
- package/types/server/ops/opsCommand.d.ts +10 -1
- package/types/server/routeState.d.ts +1 -4
- package/types/server/rscNavigationState.d.ts +2 -3
- package/types/server/rscScrollRestoration.d.ts +14 -0
- package/types/server/sitemap.d.ts +1 -1
- package/types/service/agent.service.d.ts +2 -0
- package/types/service/endpointCacheKeys.d.ts +8 -0
- package/types/service/index.d.ts +1 -0
- package/types/service/injectInfo.d.ts +2 -2
- package/types/service/predefinedAdaptor/anthropicLlm.d.ts +9 -4
- package/types/service/predefinedAdaptor/database.adaptor.d.ts +8 -1
- package/types/service/predefinedAdaptor/documentTransfer.d.ts +1 -0
- package/types/service/predefinedAdaptor/endpointCacheControl.adaptor.d.ts +9 -0
- package/types/service/predefinedAdaptor/index.d.ts +1 -0
- package/types/service/predefinedAdaptor/llm.adaptor.d.ts +7 -0
- package/types/service/predefinedAdaptor/openaiDialect.d.ts +20 -5
- package/types/service/predefinedAdaptor/sql/MigrationTables.d.ts +17 -0
- package/types/service/predefinedAdaptor/sql/RawDocumentTable.d.ts +38 -0
- package/types/service/predefinedAdaptor/sql/types.d.ts +1 -0
- package/types/service/predefinedAdaptor/storage.adaptor.d.ts +8 -0
- package/types/signal/endpointCache.d.ts +2 -0
- package/types/signal/endpointErrorContract.d.ts +10 -0
- package/types/signal/endpointIdempotency.d.ts +1 -0
- package/types/signal/endpointRateLimit.d.ts +1 -1
- package/types/signal/exception.d.ts +4 -1
- package/types/signal/index.d.ts +1 -0
- package/types/signal/middlewareChain.d.ts +11 -0
- package/types/signal/signalContext.d.ts +2 -6
- package/types/signal/slice.d.ts +1 -1
- package/types/signal/trace.d.ts +1 -1
- package/types/signal/types.d.ts +12 -0
- package/types/store/action.d.ts +2 -0
- package/types/store/agent/ScreenImage.d.ts +27 -0
- package/types/store/agent/StoreSurfaceSource.d.ts +1 -1
- package/types/store/agent/index.d.ts +2 -1
- package/types/store/databaseStateNames.d.ts +1 -0
- package/types/store/formUploadOf.d.ts +9 -0
- package/types/store/index.d.ts +1 -0
- package/types/store/state.d.ts +7 -1
- package/types/store/stateBuilder.d.ts +2 -1
- package/types/store/storeInstance.d.ts +2 -2
- package/types/store/withSelector.d.ts +1 -1
- package/types/ui/Agent/Composer.d.ts +2 -0
- package/types/ui/Agent/Menu.d.ts +2 -0
- package/types/ui/CsrImage.d.ts +2 -0
- package/types/ui/Data/CardList.d.ts +1 -1
- package/types/ui/Data/Dashboard.d.ts +1 -1
- package/types/ui/Data/Insight.d.ts +1 -1
- package/types/ui/Data/Item.d.ts +2 -2
- package/types/ui/Data/ListContainer.d.ts +1 -1
- package/types/ui/Data/Pagination.d.ts +1 -1
- package/types/ui/Data/TableList.d.ts +1 -1
- package/types/ui/Field/Relation.d.ts +13 -10
- package/types/ui/Field/index.d.ts +4 -4
- package/types/ui/Field/useRelationOptions.d.ts +3 -1
- package/types/ui/Field/useRelationWindow.d.ts +14 -0
- package/types/ui/Image.d.ts +3 -1
- package/types/ui/Load/View.d.ts +1 -1
- package/types/ui/Pagination.d.ts +1 -1
- package/types/ui/Signal/Arg.d.ts +1 -1
- package/types/ui/System/CSR.d.ts +1 -1
- package/types/ui/System/Client.d.ts +1 -1
- package/types/ui/System/SSR.d.ts +1 -1
- package/types/vendor/@akanjs/native/packages/core/src/plugin.d.ts +3 -3
- package/types/vendor/@akanjs/native/packages/desktop/src/page-veto.d.ts +1 -1
- package/types/vendor/@akanjs/native/packages/desktop/src/plugin.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/auth-session/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/auth-session/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/autostart/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/autostart/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/badge/src/desktop.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/badge/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/badge/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/biometric/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/camera/src/desktop.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/camera/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/camera/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/clipboard/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/clipboard/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/clipboard/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/contacts/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/device/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/device/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/device/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/dialog/src/desktop.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/dialog/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/dialog/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/dock/src/desktop.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/dock/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/file-picker/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/file-picker/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/filesystem/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/filesystem/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/haptics/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/haptics/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/http/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/http/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/keep-awake/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/keep-awake/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/keep-awake/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/opener/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/opener/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/opener/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/preferences/src/desktop.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/preferences/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/preferences/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/secure-storage/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/secure-storage/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/share/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/share/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/single-instance/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/splash-screen/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/splash-screen/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/sqlite/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/toast/src/index.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/toast/src/web.d.ts +1 -1
- package/types/vendor/@akanjs/native/plugins/window/src/index.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/window-state/src/desktop.d.ts +2 -2
- package/types/vendor/@akanjs/native/plugins/window-state/src/index.d.ts +1 -1
- package/types/vendor/use-agentic/Compaction.d.ts +3 -1
- package/types/vendor/use-agentic/Reference.d.ts +9 -1
- package/types/vendor/use-agentic/ToolOutput.d.ts +6 -1
- package/types/vendor/use-agentic/ToolReturn.d.ts +18 -0
- package/types/vendor/use-agentic/Transcript.d.ts +7 -0
- package/types/vendor/use-agentic/index.d.ts +1 -0
- package/types/vendor/use-agentic/types.d.ts +6 -0
- package/types/webkit/useDebounce.d.ts +1 -1
- package/ui/Agent/Chat.tsx +1 -0
- package/ui/Agent/Composer.tsx +2 -0
- package/ui/Agent/Menu.tsx +5 -1
- package/ui/Agent/agentSessionOf.ts +15 -8
- package/ui/Agent/mentionDraft.ts +2 -3
- package/ui/Agent/useReferenceMenu.ts +1 -0
- package/ui/Agent/useSlashMenu.ts +1 -0
- package/ui/Clipboard.tsx +1 -0
- package/ui/CsrImage.tsx +3 -1
- package/ui/Data/CardList.tsx +1 -1
- package/ui/Data/Dashboard.tsx +1 -1
- package/ui/Data/Insight.tsx +1 -1
- package/ui/Data/Item.tsx +5 -2
- package/ui/Data/ListContainer.tsx +2 -2
- package/ui/Data/Pagination.tsx +1 -1
- package/ui/Data/TableList.tsx +1 -1
- package/ui/DraggableList.tsx +1 -0
- package/ui/Field/Collection.tsx +4 -0
- package/ui/Field/Relation.tsx +33 -14
- package/ui/Field/useRelationOptions.ts +33 -5
- package/ui/Field/useRelationWindow.ts +50 -0
- package/ui/Image.tsx +4 -4
- package/ui/Input.tsx +1 -0
- package/ui/Layout/Sider.tsx +1 -1
- package/ui/Link/Anchor.tsx +7 -5
- package/ui/Load/Units.tsx +17 -7
- package/ui/Load/View.tsx +2 -2
- package/ui/Model/Edit.tsx +1 -1
- package/ui/Model/EditModal.tsx +11 -5
- package/ui/Model/New.tsx +1 -1
- package/ui/Model/SureToRemove.tsx +1 -0
- package/ui/Model/ViewEditModal.tsx +17 -5
- package/ui/Model/ViewModal.tsx +2 -2
- package/ui/ObjectId.tsx +5 -1
- package/ui/Pagination.tsx +1 -1
- package/ui/Signal/Arg.tsx +1 -3
- package/ui/Signal/Doc.tsx +5 -1
- package/ui/System/CSR.tsx +1 -1
- package/ui/System/Client.tsx +1 -1
- package/ui/System/Reconnect.tsx +1 -1
- package/ui/System/SSR.tsx +3 -36
- package/ui/ToggleSelect.tsx +2 -0
- package/ui/styles.css +10 -103
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeBridge.swift +3 -2
- package/vendor/@akanjs/native/packages/cli/src/lib/addons.ts +4 -1
- package/vendor/@akanjs/native/packages/cli/src/lib/apk.ts +2 -2
- package/vendor/@akanjs/native/packages/cli/src/lib/codegen.ts +1 -1
- package/vendor/@akanjs/native/packages/cli/src/lib/csp.ts +4 -3
- package/vendor/@akanjs/native/packages/cli/src/lib/googleservices.ts +7 -1
- package/vendor/@akanjs/native/packages/cli/src/lib/hmr.ts +8 -5
- package/vendor/@akanjs/native/packages/cli/src/lib/html.ts +18 -3
- package/vendor/@akanjs/native/packages/cli/src/lib/manifestmerge.ts +1 -1
- package/vendor/@akanjs/native/packages/cli/src/lib/plist.ts +2 -4
- package/vendor/@akanjs/native/packages/cli/src/lib/toolchains.ts +1 -1
- package/vendor/@akanjs/native/packages/cli/src/lib/updates.ts +10 -4
- package/vendor/@akanjs/native/packages/cli/src/lib/xml.ts +4 -3
- package/vendor/@akanjs/native/packages/cli/src/platforms/android.ts +3 -3
- package/vendor/@akanjs/native/packages/core/src/kernel.ts +3 -3
- package/vendor/@akanjs/native/packages/core/src/live.ts +1 -0
- package/vendor/@akanjs/native/packages/core/src/plugin.ts +5 -3
- package/vendor/@akanjs/native/packages/desktop/src/host.ts +13 -5
- package/vendor/@akanjs/native/packages/desktop/src/lifecycle.ts +1 -0
- package/vendor/@akanjs/native/packages/desktop/src/page-veto.ts +1 -1
- package/vendor/@akanjs/native/packages/desktop/src/plugin.ts +4 -1
- package/vendor/@akanjs/native/plugins/camera/src/web.ts +3 -3
- package/vendor/@akanjs/native/plugins/file-picker/src/index.ts +4 -1
- package/vendor/@akanjs/native/plugins/local-notifications/src/web.ts +1 -1
- package/vendor/@akanjs/native/plugins/secure-storage/src/desktop.ts +1 -1
- package/vendor/@akanjs/native/plugins/share/src/options.ts +1 -1
- package/vendor/@akanjs/native/plugins/single-instance/src/desktop.ts +3 -2
- package/vendor/@akanjs/native/plugins/updates/src/desktop.ts +4 -1
- package/vendor/@akanjs/native/plugins/window/src/index.ts +2 -2
- package/vendor/use-agentic/Compaction.ts +38 -7
- package/vendor/use-agentic/Reference.ts +16 -9
- package/vendor/use-agentic/ToolOutput.ts +25 -3
- package/vendor/use-agentic/ToolReturn.ts +32 -0
- package/vendor/use-agentic/ToolRunner.ts +15 -13
- package/vendor/use-agentic/Transcript.ts +38 -2
- package/vendor/use-agentic/WIRE.md +20 -0
- package/vendor/use-agentic/index.ts +1 -0
- package/vendor/use-agentic/types.ts +6 -0
- package/webkit/McpAppAgent.ts +12 -2
- package/webkit/RenderLayer.tsx +23 -4
- package/webkit/useDebounce.ts +23 -14
- package/client/viewTransition.ts +0 -10
- package/types/client/viewTransition.d.ts +0 -3
|
@@ -36,6 +36,7 @@ interface ActionProps {
|
|
|
36
36
|
label: ReactNode;
|
|
37
37
|
onAct: () => void;
|
|
38
38
|
closeView: () => void;
|
|
39
|
+
isBlocked?: boolean;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
const EditAction = ({ modelName, label, onAct, closeView }: ActionProps) => {
|
|
@@ -45,21 +46,30 @@ const EditAction = ({ modelName, label, onAct, closeView }: ActionProps) => {
|
|
|
45
46
|
.desc(`Turn the open ${modelName} from its detail view into the edit form.`)
|
|
46
47
|
.exec(onAct);
|
|
47
48
|
return (
|
|
48
|
-
<button
|
|
49
|
+
<button
|
|
50
|
+
type="button"
|
|
51
|
+
className={buttonRecipe({ variant: "primary" }, "w-full")}
|
|
52
|
+
onClick={editModel}
|
|
53
|
+
{...agentAttrs(editModel)}
|
|
54
|
+
>
|
|
49
55
|
<AiOutlineEdit /> {label}
|
|
50
56
|
</button>
|
|
51
57
|
);
|
|
52
58
|
};
|
|
53
59
|
|
|
54
|
-
const SaveAction = ({ modelName, label, onAct, closeView }: ActionProps) => {
|
|
60
|
+
const SaveAction = ({ modelName, label, onAct, closeView, isBlocked = false }: ActionProps) => {
|
|
55
61
|
useCloseViewTool(modelName, closeView);
|
|
56
62
|
const submitModel = st
|
|
57
|
-
.tool(`submit${capitalize(modelName)}
|
|
63
|
+
.tool(`submit${capitalize(modelName)}`, {
|
|
64
|
+
guard: () => (isBlocked ? `The ${modelName} form is not ready to submit.` : true),
|
|
65
|
+
})
|
|
58
66
|
.desc(`Save the ${modelName} the open form holds.`)
|
|
59
67
|
.exec(onAct);
|
|
60
68
|
return (
|
|
61
69
|
<button
|
|
70
|
+
type="button"
|
|
62
71
|
className={buttonRecipe({ variant: "primary" }, "w-full")}
|
|
72
|
+
disabled={isBlocked}
|
|
63
73
|
onClick={submitModel}
|
|
64
74
|
{...agentAttrs(submitModel)}
|
|
65
75
|
>
|
|
@@ -94,7 +104,7 @@ export default function ViewEditModal({
|
|
|
94
104
|
saveLabel,
|
|
95
105
|
}: ViewEditModalProps) {
|
|
96
106
|
const { l } = usePage();
|
|
97
|
-
const storeUse = st.use as unknown as { [key: string]: () => unknown };
|
|
107
|
+
const storeUse = st.use as unknown as { [key: string]: (option?: { agent?: boolean }) => unknown };
|
|
98
108
|
const storeDo = st.do as unknown as { [key: string]: (...args: any[]) => void };
|
|
99
109
|
const storeSel = st.sel as unknown as <Ret, Val>(selector: (state: { [key: string]: Val }) => Ret) => Ret;
|
|
100
110
|
const { refName, sliceName } = slice;
|
|
@@ -116,11 +126,12 @@ export default function ViewEditModal({
|
|
|
116
126
|
const modelLoading = storeUse[names.modelLoading]() as string | boolean;
|
|
117
127
|
const modelFormLoading = storeUse[names.modelFormLoading]() as string | boolean;
|
|
118
128
|
const modelFormId = storeSel<string, { id: string }>((state) => state[names.modelForm].id);
|
|
129
|
+
const isUploading = Object.keys(storeUse[`${modelName}FormUploading`]({ agent: false }) as object).length > 0;
|
|
119
130
|
const canUpdate = !!servedEndpointOf(fetch, `update${ModelName}`);
|
|
120
131
|
const canRemove = !!servedEndpointOf(fetch, `remove${ModelName}`);
|
|
121
132
|
const isModalOpen = modelModal === "view" || (modelModal === "edit" && (!!modelFormLoading || !!modelFormId));
|
|
122
133
|
const Title = () => {
|
|
123
|
-
if (!model || modelLoading || !renderTitle) return
|
|
134
|
+
if (!model || modelLoading || !renderTitle) return null;
|
|
124
135
|
const render = renderTitle(model);
|
|
125
136
|
if (typeof render === "string")
|
|
126
137
|
return <h2 className="flex items-center text-sm md:text-base lg:text-lg xl:text-2xl">{render}</h2>;
|
|
@@ -182,6 +193,7 @@ export default function ViewEditModal({
|
|
|
182
193
|
modelName={modelName}
|
|
183
194
|
label={saveLabel ?? l("base.save")}
|
|
184
195
|
closeView={closeView}
|
|
196
|
+
isBlocked={isUploading}
|
|
185
197
|
onAct={() => {
|
|
186
198
|
storeDo[names.submitModel]({ sliceName, modal: "view" });
|
|
187
199
|
}}
|
package/ui/Model/ViewModal.tsx
CHANGED
|
@@ -59,13 +59,13 @@ export default function ViewModal({
|
|
|
59
59
|
const modelLoading = storeUse[names.modelLoading]() as string | boolean;
|
|
60
60
|
const isModalOpen = modelModal === (modal ?? "view") && (modelLoading === id || model?.id === id);
|
|
61
61
|
const Title = () => {
|
|
62
|
-
if (!model || modelLoading || !renderTitle) return
|
|
62
|
+
if (!model || modelLoading || !renderTitle) return null;
|
|
63
63
|
const render = renderTitle(model);
|
|
64
64
|
if (typeof render === "string") return <h2 className="flex items-center text-2xl">{render}</h2>;
|
|
65
65
|
else return render;
|
|
66
66
|
};
|
|
67
67
|
const Action = () => {
|
|
68
|
-
if (!model || modelLoading || !renderAction) return
|
|
68
|
+
if (!model || modelLoading || !renderAction) return null;
|
|
69
69
|
const render = renderAction(model);
|
|
70
70
|
return render;
|
|
71
71
|
};
|
package/ui/ObjectId.tsx
CHANGED
|
@@ -26,7 +26,11 @@ export const ObjectId = ({ id }: ObjectIdProps) => {
|
|
|
26
26
|
<Tooltip content={id} variant="primary">
|
|
27
27
|
<div className="font-semibold text-xs">{shortenedId}</div>
|
|
28
28
|
</Tooltip>
|
|
29
|
-
<button
|
|
29
|
+
<button
|
|
30
|
+
type="button"
|
|
31
|
+
className={recipe({ variant: "ghost", size: "icon" }, "size-6 rounded-full")}
|
|
32
|
+
onClick={handleCopyClick}
|
|
33
|
+
>
|
|
30
34
|
{isCopied ? <AiOutlineCheck /> : <AiOutlineCopy />}
|
|
31
35
|
</button>
|
|
32
36
|
</div>
|
package/ui/Pagination.tsx
CHANGED
|
@@ -62,7 +62,7 @@ export const DefaultPagination = ({
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const emptyNode = empty ?? renderEmpty;
|
|
65
|
-
if (total <= 0) return emptyNode
|
|
65
|
+
if (total <= 0) return emptyNode || null;
|
|
66
66
|
return (
|
|
67
67
|
<div className={cn("flex items-center justify-center gap-1", classNames?.className)}>
|
|
68
68
|
<button
|
package/ui/Signal/Arg.tsx
CHANGED
|
@@ -37,9 +37,7 @@ export default function Arg({ argType, value, onChange }: ArgProps) {
|
|
|
37
37
|
<Arg.Json value={value as string} onChange={onChange} />
|
|
38
38
|
) : argType === "Upload" ? (
|
|
39
39
|
<Arg.Upload value={value as FileList} onChange={onChange} />
|
|
40
|
-
) :
|
|
41
|
-
<></>
|
|
42
|
-
);
|
|
40
|
+
) : null;
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
interface ArgTableProps {
|
package/ui/Signal/Doc.tsx
CHANGED
|
@@ -74,7 +74,10 @@ export const DocSetting = ({ fetch = runtimeFetch, search, onSearch }: DocSettin
|
|
|
74
74
|
<Toolbar>
|
|
75
75
|
<ToolbarField label={l.trans(signalText.baseUrl)}>
|
|
76
76
|
<Copy text={fetch.origin}>
|
|
77
|
-
<button
|
|
77
|
+
<button
|
|
78
|
+
type="button"
|
|
79
|
+
className={buttonRecipe({ variant: "ghost", size: "sm" }, "font-mono text-foreground/80")}
|
|
80
|
+
>
|
|
78
81
|
{fetch.origin}
|
|
79
82
|
<AiOutlineCopy className="text-foreground/40" />
|
|
80
83
|
</button>
|
|
@@ -173,6 +176,7 @@ export const DocAuthModal = ({ children }: DocAuthModalProps) => {
|
|
|
173
176
|
title={l.trans(signalText.setJwtTitle)}
|
|
174
177
|
action={
|
|
175
178
|
<button
|
|
179
|
+
type="button"
|
|
176
180
|
className={buttonRecipe({ variant: "primary" }, "w-full")}
|
|
177
181
|
onClick={() => {
|
|
178
182
|
st.set(
|
package/ui/System/CSR.tsx
CHANGED
package/ui/System/Client.tsx
CHANGED
package/ui/System/Reconnect.tsx
CHANGED
|
@@ -29,7 +29,7 @@ export const Reconnect = () => {
|
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
31
|
await (fetch as unknown as { ping: () => Promise<string> }).ping();
|
|
32
|
-
} catch
|
|
32
|
+
} catch {
|
|
33
33
|
setConnectStatus((prev) => (prev === "normal" || prev === "initial" ? "disconnected" : prev));
|
|
34
34
|
setTimeout(() => {
|
|
35
35
|
setConnectStatus((prev) => (prev === "disconnected" ? "connecting" : prev));
|
package/ui/System/SSR.tsx
CHANGED
|
@@ -7,20 +7,10 @@ import {
|
|
|
7
7
|
type ReactFont,
|
|
8
8
|
router,
|
|
9
9
|
Translator,
|
|
10
|
-
transitionTypes,
|
|
11
10
|
usePage,
|
|
12
|
-
viewTransitionClassOf,
|
|
13
11
|
} from "akanjs/client";
|
|
14
12
|
import { getRequestFrameState, setRequestTheme } from "akanjs/fetch";
|
|
15
|
-
import {
|
|
16
|
-
Children,
|
|
17
|
-
type CSSProperties,
|
|
18
|
-
Fragment,
|
|
19
|
-
type ReactNode,
|
|
20
|
-
Suspense,
|
|
21
|
-
type ViewTransitionClassPerType,
|
|
22
|
-
} from "react";
|
|
23
|
-
import { ViewTransition } from "../../client/viewTransition";
|
|
13
|
+
import { Children, type CSSProperties, Fragment, type ReactNode, Suspense } from "react";
|
|
24
14
|
import { FontCss } from "../fontCss";
|
|
25
15
|
import { frameSlotContainerClassNames, frameSlotContentClassNames, frameSlotStyles } from "../Layout/frameSlot";
|
|
26
16
|
import { Load } from "../Load";
|
|
@@ -28,7 +18,7 @@ import { ClientBridge, ClientInner, ClientPathWrapper, ClientSsrBridge, ClientWr
|
|
|
28
18
|
import { getFrameCssVars, isResponsiveFrame, type ProviderProps } from "./Common";
|
|
29
19
|
|
|
30
20
|
export const SSR = () => {
|
|
31
|
-
return
|
|
21
|
+
return null;
|
|
32
22
|
};
|
|
33
23
|
|
|
34
24
|
export type SSRProviderProps = ProviderProps & {
|
|
@@ -124,18 +114,6 @@ const ServerFontFace = ({ fonts }: { fonts: ReactFont[] }) => {
|
|
|
124
114
|
);
|
|
125
115
|
};
|
|
126
116
|
|
|
127
|
-
const pageViewTransition: ViewTransitionClassPerType = Object.fromEntries([
|
|
128
|
-
["default", "none"],
|
|
129
|
-
...transitionTypes.flatMap((transition) =>
|
|
130
|
-
transition === "none"
|
|
131
|
-
? []
|
|
132
|
-
: (["push", "pop"] as const).map((direction) => {
|
|
133
|
-
const type = viewTransitionClassOf(transition, direction);
|
|
134
|
-
return [type, type];
|
|
135
|
-
}),
|
|
136
|
-
),
|
|
137
|
-
]);
|
|
138
|
-
|
|
139
117
|
interface SSRWrapperProps {
|
|
140
118
|
className?: string;
|
|
141
119
|
appName: string;
|
|
@@ -220,18 +198,7 @@ const SSRWrapper = ({
|
|
|
220
198
|
layoutStyle === "mobile" && "left-1/2 h-screen w-full max-w-[600px] -translate-x-1/2",
|
|
221
199
|
)}
|
|
222
200
|
>
|
|
223
|
-
{
|
|
224
|
-
<ViewTransition
|
|
225
|
-
default="none"
|
|
226
|
-
enter={pageViewTransition}
|
|
227
|
-
exit={pageViewTransition}
|
|
228
|
-
update={pageViewTransition}
|
|
229
|
-
>
|
|
230
|
-
{Children.toArray(children)}
|
|
231
|
-
</ViewTransition>
|
|
232
|
-
) : (
|
|
233
|
-
Children.toArray(children)
|
|
234
|
-
)}
|
|
201
|
+
{Children.toArray(children)}
|
|
235
202
|
</div>
|
|
236
203
|
</div>
|
|
237
204
|
</div>
|
package/ui/ToggleSelect.tsx
CHANGED
|
@@ -70,6 +70,7 @@ const DefaultToggleSelect = <I extends string | number | boolean | null>({
|
|
|
70
70
|
<Fragment key={idx}>{renderItem(option, { selected: isSelected, disabled: isDisabled, onToggle })}</Fragment>
|
|
71
71
|
) : (
|
|
72
72
|
<button
|
|
73
|
+
type="button"
|
|
73
74
|
key={idx}
|
|
74
75
|
disabled={isDisabled}
|
|
75
76
|
className={cn(toggleBtn, isSelected && selectedCls, isDisabled && "cursor-not-allowed", btnClassName)}
|
|
@@ -128,6 +129,7 @@ const DefaultMulti = ({
|
|
|
128
129
|
const isDisabled = (disabled ?? false) || (option.disabled ?? false);
|
|
129
130
|
return (
|
|
130
131
|
<button
|
|
132
|
+
type="button"
|
|
131
133
|
key={idx}
|
|
132
134
|
disabled={isDisabled}
|
|
133
135
|
className={cn(toggleBtn, isSelected && selectedCls, isDisabled && "cursor-not-allowed", btnClassName)}
|
package/ui/styles.css
CHANGED
|
@@ -140,6 +140,16 @@ body {
|
|
|
140
140
|
-webkit-user-select: none; */
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
/* An installed web app's document does not rubber-band; in a browser tab the page keeps the browser's own feel. */
|
|
144
|
+
@layer base {
|
|
145
|
+
@media (display-mode: standalone) {
|
|
146
|
+
html,
|
|
147
|
+
body {
|
|
148
|
+
overscroll-behavior-y: none;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
143
153
|
html.akan-mobile-document,
|
|
144
154
|
body.akan-mobile-document {
|
|
145
155
|
width: 100%;
|
|
@@ -323,109 +333,6 @@ body.akan-mobile-document {
|
|
|
323
333
|
}
|
|
324
334
|
}
|
|
325
335
|
|
|
326
|
-
/* Route transitions on the web: an RSC navigation tags itself `akan-<transition>-<push|pop>` from the route's
|
|
327
|
-
`.config({ transition })`, and the page content's ViewTransition takes that class. The rest of the page holds. */
|
|
328
|
-
:root:active-view-transition-type(akan-nav)::view-transition-old(root),
|
|
329
|
-
:root:active-view-transition-type(akan-nav)::view-transition-new(root) {
|
|
330
|
-
animation: none;
|
|
331
|
-
}
|
|
332
|
-
::view-transition-old(.akan-stack-push) {
|
|
333
|
-
animation: 260ms cubic-bezier(0.32, 0.72, 0, 1) both akan-vt-out-left;
|
|
334
|
-
}
|
|
335
|
-
::view-transition-new(.akan-stack-push) {
|
|
336
|
-
animation: 260ms cubic-bezier(0.32, 0.72, 0, 1) both akan-vt-in-right;
|
|
337
|
-
}
|
|
338
|
-
::view-transition-old(.akan-stack-pop) {
|
|
339
|
-
animation: 260ms cubic-bezier(0.32, 0.72, 0, 1) both akan-vt-out-right;
|
|
340
|
-
}
|
|
341
|
-
::view-transition-new(.akan-stack-pop) {
|
|
342
|
-
animation: 260ms cubic-bezier(0.32, 0.72, 0, 1) both akan-vt-in-left;
|
|
343
|
-
}
|
|
344
|
-
::view-transition-old(.akan-bottomUp-push),
|
|
345
|
-
::view-transition-new(.akan-bottomUp-pop) {
|
|
346
|
-
animation: none;
|
|
347
|
-
}
|
|
348
|
-
::view-transition-new(.akan-bottomUp-push) {
|
|
349
|
-
animation: 280ms cubic-bezier(0.32, 0.72, 0, 1) both akan-vt-in-up;
|
|
350
|
-
}
|
|
351
|
-
::view-transition-old(.akan-bottomUp-pop) {
|
|
352
|
-
animation: 240ms ease-in both akan-vt-out-down;
|
|
353
|
-
}
|
|
354
|
-
::view-transition-old(.akan-fade-push),
|
|
355
|
-
::view-transition-old(.akan-fade-pop) {
|
|
356
|
-
animation: 180ms ease-in both akan-vt-fade-out;
|
|
357
|
-
}
|
|
358
|
-
::view-transition-new(.akan-fade-push),
|
|
359
|
-
::view-transition-new(.akan-fade-pop) {
|
|
360
|
-
animation: 180ms ease-out both akan-vt-fade-in;
|
|
361
|
-
}
|
|
362
|
-
::view-transition-old(.akan-scaleOut-push) {
|
|
363
|
-
animation: 220ms ease-in both akan-vt-shrink-out;
|
|
364
|
-
}
|
|
365
|
-
::view-transition-new(.akan-scaleOut-push) {
|
|
366
|
-
animation: 220ms ease-out both akan-vt-fade-in;
|
|
367
|
-
}
|
|
368
|
-
::view-transition-old(.akan-scaleOut-pop) {
|
|
369
|
-
animation: 200ms ease-in both akan-vt-fade-out;
|
|
370
|
-
}
|
|
371
|
-
::view-transition-new(.akan-scaleOut-pop) {
|
|
372
|
-
animation: 220ms ease-out both akan-vt-grow-in;
|
|
373
|
-
}
|
|
374
|
-
@keyframes akan-vt-in-right {
|
|
375
|
-
from {
|
|
376
|
-
transform: translateX(100%);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
@keyframes akan-vt-out-left {
|
|
380
|
-
to {
|
|
381
|
-
transform: translateX(-30%);
|
|
382
|
-
opacity: 0.6;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
@keyframes akan-vt-in-left {
|
|
386
|
-
from {
|
|
387
|
-
transform: translateX(-30%);
|
|
388
|
-
opacity: 0.6;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
@keyframes akan-vt-out-right {
|
|
392
|
-
to {
|
|
393
|
-
transform: translateX(100%);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
@keyframes akan-vt-in-up {
|
|
397
|
-
from {
|
|
398
|
-
transform: translateY(100%);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
@keyframes akan-vt-out-down {
|
|
402
|
-
to {
|
|
403
|
-
transform: translateY(100%);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
@keyframes akan-vt-fade-in {
|
|
407
|
-
from {
|
|
408
|
-
opacity: 0;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
@keyframes akan-vt-fade-out {
|
|
412
|
-
to {
|
|
413
|
-
opacity: 0;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
@keyframes akan-vt-shrink-out {
|
|
417
|
-
to {
|
|
418
|
-
transform: scale(0.94);
|
|
419
|
-
opacity: 0;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
@keyframes akan-vt-grow-in {
|
|
423
|
-
from {
|
|
424
|
-
transform: scale(0.94);
|
|
425
|
-
opacity: 0;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
336
|
/* Always-included keyframes (non-theme animations) */
|
|
430
337
|
@keyframes smaller {
|
|
431
338
|
0% {
|
|
@@ -194,8 +194,9 @@ final class AkanNativeBridge: NSObject {
|
|
|
194
194
|
return AkanNativeLog.info("emit \(plugin).\(event): data is not JSON, dropped")
|
|
195
195
|
}
|
|
196
196
|
// Arguments go in as values, so no JS string escaping is involved.
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
// The ObjC method: below an iOS 18.4 target Swift's Result overlay links libswiftWebKit.dylib, absent on iOS 18.5.
|
|
198
|
+
webView.__callAsyncJavaScript("window.__AKAN_NATIVE__ && window.__AKAN_NATIVE__.receive(m)", arguments: ["m": text], inFrame: nil, in: .page) { _, error in
|
|
199
|
+
if let error { AkanNativeLog.info("emit \(plugin).\(event) failed: \(error)") }
|
|
199
200
|
}
|
|
200
201
|
}
|
|
201
202
|
|
|
@@ -61,7 +61,10 @@ export function addonReport(serverDir: string, os: AddonOs, arch: AddonArch): Ad
|
|
|
61
61
|
`${name} was compiled on this computer at install (binding.gyp, no prebuilt binary): check that it runs on a computer with nothing else installed`,
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
|
-
return {
|
|
64
|
+
return {
|
|
65
|
+
problems: problems.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)),
|
|
66
|
+
warnings: warnings.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)),
|
|
67
|
+
};
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
/** A path inside the server as the report names it: relative, `/`-separated on every OS. */
|
|
@@ -172,7 +172,7 @@ export function assembleApk({ base, dex, assetsDir, extra = [] }: ApkInput): Uin
|
|
|
172
172
|
for (const [i, bytes] of dex.entries())
|
|
173
173
|
entries.push(fileEntry(i === 0 ? "classes.dex" : `classes${i + 1}.dex`, bytes, true));
|
|
174
174
|
for (const e of extra) entries.push(fileEntry(e.name, e.bytes, false));
|
|
175
|
-
for (const file of walk(assetsDir).sort()) {
|
|
175
|
+
for (const file of walk(assetsDir).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0))) {
|
|
176
176
|
const rel = relative(assetsDir, file).split("\\").join("/");
|
|
177
177
|
const ext = rel.split(".").pop()!.toLowerCase();
|
|
178
178
|
entries.push(fileEntry(`assets/${rel}`, new Uint8Array(readFileSync(file)), STORE_EXT.has(ext)));
|
|
@@ -194,7 +194,7 @@ export function assembleBundleModule({ base, dex, assetsDir, extra = [] }: ApkIn
|
|
|
194
194
|
entries.push(fileEntry(`dex/${i === 0 ? "classes.dex" : `classes${i + 1}.dex`}`, bytes, false));
|
|
195
195
|
|
|
196
196
|
for (const e of extra) entries.push(fileEntry(e.name.startsWith("lib/") ? e.name : `root/${e.name}`, e.bytes, false));
|
|
197
|
-
for (const file of walk(assetsDir).sort()) {
|
|
197
|
+
for (const file of walk(assetsDir).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0))) {
|
|
198
198
|
const rel = relative(assetsDir, file).split("\\").join("/");
|
|
199
199
|
const ext = rel.split(".").pop()!.toLowerCase();
|
|
200
200
|
entries.push(fileEntry(`assets/${rel}`, new Uint8Array(readFileSync(file)), STORE_EXT.has(ext)));
|
|
@@ -889,7 +889,7 @@ export function generateKotlin(model: GenModel, pkg: string): string {
|
|
|
889
889
|
} else out.push(` ${JSON.stringify(m.name)} -> ${kotlinName(m.name)}(${reply})`);
|
|
890
890
|
}
|
|
891
891
|
out.push(
|
|
892
|
-
|
|
892
|
+
` else -> call.reject(AkanNativeErrorCode.NOT_FOUND, "unknown method \${call.method}")`,
|
|
893
893
|
" }",
|
|
894
894
|
" }",
|
|
895
895
|
"}",
|
|
@@ -157,9 +157,10 @@ export function injectCspMeta(html: string, policy: string): string {
|
|
|
157
157
|
);
|
|
158
158
|
}
|
|
159
159
|
const tag = `<meta http-equiv="Content-Security-Policy" content="${policy.replace(/&/g, "&").replace(/"/g, """)}">`;
|
|
160
|
-
const head = /<head
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
const head = /<head[\s>]/i.exec(html);
|
|
161
|
+
const headEnd = head ? html.indexOf(">", head.index) : -1;
|
|
162
|
+
if (headEnd < 0) throw new CliError("index.html has no <head> for the Content-Security-Policy <meta>");
|
|
163
|
+
const afterHead = headEnd + 1;
|
|
163
164
|
const rest = html.slice(afterHead);
|
|
164
165
|
const charset = /<meta\b[^>]*\bcharset\s*=[^>]*>/i.exec(rest);
|
|
165
166
|
|
|
@@ -12,7 +12,13 @@ interface GoogleServices {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
const escape = (s: string) =>
|
|
15
|
-
s
|
|
15
|
+
s
|
|
16
|
+
.replace(/\\/g, "\\\\")
|
|
17
|
+
.replace(/&/g, "&")
|
|
18
|
+
.replace(/</g, "<")
|
|
19
|
+
.replace(/>/g, ">")
|
|
20
|
+
.replace(/'/g, "\\'")
|
|
21
|
+
.replace(/"/g, '\\"');
|
|
16
22
|
|
|
17
23
|
/** res/values/google_services.xml for `packageName` (and `fallbackPackage` when it has no client). */
|
|
18
24
|
export function googleServicesXml(json: string, packageName: string, fallbackPackage = packageName): string {
|
|
@@ -25,6 +25,9 @@ export function resolveDevEntry(project: Project): string {
|
|
|
25
25
|
);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
const scriptJson = (value: unknown) =>
|
|
29
|
+
JSON.stringify(value).replace(/[<>\u2028\u2029]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
30
|
+
|
|
28
31
|
/**
|
|
29
32
|
* Inline classic script in the dev page. It runs while the document is parsed, so before Bun's
|
|
30
33
|
* client (a module script, deferred).
|
|
@@ -47,17 +50,17 @@ export function devShim(socket?: { origin: string; path?: string; paths?: string
|
|
|
47
50
|
socket === undefined
|
|
48
51
|
? ""
|
|
49
52
|
: "var W=window.WebSocket,T=" +
|
|
50
|
-
|
|
53
|
+
scriptJson(socket.origin) +
|
|
51
54
|
",P=" +
|
|
52
|
-
|
|
55
|
+
scriptJson([socket.path ?? HMR_PATH, ...(socket.paths ?? [])]) +
|
|
53
56
|
";function S(u,p){try{var x=new URL(String(u),location.href);if(P.indexOf(x.pathname)>=0&&x.host===location.host)u=T+x.pathname+x.search}catch(e){}return p===undefined?new W(u):new W(u,p)}" +
|
|
54
57
|
"S.prototype=W.prototype;S.CONNECTING=0;S.OPEN=1;S.CLOSING=2;S.CLOSED=3;window.WebSocket=S;";
|
|
55
58
|
const gateway = socket?.origin.replace(/^ws/, "http");
|
|
56
|
-
const marker = gateway === undefined ? "" : `window.__AKAN_NATIVE_DEV__={gateway:${
|
|
59
|
+
const marker = gateway === undefined ? "" : `window.__AKAN_NATIVE_DEV__={gateway:${scriptJson(gateway)}};`;
|
|
57
60
|
const bodies = !socket?.relayBodies
|
|
58
61
|
? ""
|
|
59
62
|
: "var G=" +
|
|
60
|
-
|
|
63
|
+
scriptJson(gateway) +
|
|
61
64
|
';function R(u,m){try{var x=new URL(String(u),location.href);m=String(m||"GET").toUpperCase();' +
|
|
62
65
|
'if(x.origin===location.origin&&m!=="GET"&&m!=="HEAD"&&x.pathname.indexOf("/__akan_native/")!==0)return G+x.pathname+x.search}catch(e){}return null}' +
|
|
63
66
|
"var F=window.fetch;if(F)window.fetch=function(i,o){var q=window.Request&&i instanceof window.Request," +
|
|
@@ -387,7 +390,7 @@ export async function startHmrServer(opts: HmrOptions): Promise<HmrServer> {
|
|
|
387
390
|
for (const warning of warnings) warnOnce(warning);
|
|
388
391
|
return new Response(page, { headers: { ...noCache, "content-type": "text/html; charset=utf-8" } });
|
|
389
392
|
} catch (error) {
|
|
390
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
393
|
+
const message = `dev gateway: the page: ${error instanceof Error ? error.message : String(error)}`;
|
|
391
394
|
warnOnce(message);
|
|
392
395
|
return new Response(message, { status: 500, headers: { "content-type": "text/plain; charset=utf-8" } });
|
|
393
396
|
}
|
|
@@ -42,9 +42,24 @@ export const EARLY_ERRORS_SCRIPT =
|
|
|
42
42
|
|
|
43
43
|
/** Puts the early error collector right after the init.js tag (dev builds). */
|
|
44
44
|
export function injectEarlyErrors(html: string): string {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
const opening = /<script\b/gi;
|
|
46
|
+
for (let m = opening.exec(html); m; m = opening.exec(html)) {
|
|
47
|
+
const tagEnd = html.indexOf(">", m.index);
|
|
48
|
+
if (tagEnd < 0) break;
|
|
49
|
+
let closeAt = tagEnd + 1;
|
|
50
|
+
while (closeAt < html.length && /\s/.test(html.charAt(closeAt))) closeAt += 1;
|
|
51
|
+
const closeEnd = closeAt + "</script>".length;
|
|
52
|
+
if (html.slice(closeAt, closeEnd).toLowerCase() === "</script>" && loadsInitScript(html.slice(m.index, tagEnd)))
|
|
53
|
+
return insertAt(html, closeEnd, `<script>${EARLY_ERRORS_SCRIPT}</script>`);
|
|
54
|
+
opening.lastIndex = tagEnd + 1;
|
|
55
|
+
}
|
|
56
|
+
return html;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function loadsInitScript(tag: string): boolean {
|
|
60
|
+
for (const src of tag.matchAll(/\bsrc\s*=\s*["']?([^"'\s>]*)/gi))
|
|
61
|
+
if (/__akan_native\/init\.js/i.test(src[1] ?? "")) return true;
|
|
62
|
+
return false;
|
|
48
63
|
}
|
|
49
64
|
|
|
50
65
|
function insertAt(text: string, index: number, insert: string): string {
|
|
@@ -28,7 +28,7 @@ const KEPT_APPLICATION_ATTRS = ["android:appComponentFactory"];
|
|
|
28
28
|
function clean(element: XmlElement, applicationId: string): XmlElement {
|
|
29
29
|
element.attrs = element.attrs
|
|
30
30
|
.filter(([n]) => !n.startsWith("tools:") && n !== "xmlns:tools")
|
|
31
|
-
.map(([n, v]) => [n, v.replaceAll(
|
|
31
|
+
.map(([n, v]) => [n, v.replaceAll(`\${applicationId}`, applicationId)]);
|
|
32
32
|
for (const c of element.children) clean(c, applicationId);
|
|
33
33
|
return element;
|
|
34
34
|
}
|
|
@@ -62,10 +62,8 @@ const unescape = (text: string) =>
|
|
|
62
62
|
*/
|
|
63
63
|
export function parsePlist(xml: string): PlistValue {
|
|
64
64
|
const tokens = [
|
|
65
|
-
...xml
|
|
66
|
-
|
|
67
|
-
.matchAll(/<(\/?)([a-zA-Z]+)[^>]*?(\/)?>|([^<]+)/g),
|
|
68
|
-
];
|
|
65
|
+
...xml.matchAll(/<\?xml[^>]*\?>|<!DOCTYPE[^>]*>|<!--[\s\S]*?-->|<(\/?)([a-zA-Z]+)[^>]*?(\/)?>|([^<]+)/g),
|
|
66
|
+
].filter((t) => t[2] !== undefined || t[4] !== undefined);
|
|
69
67
|
let i = 0;
|
|
70
68
|
const next = () => tokens[i++];
|
|
71
69
|
const text = (tag: string): string => {
|
|
@@ -256,7 +256,7 @@ async function withLock<T>(
|
|
|
256
256
|
if ((error as NodeJS.ErrnoException).code !== "EEXIST") throw error;
|
|
257
257
|
}
|
|
258
258
|
if (opts.ready()) return null;
|
|
259
|
-
let stale
|
|
259
|
+
let stale: boolean;
|
|
260
260
|
try {
|
|
261
261
|
const [pid, at] = readFileSync(lock, "utf8").trim().split(" ").map(Number);
|
|
262
262
|
const alive = (() => {
|
|
@@ -175,7 +175,7 @@ export function validateUpdates(raw: unknown, problems: string[]): UpdatesConfig
|
|
|
175
175
|
}
|
|
176
176
|
const r = raw as Record<string, unknown>;
|
|
177
177
|
|
|
178
|
-
if (typeof r.url !== "string" || !/^https?:\/\/[^/?#]
|
|
178
|
+
if (typeof r.url !== "string" || !/^https?:\/\/[^/?#][^?#]*$/.test(r.url))
|
|
179
179
|
problems.push("updates.url must be an http(s) URL without a query or fragment");
|
|
180
180
|
const publicKeys = updatePublicKeys(r, problems);
|
|
181
181
|
const revokedKeys = updateRevokedKeys(r.revokedKeys, problems);
|
|
@@ -187,13 +187,13 @@ export function validateUpdates(raw: unknown, problems: string[]): UpdatesConfig
|
|
|
187
187
|
for (const key of Object.keys(r))
|
|
188
188
|
if (!["url", "publicKey", "publicKeys", "revokedKeys", "channel", "readyTimeout", "report"].includes(key))
|
|
189
189
|
problems.push(`updates.${key} is not supported`);
|
|
190
|
-
if (publicKeys
|
|
190
|
+
if (publicKeys?.every((key) => revokedKeys.includes(keyIdOf(key))))
|
|
191
191
|
problems.push(
|
|
192
192
|
"updates.revokedKeys revokes every key of updates.publicKeys: a phone built from it would trust none (add one with `akan-native update keygen`)",
|
|
193
193
|
);
|
|
194
194
|
if (typeof r.url !== "string" || !publicKeys) return null;
|
|
195
195
|
return {
|
|
196
|
-
url: r.url
|
|
196
|
+
url: withoutTrailingSlashes(r.url),
|
|
197
197
|
publicKeys,
|
|
198
198
|
revokedKeys,
|
|
199
199
|
channel: (r.channel as string | undefined) ?? "production",
|
|
@@ -202,11 +202,17 @@ export function validateUpdates(raw: unknown, problems: string[]): UpdatesConfig
|
|
|
202
202
|
};
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
function withoutTrailingSlashes(url: string): string {
|
|
206
|
+
let end = url.length;
|
|
207
|
+
while (end > 0 && url[end - 1] === "/") end -= 1;
|
|
208
|
+
return url.slice(0, end);
|
|
209
|
+
}
|
|
210
|
+
|
|
205
211
|
/** `report: { url }`, posted to as it is: the address is the receiver's, a path of its own included. */
|
|
206
212
|
function updateReportUrl(raw: unknown, problems: string[]): string | null {
|
|
207
213
|
if (raw === undefined) return null;
|
|
208
214
|
const url = raw && typeof raw === "object" && !Array.isArray(raw) ? (raw as Record<string, unknown>).url : undefined;
|
|
209
|
-
if (typeof url !== "string" || !/^https?:\/\/[^/?#]
|
|
215
|
+
if (typeof url !== "string" || !/^https?:\/\/[^/?#][^#]*$/.test(url) || Object.keys(raw as object).length !== 1) {
|
|
210
216
|
problems.push("updates.report must be { url } with an http(s) URL");
|
|
211
217
|
return null;
|
|
212
218
|
}
|
|
@@ -27,12 +27,13 @@ export const escapeXml = (text: string) =>
|
|
|
27
27
|
|
|
28
28
|
/** Parses a document's root element. Text between elements is ignored (manifests have none that matters). */
|
|
29
29
|
export function parseXml(source: string): XmlElement {
|
|
30
|
-
const
|
|
31
|
-
|
|
30
|
+
const tag =
|
|
31
|
+
/<\?[\s\S]*?\?>|<!--[\s\S]*?-->|<!DOCTYPE[^>]*>|<(\/?)([\w:.-]+)((?:\s+[\w:.-]+\s*=\s*(?:"[^"]*"|'[^']*'))*)\s*(\/?)>/g;
|
|
32
32
|
const stack: XmlElement[] = [];
|
|
33
33
|
let root: XmlElement | null = null;
|
|
34
|
-
for (let m = tag.exec(
|
|
34
|
+
for (let m = tag.exec(source); m; m = tag.exec(source)) {
|
|
35
35
|
const [, closing, name, attrText, selfClosing] = m;
|
|
36
|
+
if (name === undefined) continue;
|
|
36
37
|
if (closing) {
|
|
37
38
|
const open = stack.pop();
|
|
38
39
|
if (!open || open.name !== name) throw new Error(`XML: </${name}> does not close <${open?.name ?? "nothing"}>`);
|