akanjs 3.0.0-alpha.6 → 3.0.0-alpha.60
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/CHANGELOG.md +103 -0
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/base/baseEnv.ts +7 -4
- package/base/primitiveRegistry.ts +14 -10
- package/base/symbols.ts +4 -0
- package/client/capacitor.ts +34 -0
- package/client/clientRuntime.ts +13 -0
- package/client/csrTypes.ts +4 -3
- package/client/index.ts +1 -0
- package/client/locale.ts +2 -2
- package/client/sharedContext.ts +31 -0
- package/client/translator.ts +2 -2
- package/client/types.ts +3 -3
- package/common/deepObjectify.ts +21 -7
- package/common/index.ts +16 -0
- package/common/mcpExposure.ts +99 -0
- package/common/pathGetLoose.ts +31 -0
- package/common/pathSet.ts +17 -5
- package/common/routeConvention.ts +52 -12
- package/constant/crystalize.ts +3 -1
- package/constant/fieldInfo.ts +43 -3
- package/constant/immerify.ts +1 -1
- package/constant/index.ts +2 -0
- package/constant/labelOf.ts +17 -0
- package/constant/mask.ts +67 -0
- package/constant/purify.ts +17 -11
- package/constant/textFieldPaths.ts +13 -7
- package/constant/types.ts +14 -12
- package/constant/via.ts +6 -2
- package/dictionary/DictionaryLookup.ts +30 -0
- package/dictionary/agent.dictionary.ts +31 -0
- package/dictionary/agentTurn.dictionary.ts +29 -0
- package/dictionary/base.dictionary.ts +63 -0
- package/dictionary/dictInfo.ts +11 -2
- package/dictionary/dictionary.ts +9 -3
- package/dictionary/index.ts +1 -0
- package/dictionary/trans.ts +2 -2
- package/document/documentQuery.ts +1 -0
- package/document/filterMeta.ts +77 -11
- package/document/index.ts +1 -0
- package/document/into.ts +2 -0
- package/document/noDocumentError.ts +12 -0
- package/fetch/agentTurn.ts +19 -0
- package/fetch/client/fetchClient.ts +113 -28
- package/fetch/client/httpClient.ts +15 -11
- package/fetch/client/wsClient.ts +29 -6
- package/fetch/fetchType/appliedReturn.type.ts +6 -0
- package/fetch/fetchType/endpointFetch.type.ts +11 -5
- package/fetch/index.ts +1 -0
- package/index.ts +1 -1
- package/local/apps/serverLifecycle/serverLifecycle-local.db +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local.db-shm +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local.db-wal +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-shm +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-wal +0 -0
- package/package.json +11 -13
- package/server/akanApp.ts +37 -7
- package/server/akanOption.ts +63 -8
- package/server/akanServer.ts +206 -18
- package/server/animatedImage.ts +83 -0
- package/server/devtools/signalSerializer.ts +2 -2
- package/server/devtools/types.ts +4 -4
- package/server/di/diLifecycle.ts +123 -13
- package/server/di/predefinedAdaptor.ts +6 -0
- package/server/di/utils.ts +40 -0
- package/server/imageOptimizer.ts +33 -46
- package/server/lifecycle/shutdownManager.ts +1 -1
- package/server/mcp/McpAuth.ts +177 -0
- package/server/mcp/McpDispatcher.ts +285 -0
- package/server/mcp/McpEventStream.ts +76 -0
- package/server/mcp/McpExecutionContext.ts +105 -0
- package/server/mcp/McpRouter.ts +595 -0
- package/server/mcp/index.ts +5 -0
- package/server/resolver/CascadeRunner.ts +1 -1
- package/server/resolver/database.resolver.ts +8 -4
- package/server/resolver/signal.resolver.ts +63 -18
- package/server/routeTreeBuilder.ts +12 -52
- package/server/routing/appWsData.ts +8 -1
- package/server/rscWorker.tsx +11 -15
- package/server/subRouteIndexDocument.tsx +61 -0
- package/server/systemPageDocument.tsx +3 -3
- package/server/systemPages.tsx +49 -16
- package/server/vendor/akanjs-fetch.ts +1 -0
- package/server/webRouter.ts +39 -7
- package/service/adapt.ts +4 -4
- package/service/agent.service.ts +81 -0
- package/service/base.service.ts +2 -1
- package/service/index.ts +1 -0
- package/service/injectInfo.ts +8 -3
- package/service/predefinedAdaptor/database.adaptor.ts +68 -37
- package/service/predefinedAdaptor/deepseekLlm.ts +271 -0
- package/service/predefinedAdaptor/index.ts +3 -0
- package/service/predefinedAdaptor/insightQuery.ts +183 -0
- package/service/predefinedAdaptor/llm.adaptor.ts +115 -0
- package/service/predefinedAdaptor/queue.adaptor.ts +5 -2
- package/service/predefinedAdaptor/role.adaptor.ts +2 -0
- package/service/predefinedAdaptor/schedule.adaptor.ts +12 -5
- package/service/predefinedAdaptor/solidPubsub.adaptor.ts +10 -6
- package/service/predefinedAdaptor/solidQueue.adaptor.ts +6 -2
- package/service/predefinedAdaptor/solidSqlite.ts +11 -9
- package/service/predefinedAdaptor/websocket.adaptor.ts +6 -1
- package/service/serve.ts +16 -9
- package/service/toolNames.ts +119 -0
- package/signal/agent/AgentCatalogue.ts +165 -0
- package/signal/agent/index.ts +1 -0
- package/signal/agent.signal.ts +38 -0
- package/signal/agentTurn.ts +8 -0
- package/signal/agentTurnStream.ts +60 -0
- package/signal/base.signal.ts +2 -1
- package/signal/endpointInfo.ts +38 -2
- package/signal/guard.ts +28 -1
- package/signal/guards.ts +49 -1
- package/signal/index.ts +6 -0
- package/signal/intercept.ts +4 -4
- package/signal/internalArg.ts +7 -2
- package/signal/mcp/McpDocument.ts +286 -0
- package/signal/mcp/McpProgress.ts +106 -0
- package/signal/mcp/McpUriTemplate.ts +85 -0
- package/signal/mcp/Msg.ts +368 -0
- package/signal/mcp/index.ts +5 -0
- package/signal/mcp/mcpProtocol.ts +120 -0
- package/signal/middleware.ts +3 -3
- package/signal/openapi/openapi.ts +35 -173
- package/signal/schema/JsonSchemaBuilder.ts +219 -0
- package/signal/schema/index.ts +1 -0
- package/signal/serializer/fetch.serializer.ts +37 -0
- package/signal/signalContext.ts +63 -24
- package/signal/slice.ts +30 -26
- package/signal/types.ts +14 -1
- package/store/action.ts +16 -22
- package/store/actionTag.ts +33 -0
- package/store/agent/AgentBridge.ts +87 -0
- package/store/agent/AgentContext.ts +71 -0
- package/store/agent/AgentPrompts.ts +111 -0
- package/store/agent/ScreenReader.ts +349 -0
- package/store/agent/ScreenSettle.ts +45 -0
- package/store/agent/ScreenTarget.ts +135 -0
- package/store/agent/StoreCatalogue.ts +116 -0
- package/store/agent/StoreSurfaceSource.ts +225 -0
- package/store/agent/index.ts +13 -0
- package/store/agent/storeSurface.ts +28 -0
- package/store/agent/types.ts +16 -0
- package/store/agentic/AgentValue.ts +119 -0
- package/store/agentic/StExposeBuilder.ts +47 -0
- package/store/agentic/StExposeDraft.ts +24 -0
- package/store/agentic/StStateBuilder.ts +85 -0
- package/store/agentic/StStateDraft.ts +23 -0
- package/store/agentic/StToolBuilder.ts +279 -0
- package/store/agentic/StToolDraft.ts +22 -0
- package/store/agentic/attachAgentic.ts +33 -0
- package/store/agentic/formFields.ts +194 -0
- package/store/agentic/index.ts +12 -0
- package/store/agentic/useFieldTool.ts +183 -0
- package/store/agentic/useFormTools.ts +77 -0
- package/store/agentic/useRelationFieldTool.ts +113 -0
- package/store/baseSt.ts +1 -1
- package/store/databaseStateNames.ts +31 -0
- package/store/formSetterNames.ts +35 -0
- package/store/index.ts +8 -0
- package/store/rootStore.ts +3 -1
- package/store/sliceRole.ts +36 -0
- package/store/state.ts +2 -12
- package/store/store.ts +9 -0
- package/store/storeInstance.ts +185 -20
- package/store/storeRegistry.ts +39 -1
- package/store/types.ts +12 -0
- package/store/withSelector.ts +7 -8
- package/test/index.ts +1 -1
- package/test/registerDom.ts +4 -0
- package/test/signalTestRuntime.ts +5 -5
- package/test/testServer.ts +8 -5
- package/types/base/baseEnv.d.ts +1 -1
- package/types/base/primitiveRegistry.d.ts +6 -6
- package/types/base/symbols.d.ts +4 -0
- package/types/client/capacitor.d.ts +39 -0
- package/types/client/clientRuntime.d.ts +7 -0
- package/types/client/index.d.ts +1 -0
- package/types/client/sharedContext.d.ts +21 -0
- package/types/client/types.d.ts +5 -3
- package/types/common/deepObjectify.d.ts +4 -2
- package/types/common/index.d.ts +3 -1
- package/types/common/mcpExposure.d.ts +60 -0
- package/types/common/pathGetLoose.d.ts +8 -0
- package/types/common/routeConvention.d.ts +14 -0
- package/types/constant/fieldInfo.d.ts +20 -3
- package/types/constant/index.d.ts +2 -0
- package/types/constant/labelOf.d.ts +6 -0
- package/types/constant/mask.d.ts +41 -0
- package/types/constant/purify.d.ts +2 -2
- package/types/constant/types.d.ts +2 -2
- package/types/dictionary/DictionaryLookup.d.ts +14 -0
- package/types/dictionary/agent.dictionary.d.ts +1 -0
- package/types/dictionary/agentTurn.dictionary.d.ts +1 -0
- package/types/dictionary/base.dictionary.d.ts +1 -1
- package/types/dictionary/dictInfo.d.ts +7 -1
- package/types/dictionary/dictionary.d.ts +11 -9
- package/types/dictionary/index.d.ts +1 -0
- package/types/document/filterMeta.d.ts +24 -3
- package/types/document/index.d.ts +1 -0
- package/types/document/into.d.ts +2 -0
- package/types/document/noDocumentError.d.ts +12 -0
- package/types/fetch/agentTurn.d.ts +593 -0
- package/types/fetch/client/fetchClient.d.ts +13 -0
- package/types/fetch/client/httpClient.d.ts +2 -1
- package/types/fetch/fetchType/appliedReturn.type.d.ts +5 -0
- package/types/fetch/fetchType/endpointFetch.type.d.ts +6 -4
- package/types/fetch/index.d.ts +1 -0
- package/types/index.d.ts +1 -1
- package/types/server/akanApp.d.ts +5 -0
- package/types/server/akanOption.d.ts +36 -6
- package/types/server/akanServer.d.ts +60 -7
- package/types/server/animatedImage.d.ts +7 -0
- package/types/server/devtools/types.d.ts +4 -4
- package/types/server/di/diLifecycle.d.ts +10 -2
- package/types/server/di/predefinedAdaptor.d.ts +4 -1
- package/types/server/di/utils.d.ts +16 -0
- package/types/server/mcp/McpAuth.d.ts +62 -0
- package/types/server/mcp/McpDispatcher.d.ts +61 -0
- package/types/server/mcp/McpEventStream.d.ts +18 -0
- package/types/server/mcp/McpExecutionContext.d.ts +44 -0
- package/types/server/mcp/McpRouter.d.ts +63 -0
- package/types/server/mcp/index.d.ts +5 -0
- package/types/server/mcp.d.ts +1 -0
- package/types/server/resolver/signal.resolver.d.ts +5 -3
- package/types/server/routing/appWsData.d.ts +7 -1
- package/types/server/subRouteIndexDocument.d.ts +8 -0
- package/types/server/systemPageDocument.d.ts +1 -0
- package/types/server/systemPages.d.ts +5 -0
- package/types/server/vendor/akanjs-fetch.d.ts +1 -0
- package/types/service/adapt.d.ts +2 -2
- package/types/service/agent.service.d.ts +32 -0
- package/types/service/base.service.d.ts +4 -0
- package/types/service/index.d.ts +1 -0
- package/types/service/injectInfo.d.ts +2 -2
- package/types/service/predefinedAdaptor/database.adaptor.d.ts +9 -3
- package/types/service/predefinedAdaptor/deepseekLlm.d.ts +76 -0
- package/types/service/predefinedAdaptor/index.d.ts +3 -0
- package/types/service/predefinedAdaptor/insightQuery.d.ts +50 -0
- package/types/service/predefinedAdaptor/llm.adaptor.d.ts +105 -0
- package/types/service/predefinedAdaptor/queue.adaptor.d.ts +3 -2
- package/types/service/predefinedAdaptor/role.adaptor.d.ts +2 -0
- package/types/service/predefinedAdaptor/schedule.adaptor.d.ts +10 -6
- package/types/service/predefinedAdaptor/solidQueue.adaptor.d.ts +6 -2
- package/types/service/predefinedAdaptor/solidSqlite.d.ts +2 -2
- package/types/service/serve.d.ts +3 -3
- package/types/service/toolNames.d.ts +35 -0
- package/types/signal/agent/AgentCatalogue.d.ts +100 -0
- package/types/signal/agent/index.d.ts +1 -0
- package/types/signal/agent.d.ts +1 -0
- package/types/signal/agent.signal.d.ts +24 -0
- package/types/signal/agentTurn.d.ts +9 -0
- package/types/signal/agentTurnStream.d.ts +24 -0
- package/types/signal/base.signal.d.ts +1 -1
- package/types/signal/endpointInfo.d.ts +21 -3
- package/types/signal/guard.d.ts +12 -0
- package/types/signal/guards.d.ts +23 -1
- package/types/signal/index.d.ts +6 -0
- package/types/signal/intercept.d.ts +2 -2
- package/types/signal/internalArg.d.ts +9 -2
- package/types/signal/mcp/McpDocument.d.ts +65 -0
- package/types/signal/mcp/McpProgress.d.ts +40 -0
- package/types/signal/mcp/McpUriTemplate.d.ts +26 -0
- package/types/signal/mcp/Msg.d.ts +143 -0
- package/types/signal/mcp/index.d.ts +5 -0
- package/types/signal/mcp/mcpProtocol.d.ts +107 -0
- package/types/signal/mcp.d.ts +1 -0
- package/types/signal/middleware.d.ts +7 -7
- package/types/signal/openapi/openapi.d.ts +3 -3
- package/types/signal/schema/JsonSchemaBuilder.d.ts +51 -0
- package/types/signal/schema/index.d.ts +1 -0
- package/types/signal/schema.d.ts +1 -0
- package/types/signal/signalContext.d.ts +18 -3
- package/types/signal/slice.d.ts +17 -15
- package/types/signal/types.d.ts +13 -1
- package/types/store/actionTag.d.ts +21 -0
- package/types/store/agent/AgentBridge.d.ts +37 -0
- package/types/store/agent/AgentContext.d.ts +16 -0
- package/types/store/agent/AgentPrompts.d.ts +31 -0
- package/types/store/agent/ScreenReader.d.ts +29 -0
- package/types/store/agent/ScreenSettle.d.ts +22 -0
- package/types/store/agent/ScreenTarget.d.ts +34 -0
- package/types/store/agent/StoreCatalogue.d.ts +26 -0
- package/types/store/agent/StoreSurfaceSource.d.ts +30 -0
- package/types/store/agent/index.d.ts +11 -0
- package/types/store/agent/storeSurface.d.ts +14 -0
- package/types/store/agent/types.d.ts +15 -0
- package/types/store/agent.d.ts +1 -0
- package/types/store/agentic/AgentValue.d.ts +43 -0
- package/types/store/agentic/StExposeBuilder.d.ts +21 -0
- package/types/store/agentic/StExposeDraft.d.ts +13 -0
- package/types/store/agentic/StStateBuilder.d.ts +21 -0
- package/types/store/agentic/StStateDraft.d.ts +12 -0
- package/types/store/agentic/StToolBuilder.d.ts +56 -0
- package/types/store/agentic/StToolDraft.d.ts +13 -0
- package/types/store/agentic/attachAgentic.d.ts +25 -0
- package/types/store/agentic/formFields.d.ts +53 -0
- package/types/store/agentic/index.d.ts +12 -0
- package/types/store/agentic/useFieldTool.d.ts +22 -0
- package/types/store/agentic/useFormTools.d.ts +19 -0
- package/types/store/agentic/useRelationFieldTool.d.ts +27 -0
- package/types/store/agentic.d.ts +1 -0
- package/types/store/baseSt.d.ts +34 -34
- package/types/store/databaseStateNames.d.ts +25 -0
- package/types/store/formSetterNames.d.ts +30 -0
- package/types/store/index.d.ts +7 -0
- package/types/store/rootStore.d.ts +5 -1
- package/types/store/sliceRole.d.ts +25 -0
- package/types/store/store.d.ts +5 -1
- package/types/store/storeInstance.d.ts +33 -1
- package/types/store/storeRegistry.d.ts +5 -0
- package/types/store/types.d.ts +8 -0
- package/types/store/withSelector.d.ts +7 -8
- package/types/test/index.d.ts +1 -1
- package/types/test/registerDom.d.ts +1 -0
- package/types/test/signalTestRuntime.d.ts +2 -3
- package/types/test/testServer.d.ts +6 -4
- package/types/ui/Agent/Approval.d.ts +8 -0
- package/types/ui/Agent/Attach.d.ts +16 -0
- package/types/ui/Agent/Bubble.d.ts +26 -0
- package/types/ui/Agent/Chat.d.ts +91 -0
- package/types/ui/Agent/ChatCommands.d.ts +34 -0
- package/types/ui/Agent/Composer.d.ts +23 -0
- package/types/ui/Agent/Context.d.ts +13 -0
- package/types/ui/Agent/Dock.d.ts +17 -0
- package/types/ui/Agent/Guide.d.ts +9 -0
- package/types/ui/Agent/History.d.ts +26 -0
- package/types/ui/Agent/Launcher.d.ts +16 -0
- package/types/ui/Agent/Markdown.d.ts +19 -0
- package/types/ui/Agent/Menu.d.ts +18 -0
- package/types/ui/Agent/Mic.d.ts +8 -0
- package/types/ui/Agent/Question.d.ts +14 -0
- package/types/ui/Agent/Section.d.ts +10 -0
- package/types/ui/Agent/Skip.d.ts +22 -0
- package/types/ui/Agent/StateKey.d.ts +16 -0
- package/types/ui/Agent/Tool.d.ts +15 -0
- package/types/ui/Agent/Transcript.d.ts +13 -0
- package/types/ui/Agent/Zone.d.ts +48 -0
- package/types/ui/Agent/agentSessionOf.d.ts +27 -0
- package/types/ui/Agent/attachment.d.ts +34 -0
- package/types/ui/Agent/fetchRunner.d.ts +12 -0
- package/types/ui/Agent/index.d.ts +19 -0
- package/types/ui/Agent/index_.d.ts +1 -0
- package/types/ui/Agent/markdownBlocks.d.ts +35 -0
- package/types/ui/Agent/markdownSpans.d.ts +2 -0
- package/types/ui/Agent/markdownTable.d.ts +16 -0
- package/types/ui/Agent/sessionHistory.d.ts +14 -0
- package/types/ui/Agent/sessionView.d.ts +15 -0
- package/types/ui/Agent/tokenCount.d.ts +6 -0
- package/types/ui/Agent/useChatAttachments.d.ts +24 -0
- package/types/ui/Agent/useChatVoice.d.ts +30 -0
- package/types/ui/Agent/useDraftRecall.d.ts +14 -0
- package/types/ui/Agent/useKeyboardInset.d.ts +8 -0
- package/types/ui/Agent/useSlashMenu.d.ts +24 -0
- package/types/ui/Agent/voice.d.ts +71 -0
- package/types/ui/Agent.d.ts +1 -0
- package/types/ui/Badge.d.ts +1 -1
- package/types/ui/Button.d.ts +1 -1
- package/types/ui/Constant/Graph.d.ts +10 -0
- package/types/ui/Constant/index.d.ts +2 -1
- package/types/ui/Constant/schemaGraph.d.ts +39 -0
- package/types/ui/CsrImage.d.ts +1 -1
- package/types/ui/Data/Dashboard.d.ts +6 -3
- package/types/ui/Data/Insight.d.ts +1 -1
- package/types/ui/Data/ListContainer.d.ts +10 -6
- package/types/ui/Data/QueryMaker.d.ts +3 -3
- package/types/ui/Data/dataExport.d.ts +5 -0
- package/types/ui/Data/dataText.d.ts +6 -0
- package/types/ui/Data/index.d.ts +1 -0
- package/types/ui/Dialog/LegacyModal.d.ts +13 -0
- package/types/ui/Dialog/Provider.d.ts +3 -1
- package/types/ui/Dialog/context.d.ts +9 -1
- package/types/ui/Dialog/index.d.ts +1 -0
- package/types/ui/DraggableList.d.ts +1 -1
- package/types/ui/Dropdown.d.ts +5 -1
- package/types/ui/Field.d.ts +13 -12
- package/types/ui/Image.d.ts +3 -3
- package/types/ui/Layout/BottomTab.d.ts +3 -2
- package/types/ui/LegacyModal.d.ts +24 -0
- package/types/ui/Loading/ProgressBar.d.ts +4 -0
- package/types/ui/Loading/Spin.d.ts +2 -1
- package/types/ui/Model/AdminPanel.d.ts +10 -3
- package/types/ui/Model/EditModal.d.ts +1 -1
- package/types/ui/Model/New.d.ts +3 -1
- package/types/ui/Model/NewWrapper.d.ts +2 -0
- package/types/ui/Model/NewWrapper_Client.d.ts +2 -1
- package/types/ui/Pagination.d.ts +2 -2
- package/types/ui/Radio.d.ts +1 -1
- package/types/ui/RecentTime.d.ts +18 -1
- package/types/ui/Reference/Collapse.d.ts +11 -0
- package/types/ui/Reference/Panel.d.ts +29 -0
- package/types/ui/Reference/Segmented.d.ts +17 -0
- package/types/ui/Reference/Summary.d.ts +13 -0
- package/types/ui/Reference/Toolbar.d.ts +21 -0
- package/types/ui/Reference/dictText.d.ts +6 -0
- package/types/ui/Reference/index.d.ts +7 -0
- package/types/ui/Reference/style.d.ts +20 -0
- package/types/ui/Reference.d.ts +1 -0
- package/types/ui/ScreenNavigator.d.ts +3 -1
- package/types/ui/Signal/Arg.d.ts +4 -3
- package/types/ui/Signal/Doc.d.ts +4 -6
- package/types/ui/Signal/Object.d.ts +2 -1
- package/types/ui/Signal/RestApi.d.ts +2 -1
- package/types/ui/Signal/WebSocket.d.ts +2 -1
- package/types/ui/Signal/endpointEntries.d.ts +20 -0
- package/types/ui/Signal/style.d.ts +9 -8
- package/types/ui/System/Messages.d.ts +1 -1
- package/types/ui/Tab/Provider.d.ts +3 -1
- package/types/ui/Tab/context.d.ts +4 -2
- package/types/ui/ToggleSelect.d.ts +1 -0
- package/types/ui/UiOverride/context.d.ts +18 -1
- package/types/ui/agentAttrs.d.ts +14 -0
- package/types/ui/index.d.ts +22 -1
- package/types/ui/overlayLayer.d.ts +13 -0
- package/types/ui/overlayPosition.d.ts +28 -0
- package/types/ui/recipe/badgeRecipe.d.ts +2 -2
- package/types/ui/recipe/buttonRecipe.d.ts +2 -2
- package/types/vendor/use-agentic/AgentAbort.d.ts +17 -0
- package/types/vendor/use-agentic/AgentProgress.d.ts +27 -0
- package/types/vendor/use-agentic/AgentProvider.d.ts +17 -0
- package/types/vendor/use-agentic/AgentScope.d.ts +9 -0
- package/types/vendor/use-agentic/AgentSession.d.ts +163 -0
- package/types/vendor/use-agentic/Agentic.d.ts +21 -0
- package/types/vendor/use-agentic/AgenticSurface.d.ts +58 -0
- package/types/vendor/use-agentic/Compaction.d.ts +48 -0
- package/types/vendor/use-agentic/ToolOutput.d.ts +21 -0
- package/types/vendor/use-agentic/Transcript.d.ts +18 -0
- package/types/vendor/use-agentic/httpRunner.d.ts +15 -0
- package/types/vendor/use-agentic/index.d.ts +19 -0
- package/types/vendor/use-agentic/sharedContext.d.ts +15 -0
- package/types/vendor/use-agentic/surfaceContext.d.ts +5 -0
- package/types/vendor/use-agentic/types.d.ts +182 -0
- package/types/vendor/use-agentic/useAgent.d.ts +4 -0
- package/types/vendor/use-agentic/useAgentGuide.d.ts +6 -0
- package/types/vendor/use-agentic/useAgentResource.d.ts +12 -0
- package/types/vendor/use-agentic/useAgentState.d.ts +16 -0
- package/types/vendor/use-agentic/useAgentTool.d.ts +16 -0
- package/types/vendor/use-agentic.d.ts +1 -0
- package/types/webkit/index.d.ts +4 -0
- package/types/webkit/useBodyScrollLock.d.ts +2 -0
- package/types/webkit/usePageTool.d.ts +19 -0
- package/types/webkit/useScreenScope.d.ts +25 -0
- package/ui/Agent/Approval.tsx +32 -0
- package/ui/Agent/Attach.tsx +77 -0
- package/ui/Agent/Bubble.tsx +192 -0
- package/ui/Agent/Chat.tsx +525 -0
- package/ui/Agent/ChatCommands.ts +141 -0
- package/ui/Agent/Composer.tsx +94 -0
- package/ui/Agent/Context.tsx +47 -0
- package/ui/Agent/Dock.tsx +75 -0
- package/ui/Agent/Guide.tsx +16 -0
- package/ui/Agent/History.tsx +49 -0
- package/ui/Agent/Launcher.tsx +60 -0
- package/ui/Agent/Markdown.tsx +142 -0
- package/ui/Agent/Menu.tsx +55 -0
- package/ui/Agent/Mic.tsx +27 -0
- package/ui/Agent/Question.tsx +63 -0
- package/ui/Agent/Section.tsx +24 -0
- package/ui/Agent/Skip.tsx +30 -0
- package/ui/Agent/StateKey.tsx +46 -0
- package/ui/Agent/Tool.tsx +59 -0
- package/ui/Agent/Transcript.tsx +33 -0
- package/ui/Agent/Zone.tsx +116 -0
- package/ui/Agent/agentSessionOf.ts +60 -0
- package/ui/Agent/attachment.ts +73 -0
- package/ui/Agent/fetchRunner.ts +44 -0
- package/ui/Agent/index.ts +27 -0
- package/ui/Agent/index_.tsx +4 -0
- package/ui/Agent/markdownBlocks.ts +137 -0
- package/ui/Agent/markdownSpans.tsx +49 -0
- package/ui/Agent/markdownTable.ts +54 -0
- package/ui/Agent/sessionHistory.ts +62 -0
- package/ui/Agent/sessionView.ts +38 -0
- package/ui/Agent/tokenCount.ts +10 -0
- package/ui/Agent/useChatAttachments.ts +84 -0
- package/ui/Agent/useChatVoice.ts +129 -0
- package/ui/Agent/useDraftRecall.ts +42 -0
- package/ui/Agent/useKeyboardInset.ts +26 -0
- package/ui/Agent/useSlashMenu.ts +58 -0
- package/ui/Agent/voice.ts +177 -0
- package/ui/Badge.tsx +1 -1
- package/ui/BottomSheet.tsx +32 -36
- package/ui/Button.tsx +3 -1
- package/ui/Clipboard.tsx +3 -6
- package/ui/Constant/Doc.tsx +265 -254
- package/ui/Constant/Graph.tsx +151 -0
- package/ui/Constant/index.ts +3 -2
- package/ui/Constant/schemaGraph.ts +232 -0
- package/ui/CsrImage.tsx +1 -1
- package/ui/Data/CardList.tsx +14 -3
- package/ui/Data/Dashboard.tsx +35 -51
- package/ui/Data/Insight.tsx +18 -12
- package/ui/Data/Item.tsx +42 -56
- package/ui/Data/ListContainer.tsx +216 -129
- package/ui/Data/Pagination.tsx +10 -3
- package/ui/Data/QueryMaker.tsx +62 -12
- package/ui/Data/TableList.tsx +22 -13
- package/ui/Data/dataExport.ts +54 -0
- package/ui/Data/dataText.ts +22 -0
- package/ui/Data/index.ts +2 -1
- package/ui/DatePicker.tsx +1 -1
- package/ui/Dialog/Close.tsx +3 -7
- package/ui/Dialog/LegacyModal.tsx +241 -0
- package/ui/Dialog/Modal.tsx +62 -195
- package/ui/Dialog/Provider.tsx +47 -3
- package/ui/Dialog/Trigger.tsx +3 -7
- package/ui/Dialog/context.ts +14 -2
- package/ui/Dialog/index.tsx +2 -0
- package/ui/DragAction.tsx +3 -2
- package/ui/DraggableList.tsx +9 -4
- package/ui/Dropdown.tsx +89 -27
- package/ui/Empty.tsx +6 -4
- package/ui/Field.tsx +128 -58
- package/ui/Image.tsx +3 -3
- package/ui/Input.tsx +27 -5
- package/ui/KeyboardAvoiding.tsx +2 -2
- package/ui/Layout/BottomTab.tsx +32 -37
- package/ui/Layout/Sider.tsx +37 -14
- package/ui/LegacyModal.tsx +53 -0
- package/ui/Link/CsrLink.tsx +1 -1
- package/ui/Load/Pagination.tsx +15 -8
- package/ui/Load/Units.tsx +27 -6
- package/ui/Load/View.tsx +10 -3
- package/ui/Loading/Area.tsx +7 -6
- package/ui/Loading/Button.tsx +7 -9
- package/ui/Loading/Input.tsx +7 -9
- package/ui/Loading/ProgressBar.tsx +16 -7
- package/ui/Loading/Skeleton.tsx +8 -13
- package/ui/Loading/Spin.tsx +20 -14
- package/ui/Menu.tsx +1 -1
- package/ui/Model/AdminPanel.tsx +43 -12
- package/ui/Model/EditModal.tsx +27 -5
- package/ui/Model/EditWrapper.tsx +16 -4
- package/ui/Model/New.tsx +4 -0
- package/ui/Model/NewWrapper.tsx +2 -0
- package/ui/Model/NewWrapper_Client.tsx +20 -6
- package/ui/Model/Remove.tsx +18 -6
- package/ui/Model/RemoveWrapper.tsx +12 -2
- package/ui/Model/SureToRemove.tsx +18 -6
- package/ui/Model/ViewEditModal.tsx +64 -15
- package/ui/Model/ViewModal.tsx +25 -11
- package/ui/Model/ViewWrapper.tsx +15 -4
- package/ui/Model/index_.tsx +1 -1
- package/ui/Pagination.tsx +51 -66
- package/ui/Popconfirm.tsx +88 -78
- package/ui/Radio.tsx +53 -24
- package/ui/RecentTime.tsx +83 -35
- package/ui/Reference/Collapse.tsx +26 -0
- package/ui/Reference/Panel.tsx +79 -0
- package/ui/Reference/Segmented.tsx +41 -0
- package/ui/Reference/Summary.tsx +25 -0
- package/ui/Reference/Toolbar.tsx +44 -0
- package/ui/Reference/dictText.ts +9 -0
- package/ui/Reference/index.ts +7 -0
- package/ui/Reference/style.ts +45 -0
- package/ui/ScreenNavigator.tsx +17 -2
- package/ui/Select.tsx +96 -57
- package/ui/Signal/Arg.tsx +70 -59
- package/ui/Signal/Doc.tsx +163 -129
- package/ui/Signal/Listener.tsx +24 -28
- package/ui/Signal/Message.tsx +87 -135
- package/ui/Signal/Object.tsx +79 -57
- package/ui/Signal/PubSub.tsx +72 -113
- package/ui/Signal/Request.tsx +2 -22
- package/ui/Signal/Response.tsx +19 -45
- package/ui/Signal/RestApi.tsx +170 -200
- package/ui/Signal/WebSocket.tsx +29 -26
- package/ui/Signal/endpointEntries.ts +59 -0
- package/ui/Signal/makeExample.ts +10 -3
- package/ui/Signal/style.ts +34 -29
- package/ui/Switch.tsx +4 -0
- package/ui/System/CSR.tsx +1 -1
- package/ui/System/Client.tsx +24 -12
- package/ui/System/DevModeToggle.tsx +1 -1
- package/ui/System/Gtag.tsx +2 -2
- package/ui/System/Messages.tsx +52 -31
- package/ui/System/Reconnect.tsx +22 -56
- package/ui/System/SelectLanguage.tsx +24 -15
- package/ui/System/ThemeToggle.tsx +25 -13
- package/ui/Tab/Menu.tsx +24 -12
- package/ui/Tab/Menus.tsx +6 -3
- package/ui/Tab/Provider.tsx +30 -3
- package/ui/Tab/context.ts +8 -4
- package/ui/Table.tsx +66 -60
- package/ui/ToggleSelect.tsx +8 -7
- package/ui/Tooltip.tsx +15 -1
- package/ui/UiOverride/context.ts +21 -2
- package/ui/Unauthorized.tsx +6 -4
- package/ui/agentAttrs.ts +19 -0
- package/ui/index.ts +49 -1
- package/ui/overlayLayer.ts +12 -2
- package/ui/overlayPosition.ts +104 -0
- package/ui/recipe/buttonRecipe.ts +2 -2
- package/ui/styles.css +27 -0
- package/vendor/use-agentic/AgentAbort.ts +29 -0
- package/vendor/use-agentic/AgentProgress.ts +40 -0
- package/vendor/use-agentic/AgentProvider.tsx +39 -0
- package/vendor/use-agentic/AgentScope.tsx +20 -0
- package/vendor/use-agentic/AgentSession.ts +750 -0
- package/vendor/use-agentic/Agentic.tsx +44 -0
- package/vendor/use-agentic/AgenticSurface.ts +333 -0
- package/vendor/use-agentic/Compaction.ts +120 -0
- package/vendor/use-agentic/ToolOutput.ts +60 -0
- package/vendor/use-agentic/Transcript.ts +50 -0
- package/vendor/use-agentic/WIRE.md +86 -0
- package/vendor/use-agentic/httpRunner.ts +131 -0
- package/vendor/use-agentic/index.ts +20 -0
- package/vendor/use-agentic/sharedContext.ts +25 -0
- package/vendor/use-agentic/surfaceContext.ts +10 -0
- package/vendor/use-agentic/types.ts +192 -0
- package/vendor/use-agentic/useAgent.ts +18 -0
- package/vendor/use-agentic/useAgentGuide.ts +16 -0
- package/vendor/use-agentic/useAgentResource.ts +36 -0
- package/vendor/use-agentic/useAgentState.ts +64 -0
- package/vendor/use-agentic/useAgentTool.ts +55 -0
- package/webkit/bootCsr.tsx +12 -41
- package/webkit/index.ts +4 -0
- package/webkit/lazy.tsx +5 -1
- package/webkit/useBodyScrollLock.tsx +29 -0
- package/webkit/useFrameRuntime.ts +1 -1
- package/webkit/usePageTool.tsx +37 -0
- package/webkit/useScreenScope.tsx +60 -0
- package/types/ui/Constant/Mermaid.d.ts +0 -8
- package/types/ui/Signal/Collapse.d.ts +0 -12
- package/ui/Constant/Mermaid.tsx +0 -149
- package/ui/Signal/Collapse.tsx +0 -29
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,108 @@
|
|
|
1
1
|
# akanjs
|
|
2
2
|
|
|
3
|
+
## 2.4.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 11aa655: feat(constant): remove a relation's target with its owner via `cascade: "remove"`
|
|
8
|
+
|
|
9
|
+
A relation field can now take its target down with it: `image: field(File, { cascade: "remove" })`, arrays
|
|
10
|
+
included. The removal runs through the **target's service**, so the target's own `_postRemove` runs with it —
|
|
11
|
+
that is how removing a model also deletes the file's stored blob or object, with no extra wiring in the owning
|
|
12
|
+
module.
|
|
13
|
+
|
|
14
|
+
Only a relation accepts the option. A `String`, an `ID`, a scalar, and a nested array each fail while the class
|
|
15
|
+
is being built, naming the field: none of them points at a document the framework could remove.
|
|
16
|
+
|
|
17
|
+
Target services resolve lazily, at removal time, so a cascade adds no boot-order edge between two services and a
|
|
18
|
+
cascade cycle cannot fail the boot. They resolve _before_ the parent is touched, so a model cascading into a
|
|
19
|
+
module the app never mounted fails with nothing half-removed.
|
|
20
|
+
|
|
21
|
+
Two limits worth knowing. Nothing checks whether another document still references the same target, so declaring
|
|
22
|
+
`cascade` asserts that the field owns its target exclusively. And query-level removal (`deleteManyByQuery` /
|
|
23
|
+
`updateManyByQuery`) stamps `removedAt` in one atomic update that fires no hooks and therefore no cascade —
|
|
24
|
+
remove documents one at a time when they cascade.
|
|
25
|
+
|
|
26
|
+
- 11aa655: feat(store): invalidate sibling slices on create and refetch them in `Load.Units`
|
|
27
|
+
|
|
28
|
+
A model with more than one parent is listed by more than one slice, and a create could only ever be spliced
|
|
29
|
+
into the slice it was issued from. Creating a `bizDoc` from `bizDocInOrg` left `bizDocListInProject` without
|
|
30
|
+
it, and an RSC navigation back to that page replayed a cached payload whose server-stamped
|
|
31
|
+
`bizDocInitAtInProject` still satisfied `Load.Units`' cache check — so the new document stayed invisible until
|
|
32
|
+
a full reload.
|
|
33
|
+
|
|
34
|
+
`create<Model>` and `create<Model>InForm` now stamp a new per-slice `<model>StaleAt<Suffix>` on every slice
|
|
35
|
+
_except_ the one named by `sliceName`. Whether the new document belongs to a sibling slice is a server-side
|
|
36
|
+
filter decision, so the siblings are marked for revalidation rather than patched optimistically. `Load.Units`
|
|
37
|
+
refetches through `refresh<Model><Suffix>` when its slice's `StaleAt` is newer than its `InitAt`, and a
|
|
38
|
+
completed refresh restamps `InitAt` past `StaleAt` to end the stale state. The refetch is skipped while the
|
|
39
|
+
list is already loading, which also dedups several `Load.Units` mounted on one slice.
|
|
40
|
+
|
|
41
|
+
`Load.Units` also takes a `staleTime` prop, in milliseconds, for age-based revalidation independent of any
|
|
42
|
+
create: `staleTime={0}` always refetches on mount, `staleTime={30_000}` refetches only when the cached data is
|
|
43
|
+
older than 30s. Omitting it leaves the component purely invalidation-driven.
|
|
44
|
+
|
|
45
|
+
Update and remove are unchanged — they already walk every slice, because a document they touch is one the
|
|
46
|
+
cached lists can be searched for by id.
|
|
47
|
+
|
|
48
|
+
- 11aa655: feat(server): add subRoute hosts at runtime with `AKAN_SUB_ROUTE_HOSTS`
|
|
49
|
+
|
|
50
|
+
An app resolved a request Host to a basePath through a map fixed at build time — the domains written into
|
|
51
|
+
`akan.config.ts` plus the generated `<basePath>-<branch>.<serveDomain>`. A platform that mints its hostnames when
|
|
52
|
+
a project is created cannot write either one into the repo, so its subRoute hosts fell through to the root app.
|
|
53
|
+
|
|
54
|
+
`AKAN_SUB_ROUTE_HOSTS` adds to that map at boot, in the same spirit as `AKAN_PUBLIC_BASE_PATHS`:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
AKAN_SUB_ROUTE_HOSTS="soft=soft-abc.try.akanjs.com,soft.acme.com;office=office-abc.try.akanjs.com"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Hosts are matched lowercased and without a port, exactly as the built-in ones are. The env mapping is a union with
|
|
61
|
+
the built one, never a replacement, so a tenant's own domains keep working and removing the env restores the
|
|
62
|
+
previous behaviour byte for byte.
|
|
63
|
+
|
|
64
|
+
A basePath the build does not serve is dropped with a warning rather than honoured — the route tree is a build
|
|
65
|
+
output, so accepting one would answer every request under it with a 404 and nothing to explain why. A malformed
|
|
66
|
+
entry is skipped the same way: the value is rendered by a deployment platform, and one bad character must not turn
|
|
67
|
+
into a boot loop across every pod.
|
|
68
|
+
|
|
69
|
+
`x-base-path` is now checked against the basePaths the build serves before it is trusted, matching the check
|
|
70
|
+
`getBasePathFromPathname` already applied to it. An unrecognised value falls through to host matching instead of
|
|
71
|
+
selecting a basePath that resolves to nothing.
|
|
72
|
+
|
|
73
|
+
- 25d5b15: feat(devkit): sync lib `page` trees into apps and honor `pageConfig.devOnly`
|
|
74
|
+
|
|
75
|
+
Apps can opt in with `syncPageLibs` (`true` / lib list) so `akan sync` links each lib's routes under
|
|
76
|
+
`page/(libs)/(<lib>)` — once per basePath when the app has subRoutes. The link is generated and
|
|
77
|
+
gitignored; the lib source stays the edit target. Collision on the resolved route pattern is a
|
|
78
|
+
sync-time error.
|
|
79
|
+
|
|
80
|
+
`pageConfig.devOnly: true` (literal only) keeps a route out of `akan build` while `akan start` still
|
|
81
|
+
serves it. On a `_layout` it excludes the whole subtree. Symlink-aware file ops avoid wiping a synced
|
|
82
|
+
lib when cleaning an app link, and dangling lib links no longer break `getApps`.
|
|
83
|
+
|
|
84
|
+
- 25d5b15: feat(signal): refresh websocket credentials in-session and re-check pubsub rooms
|
|
85
|
+
|
|
86
|
+
Handshake credentials now live on `AppWsData` (headers/cookies only). Clients that hold the token in
|
|
87
|
+
memory send it with `fetch.setJwt(...)`, which forwards an `__auth` frame; the server swaps the
|
|
88
|
+
snapshot synchronously and re-runs each subscribed room's guards, unsubscribing the ones that fail.
|
|
89
|
+
|
|
90
|
+
Guards should read the caller with `context.get("account")` instead of branching on HTTP vs websocket
|
|
91
|
+
transport. Slice-level guards still only wrap generated query/mutation endpoints — a pubsub endpoint
|
|
92
|
+
needs its own `guards` if the room itself must be protected.
|
|
93
|
+
|
|
94
|
+
### Patch Changes
|
|
95
|
+
|
|
96
|
+
- 6d58c7e: add search feature for sqlit database with fts5
|
|
97
|
+
- 25d5b15: fix(ui): refresh EditModal when the hydrated edit payload is stale
|
|
98
|
+
|
|
99
|
+
RSC navigation can replay a cached page tree, and an edit shell hydrated from that payload can show
|
|
100
|
+
arbitrarily old form data. EditModal now treats a cache replay (or a `modelViewAt` older than 60s) as
|
|
101
|
+
stale and refetches via `edit<Model>` while keeping the modal open on the last known id.
|
|
102
|
+
|
|
103
|
+
- 42cf7a2: Normalize unsendable relayed WebSocket close codes to 1001 so Bun's global client WebSocket.close no longer throws InvalidAccessError at the gateway's client-to-upstream relay when a peer disappears without a close frame (code 1006). The upstream-to-client relay applies the same normalization defensively.
|
|
104
|
+
- 04cb46d: Allow the documented wsConnect export during source validation for root layouts, including base-path and grouped root boundaries, while continuing to reject it on nested layouts.
|
|
105
|
+
|
|
3
106
|
## 2.4.1
|
|
4
107
|
|
|
5
108
|
### Patch Changes
|
package/README.ko.md
CHANGED
package/README.md
CHANGED
package/base/baseEnv.ts
CHANGED
|
@@ -15,7 +15,7 @@ export interface BaseEnv {
|
|
|
15
15
|
operationMode: "local" | "edge" | "cloud" | "module";
|
|
16
16
|
databaseMode?: DatabaseMode;
|
|
17
17
|
}
|
|
18
|
-
export type BackendEnv =
|
|
18
|
+
export type BackendEnv = {
|
|
19
19
|
hostname?: string | null;
|
|
20
20
|
port?: number;
|
|
21
21
|
database?: {
|
|
@@ -73,15 +73,18 @@ export type ClientEnv = BaseEnv & {
|
|
|
73
73
|
|
|
74
74
|
let cachedEnv: ClientEnv | undefined;
|
|
75
75
|
|
|
76
|
+
const missingPublicEnv = (key: string) =>
|
|
77
|
+
`getEnv() cannot run at build time: akan build does not inject ${key}. Call it from a runtime function instead of at module scope (e.g. env(() => getEnv()) in adapt(), a method body, or a default thunk).`;
|
|
78
|
+
|
|
76
79
|
/** Reads and caches Akan runtime environment values from process/browser environment settings. */
|
|
77
80
|
export const getEnv = (): ClientEnv => {
|
|
78
81
|
if (cachedEnv) return cachedEnv;
|
|
79
82
|
const appName = process.env.AKAN_PUBLIC_APP_NAME ?? "unknown";
|
|
80
83
|
const repoName = process.env.AKAN_PUBLIC_REPO_NAME ?? "unknown";
|
|
81
84
|
const serveDomain = process.env.AKAN_PUBLIC_SERVE_DOMAIN ?? "unknown";
|
|
82
|
-
if (appName === "unknown") throw new Error("
|
|
83
|
-
if (repoName === "unknown") throw new Error("
|
|
84
|
-
if (serveDomain === "unknown") throw new Error("
|
|
85
|
+
if (appName === "unknown") throw new Error(missingPublicEnv("AKAN_PUBLIC_APP_NAME"));
|
|
86
|
+
if (repoName === "unknown") throw new Error(missingPublicEnv("AKAN_PUBLIC_REPO_NAME"));
|
|
87
|
+
if (serveDomain === "unknown") throw new Error(missingPublicEnv("AKAN_PUBLIC_SERVE_DOMAIN"));
|
|
85
88
|
const environment = (process.env.AKAN_PUBLIC_ENV ?? "debug") as BaseEnv["environment"];
|
|
86
89
|
const operationMode = (process.env.AKAN_PUBLIC_OPERATION_MODE ??
|
|
87
90
|
(environment === "local" ? "local" : "cloud")) as BaseEnv["operationMode"];
|
|
@@ -209,12 +209,12 @@ declare global {
|
|
|
209
209
|
[DEFAULT_VALUE]: boolean;
|
|
210
210
|
[PURIFIED_VALUE]: boolean;
|
|
211
211
|
[EXAMPLE_VALUE]: boolean;
|
|
212
|
-
validate(value: boolean | number): boolean;
|
|
213
|
-
parseValue(input: boolean | number): boolean | number;
|
|
214
|
-
serializeValue(value: boolean | number): boolean | number;
|
|
215
|
-
_parse(input: boolean | number): boolean;
|
|
216
|
-
_serialize(value: boolean | number): boolean;
|
|
217
|
-
_checkValue(value: boolean | number): void;
|
|
212
|
+
validate(value: boolean | number | string): boolean;
|
|
213
|
+
parseValue(input: boolean | number | string): boolean | number | string;
|
|
214
|
+
serializeValue(value: boolean | number | string): boolean | number | string;
|
|
215
|
+
_parse(input: boolean | number | string): boolean;
|
|
216
|
+
_serialize(value: boolean | number | string): boolean;
|
|
217
|
+
_checkValue(value: boolean | number | string): void;
|
|
218
218
|
}
|
|
219
219
|
interface DateConstructor {
|
|
220
220
|
refName: "Date";
|
|
@@ -305,10 +305,14 @@ Object.assign(String, scalarPrimitiveStatics, {
|
|
|
305
305
|
});
|
|
306
306
|
PrimitiveRegistry.register(String);
|
|
307
307
|
|
|
308
|
-
const normalizeBooleanPrimitiveValue = (value: boolean | number): boolean | null => {
|
|
308
|
+
const normalizeBooleanPrimitiveValue = (value: boolean | number | string): boolean | null => {
|
|
309
309
|
if (typeof value === "boolean") return value;
|
|
310
310
|
if (value === 1) return true;
|
|
311
311
|
if (value === 0) return false;
|
|
312
|
+
if (typeof value !== "string") return null;
|
|
313
|
+
const text = value.trim().toLowerCase();
|
|
314
|
+
if (text === "true" || text === "1") return true;
|
|
315
|
+
if (text === "false" || text === "0") return false;
|
|
312
316
|
return null;
|
|
313
317
|
};
|
|
314
318
|
|
|
@@ -317,13 +321,13 @@ Object.assign(Boolean, {
|
|
|
317
321
|
refName: "Boolean",
|
|
318
322
|
[DEFAULT_VALUE]: false,
|
|
319
323
|
[EXAMPLE_VALUE]: true,
|
|
320
|
-
validate(value: boolean | number) {
|
|
324
|
+
validate(value: boolean | number | string) {
|
|
321
325
|
return normalizeBooleanPrimitiveValue(value) !== null;
|
|
322
326
|
},
|
|
323
|
-
parseValue(input: boolean | number) {
|
|
327
|
+
parseValue(input: boolean | number | string) {
|
|
324
328
|
return normalizeBooleanPrimitiveValue(input) ?? input;
|
|
325
329
|
},
|
|
326
|
-
serializeValue(value: boolean | number) {
|
|
330
|
+
serializeValue(value: boolean | number | string) {
|
|
327
331
|
return normalizeBooleanPrimitiveValue(value) ?? value;
|
|
328
332
|
},
|
|
329
333
|
});
|
package/base/symbols.ts
CHANGED
|
@@ -13,6 +13,10 @@ export const STATE_META = Symbol.for("akan.state");
|
|
|
13
13
|
export const STATE_INIT_META = Symbol.for("akan.state.init");
|
|
14
14
|
export const STATE_DERIVED_META = Symbol.for("akan.state.derived");
|
|
15
15
|
export const ACTION_META = Symbol.for("akan.action");
|
|
16
|
+
/** Which module declared each action. See `ActionOwner`. */
|
|
17
|
+
export const ACTION_OWNER_META = Symbol.for("akan.action.owner");
|
|
18
|
+
/** What a dispatcher does, carried on the function so a component handed one can annotate the DOM with it. */
|
|
19
|
+
export const ACTION_TAG = Symbol.for("akan.action.tag");
|
|
16
20
|
export const SERVER_VALUE = Symbol.for("akan.value.server");
|
|
17
21
|
export const CLIENT_VALUE = Symbol.for("akan.value.client");
|
|
18
22
|
export const DEFAULT_VALUE = Symbol.for("akan.value.default");
|
package/client/capacitor.ts
CHANGED
|
@@ -46,6 +46,28 @@ export type CapacitorContactsModule = {
|
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
export type CapacitorSpeechRecognitionModule = {
|
|
50
|
+
SpeechRecognition: {
|
|
51
|
+
available: () => Promise<{ available: boolean }>;
|
|
52
|
+
checkPermissions: () => Promise<{ speechRecognition: CapacitorPermissionState }>;
|
|
53
|
+
requestPermissions: () => Promise<{ speechRecognition: CapacitorPermissionState }>;
|
|
54
|
+
start: (options: Record<string, unknown>) => Promise<{ matches?: string[] }>;
|
|
55
|
+
stop: () => Promise<void>;
|
|
56
|
+
removeAllListeners: () => Promise<void> | void;
|
|
57
|
+
addListener: (
|
|
58
|
+
eventName: string,
|
|
59
|
+
listenerFunc: (data: { matches?: string[] }) => void,
|
|
60
|
+
) => Promise<{ remove: () => Promise<void> | void }> | { remove: () => Promise<void> | void };
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export type CapacitorTextToSpeechModule = {
|
|
65
|
+
TextToSpeech: {
|
|
66
|
+
speak: (options: { text: string; lang?: string; rate?: number }) => Promise<void>;
|
|
67
|
+
stop: () => Promise<void>;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
|
|
49
71
|
export type CapacitorCoreModule = {
|
|
50
72
|
CapacitorCookies: {
|
|
51
73
|
setCookie: (options: { key: string; value: string; path?: string }) => Promise<void> | void;
|
|
@@ -155,6 +177,8 @@ type CapacitorModuleMap = {
|
|
|
155
177
|
preferences: CapacitorPreferencesModule;
|
|
156
178
|
pushNotifications: CapacitorPushNotificationsModule;
|
|
157
179
|
safeArea: CapacitorSafeAreaModule;
|
|
180
|
+
speechRecognition: CapacitorSpeechRecognitionModule;
|
|
181
|
+
textToSpeech: CapacitorTextToSpeechModule;
|
|
158
182
|
updater: CapacitorUpdaterModule;
|
|
159
183
|
};
|
|
160
184
|
|
|
@@ -257,6 +281,16 @@ export const loadCapacitorSafeArea = () =>
|
|
|
257
281
|
SafeArea: getCapacitorPlugin<CapacitorSafeAreaModule["SafeArea"]>("SafeArea"),
|
|
258
282
|
}));
|
|
259
283
|
|
|
284
|
+
export const loadCapacitorSpeechRecognition = () =>
|
|
285
|
+
loadCapacitorModule("speechRecognition", async () => ({
|
|
286
|
+
SpeechRecognition: getCapacitorPlugin<CapacitorSpeechRecognitionModule["SpeechRecognition"]>("SpeechRecognition"),
|
|
287
|
+
}));
|
|
288
|
+
|
|
289
|
+
export const loadCapacitorTextToSpeech = () =>
|
|
290
|
+
loadCapacitorModule("textToSpeech", async () => ({
|
|
291
|
+
TextToSpeech: getCapacitorPlugin<CapacitorTextToSpeechModule["TextToSpeech"]>("TextToSpeech"),
|
|
292
|
+
}));
|
|
293
|
+
|
|
260
294
|
export const loadCapacitorUpdater = () =>
|
|
261
295
|
loadCapacitorModule("updater", async () => ({
|
|
262
296
|
CapacitorUpdater: getCapacitorPlugin<CapacitorUpdaterModule["CapacitorUpdater"]>("CapacitorUpdater"),
|
package/client/clientRuntime.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SliceMeta } from "akanjs/fetch";
|
|
2
|
+
import type { SerializedArg } from "akanjs/signal";
|
|
2
3
|
import type { ReactNode } from "react";
|
|
3
4
|
import type { TransMessageOption } from "./makePageProto";
|
|
4
5
|
|
|
@@ -47,6 +48,10 @@ type RuntimeFetch = typeof globalThis.fetch & {
|
|
|
47
48
|
serializedSignal: Record<string, unknown>;
|
|
48
49
|
setJwt: (jwt: string | null) => void;
|
|
49
50
|
slice: Record<string, SliceMeta>;
|
|
51
|
+
/** Sort keys per model refName, registered from each serialized signal's filter. */
|
|
52
|
+
sortKeyMap?: Map<string, string[]>;
|
|
53
|
+
/** Filter queries per model refName, with the args each one takes — what the root slice picks from. */
|
|
54
|
+
filterQueryMap?: Map<string, { [queryKey: string]: SerializedArg[] }>;
|
|
50
55
|
ws: RuntimeWs;
|
|
51
56
|
[key: string]: unknown;
|
|
52
57
|
};
|
|
@@ -75,6 +80,13 @@ globalWithRuntime[CLIENT_RUNTIME_KEY] = state;
|
|
|
75
80
|
const missingRuntimeError = () =>
|
|
76
81
|
new Error("Akan client runtime is not registered. Import the generated app client first.");
|
|
77
82
|
|
|
83
|
+
const applyRuntimeErrorConstructor = (runtime: ClientRuntime) => {
|
|
84
|
+
const instance = (runtime.fetch as RuntimeFetch | undefined)?.instance as
|
|
85
|
+
| { setErrorConstructor?: (Err: unknown) => void }
|
|
86
|
+
| undefined;
|
|
87
|
+
if (typeof instance?.setErrorConstructor === "function") instance.setErrorConstructor(runtime.Err);
|
|
88
|
+
};
|
|
89
|
+
|
|
78
90
|
export const registerClientRuntime = <Runtime>(
|
|
79
91
|
runtime: Runtime,
|
|
80
92
|
{ scope = "app" }: { scope?: RuntimeScope } = {},
|
|
@@ -82,6 +94,7 @@ export const registerClientRuntime = <Runtime>(
|
|
|
82
94
|
if (state.scope === "app" && scope === "lib") return runtime;
|
|
83
95
|
state.runtime = runtime as ClientRuntime;
|
|
84
96
|
state.scope = scope;
|
|
97
|
+
applyRuntimeErrorConstructor(state.runtime);
|
|
85
98
|
return runtime;
|
|
86
99
|
};
|
|
87
100
|
|
package/client/csrTypes.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import type { ReactDOMAttributes } from "@use-gesture/react/dist/declarations/src/types";
|
|
3
3
|
import type { PromiseOrObject } from "akanjs/base";
|
|
4
|
-
import {
|
|
4
|
+
import { type ForwardRefExoticComponent, type ReactNode, type RefObject, useContext } from "react";
|
|
5
5
|
import type { AnimatedComponent, AnimatedProps, Interpolation, SpringValue } from "react-spring";
|
|
6
6
|
import type { RouterInstance } from "./router";
|
|
7
|
+
import { sharedContext } from "./sharedContext";
|
|
7
8
|
import type { ReactFont } from "./types";
|
|
8
9
|
|
|
9
10
|
export type TransitionType = "none" | "fade" | "bottomUp" | "stack" | "scaleOut";
|
|
@@ -349,7 +350,7 @@ export type UseCsrTransition = CsrTransitionStyles & {
|
|
|
349
350
|
};
|
|
350
351
|
|
|
351
352
|
export type CsrContextType = RouteState & UseCsrTransition;
|
|
352
|
-
export const csrContext =
|
|
353
|
+
export const csrContext = sharedContext<CsrContextType>("csr", {} as unknown as CsrContextType);
|
|
353
354
|
export const useCsr = () => {
|
|
354
355
|
const contextValues = useContext(csrContext);
|
|
355
356
|
return contextValues;
|
|
@@ -363,7 +364,7 @@ export interface PathContextType {
|
|
|
363
364
|
setGestureEnabled: (enabled: boolean) => void;
|
|
364
365
|
registerFrameSlot: (slot: FrameSlotRegistration) => () => void;
|
|
365
366
|
}
|
|
366
|
-
export const pathContext =
|
|
367
|
+
export const pathContext = sharedContext<PathContextType>("path", {} as unknown as PathContextType);
|
|
367
368
|
export const usePathCtx = () => {
|
|
368
369
|
const contextValues = useContext(pathContext);
|
|
369
370
|
return contextValues;
|
package/client/index.ts
CHANGED
package/client/locale.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { sharedContext } from "./sharedContext";
|
|
3
3
|
|
|
4
|
-
export const dictionaryContext =
|
|
4
|
+
export const dictionaryContext = sharedContext<{ [key: string]: { [key: string]: string } }>("dictionary", {});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { type Context, createContext } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A React context interned on `globalThis`, which is how every context this framework owns must be made.
|
|
6
|
+
*
|
|
7
|
+
* An akan build does not give an app one copy of `akanjs`: it inlines each reachable module into every client
|
|
8
|
+
* chunk that reaches it — four copies of the agent runtime in this repo's own docs app. A context is identified
|
|
9
|
+
* by object identity, so a Provider mounted from one copy is invisible to a consumer holding another, and the
|
|
10
|
+
* consumer silently reads the context's default instead.
|
|
11
|
+
*
|
|
12
|
+
* Silently is the whole problem. `UiOverrideContext` was a plain `createContext`, so a route's `_overrides.tsx`
|
|
13
|
+
* bound its slots in the chunk holding the generated provider and every overridable component in another chunk
|
|
14
|
+
* kept rendering the framework default — no throw, no warning, and only *some* slots affected, which reads like
|
|
15
|
+
* a bug in the app's own component. The same shape cost a zone every tool it declared.
|
|
16
|
+
*
|
|
17
|
+
* The rule is therefore mechanical rather than case-by-case: a context whose Provider and consumers can be
|
|
18
|
+
* bundled apart is every context worth having, so all of them go through here. A test fails if one does not.
|
|
19
|
+
*
|
|
20
|
+
* `use-agentic` carries its own twin under a `useAgentic.` prefix, deliberately — it ships as a standalone
|
|
21
|
+
* package and cannot import this one. The prefixes keep the two namespaces from ever meeting.
|
|
22
|
+
*/
|
|
23
|
+
export const sharedContext = <T>(name: string, initial: T): Context<T> => {
|
|
24
|
+
const key = Symbol.for(`akanjs.context.${name}`);
|
|
25
|
+
const holder = globalThis as typeof globalThis & { [slot: symbol]: Context<T> | undefined };
|
|
26
|
+
const existing = holder[key];
|
|
27
|
+
if (existing) return existing;
|
|
28
|
+
const created = createContext(initial);
|
|
29
|
+
holder[key] = created;
|
|
30
|
+
return created;
|
|
31
|
+
};
|
package/client/translator.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { pathGetLoose } from "akanjs/common";
|
|
2
2
|
|
|
3
3
|
export interface Dictionary {
|
|
4
4
|
[key: string]: {
|
|
@@ -63,7 +63,7 @@ export class Translator {
|
|
|
63
63
|
static translateByLocale(lang: string, key: string, param?: Record<string, string | number>): string {
|
|
64
64
|
const dictionary = getTranslatorState().langDictionaryMap.get(lang);
|
|
65
65
|
if (!dictionary) return key;
|
|
66
|
-
const msg = (
|
|
66
|
+
const msg = (pathGetLoose(key, dictionary, ".", { t: key }) as { t: string }).t;
|
|
67
67
|
return param ? msg.replace(/{([^}]+)}/g, (_, key: string) => param[key] as string) : msg;
|
|
68
68
|
}
|
|
69
69
|
|
package/client/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BaseInsight } from "akanjs/constant";
|
|
2
|
-
import type { FetchInitForm, SliceMeta } from "akanjs/fetch";
|
|
2
|
+
import type { FetchInitForm, QuerySetting, SliceMeta } from "akanjs/fetch";
|
|
3
3
|
import type { ReactElement, ReactNode } from "react";
|
|
4
4
|
|
|
5
5
|
export type ReactFontStyle = "normal" | "italic" | "oblique";
|
|
@@ -109,7 +109,7 @@ const slugFontPart = (value: string) =>
|
|
|
109
109
|
export interface ModelsProps<M extends { id: string }> {
|
|
110
110
|
className?: string;
|
|
111
111
|
slice?: SliceMeta;
|
|
112
|
-
query?:
|
|
112
|
+
query?: QuerySetting;
|
|
113
113
|
init?: FetchInitForm<any, any>;
|
|
114
114
|
onClickItem?: (model: M) => unknown;
|
|
115
115
|
}
|
|
@@ -127,7 +127,7 @@ export type ModelProps<T extends string, L extends { id: string }> = { [key in T
|
|
|
127
127
|
export interface ModelDashboardProps<Summary> {
|
|
128
128
|
className?: string;
|
|
129
129
|
summary: Summary;
|
|
130
|
-
queryMap?:
|
|
130
|
+
queryMap?: { [column: string]: QuerySetting };
|
|
131
131
|
columns?: (keyof Summary)[];
|
|
132
132
|
hidePresents?: boolean;
|
|
133
133
|
slice?: SliceMeta;
|
package/common/deepObjectify.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { isDayjs } from "./isDayjs";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
interface DeepObjectifyOption {
|
|
4
|
+
serializable?: boolean;
|
|
5
|
+
convertDate?: "string" | "number";
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const objectifyChild = (value: unknown, option: DeepObjectifyOption): unknown => {
|
|
9
|
+
const modelValue = value as { __ModelType__?: string } | null | undefined;
|
|
10
|
+
return modelValue?.__ModelType__ && !option.serializable ? value : deepObjectify(value, option);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const deepObjectify = <T = unknown>(obj: T | null | undefined, option: DeepObjectifyOption = {}): T => {
|
|
7
14
|
if (isDayjs(obj) || obj?.constructor === Date) {
|
|
8
15
|
if (!option.serializable && !option.convertDate) return obj as T;
|
|
9
16
|
if (option.convertDate === "string") return obj.toISOString() as T;
|
|
@@ -12,13 +19,20 @@ export const deepObjectify = <T = unknown>(
|
|
|
12
19
|
else return (isDayjs(obj) ? obj.toDate() : obj) as T;
|
|
13
20
|
} else if (Array.isArray(obj)) {
|
|
14
21
|
return obj.map((o: unknown) => deepObjectify(o, option)) as T;
|
|
22
|
+
} else if (obj instanceof Map) {
|
|
23
|
+
|
|
24
|
+
const entries = [...obj.entries()].map(
|
|
25
|
+
([key, value]: [string, unknown]) => [key, objectifyChild(value, option)] as const,
|
|
26
|
+
);
|
|
27
|
+
return (option.serializable ? Object.fromEntries(entries) : new Map(entries)) as T;
|
|
28
|
+
} else if (obj instanceof Set) {
|
|
29
|
+
const values = [...obj.values()].map((value: unknown) => objectifyChild(value, option));
|
|
30
|
+
return (option.serializable ? values : new Set(values)) as T;
|
|
15
31
|
} else if (obj && typeof obj === "object") {
|
|
16
32
|
const val: Record<string, unknown> = {};
|
|
17
33
|
const objRecord = obj as Record<string, unknown>;
|
|
18
34
|
Object.keys(obj).forEach((key) => {
|
|
19
|
-
|
|
20
|
-
if (fieldValue?.__ModelType__ && !option.serializable) val[key] = fieldValue;
|
|
21
|
-
else if (typeof objRecord[key] !== "function") val[key] = deepObjectify(fieldValue, option);
|
|
35
|
+
if (typeof objRecord[key] !== "function") val[key] = objectifyChild(objRecord[key], option);
|
|
22
36
|
});
|
|
23
37
|
return val as T;
|
|
24
38
|
} else {
|
package/common/index.ts
CHANGED
|
@@ -27,21 +27,37 @@ export {
|
|
|
27
27
|
resolveAkanI18nConfig,
|
|
28
28
|
} from "./localeConfig";
|
|
29
29
|
export { lowerlize } from "./lowerlize";
|
|
30
|
+
export {
|
|
31
|
+
isMcpDescribableArg,
|
|
32
|
+
type McpExposureEndpoint,
|
|
33
|
+
type McpExposureOption,
|
|
34
|
+
mcpBaseVerbOf,
|
|
35
|
+
mcpHintsOf,
|
|
36
|
+
mcpPromptRefusalOf,
|
|
37
|
+
mcpRefusalOf,
|
|
38
|
+
} from "./mcpExposure";
|
|
30
39
|
export { mergeVersion } from "./mergeVersion";
|
|
31
40
|
export { objectify } from "./objectify";
|
|
32
41
|
export { pathGet } from "./pathGet";
|
|
42
|
+
export { pathGetLoose } from "./pathGetLoose";
|
|
33
43
|
export { pathSet } from "./pathSet";
|
|
34
44
|
export { randomPick } from "./randomPick";
|
|
35
45
|
export { randomPicks } from "./randomPicks";
|
|
36
46
|
export {
|
|
37
47
|
assertUniqueRoutePatterns,
|
|
38
48
|
compareRouteSpecificity,
|
|
49
|
+
getPageSourceFileViolation,
|
|
50
|
+
getRouteExports,
|
|
39
51
|
isRouteSourceFile,
|
|
40
52
|
isSpecialRouteLeaf,
|
|
53
|
+
LAYOUT_ROUTE_EXPORTS,
|
|
41
54
|
matchRoutePattern,
|
|
42
55
|
normalizeRoutePattern,
|
|
56
|
+
PAGE_ROUTE_EXPORTS,
|
|
43
57
|
type ParsedRouteModuleKey,
|
|
44
58
|
parseRouteModuleKey,
|
|
59
|
+
RESERVED_ROUTE_CONFIG_EXPORTS,
|
|
60
|
+
ROOT_LAYOUT_ROUTE_EXPORTS,
|
|
45
61
|
type RouteModuleKind,
|
|
46
62
|
routeSegmentToPatternPart,
|
|
47
63
|
routeSegmentToTreePath,
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { capitalize } from "./capitalize";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* What MCP says about one endpoint: whether it is published, why it is not, and the hints it carries.
|
|
5
|
+
*
|
|
6
|
+
* Structurally typed like the rest of `common/` so the same rules answer on both sides — the server builds its
|
|
7
|
+
* catalogue from them and the browser API explorer badges an endpoint from them. A second implementation would
|
|
8
|
+
* eventually disagree, and an audit surface that disagrees with the catalogue is worse than none.
|
|
9
|
+
*
|
|
10
|
+
* Every rejection returns the sentence an author reads, at boot in the server log and in the explorer. Fail-closed
|
|
11
|
+
* with no reason leaves an author whose endpoint is missing from the catalogue nowhere to look but the source.
|
|
12
|
+
*/
|
|
13
|
+
export interface McpExposureEndpoint {
|
|
14
|
+
type: string;
|
|
15
|
+
returns: { refName: string };
|
|
16
|
+
args: { name: string; refName: string; type: string; arrDepth?: number; nullable?: boolean }[];
|
|
17
|
+
guards?: string[];
|
|
18
|
+
fileUpload?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface McpExposureOption {
|
|
22
|
+
/**
|
|
23
|
+
* The read-only deployment valve, which is server configuration. The browser explorer cannot know it and so
|
|
24
|
+
* badges what the code decided; the boot log is where a read-only deployment says what it dropped.
|
|
25
|
+
*/
|
|
26
|
+
readOnly?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** `Any` publishes as the empty schema, which tells a model nothing — so it is left out rather than described. */
|
|
30
|
+
export const isMcpDescribableArg = (arg: { refName: string }) => arg.refName !== "Any";
|
|
31
|
+
|
|
32
|
+
/** Which CRUD verb a generated endpoint key is, or `null` when the key is not one of the five. */
|
|
33
|
+
export const mcpBaseVerbOf = (refName: string, key: string) => {
|
|
34
|
+
const cap = capitalize(refName);
|
|
35
|
+
if (key === refName || key === `light${cap}`) return "get" as const;
|
|
36
|
+
if (key === `create${cap}`) return "create" as const;
|
|
37
|
+
if (key === `update${cap}`) return "update" as const;
|
|
38
|
+
if (key === `remove${cap}`) return "remove" as const;
|
|
39
|
+
return null;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The hints a client renders beside a tool. Hints only — clients are told to distrust them, so they inform a UI
|
|
44
|
+
* and never stand in for a guard. `openWorldHint` is always false: every endpoint reaches this app's own
|
|
45
|
+
* database, not the wider internet.
|
|
46
|
+
*/
|
|
47
|
+
export const mcpHintsOf = (key: string, endpoint: { type: string }) => {
|
|
48
|
+
const readOnly = endpoint.type === "query";
|
|
49
|
+
const destructive = !readOnly && /^(remove|delete)/.test(key);
|
|
50
|
+
return {
|
|
51
|
+
readOnlyHint: readOnly,
|
|
52
|
+
destructiveHint: destructive,
|
|
53
|
+
idempotentHint: readOnly || /^(set|update)/.test(key),
|
|
54
|
+
openWorldHint: false,
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/** The sentence explaining why this endpoint is not in the catalogue, or `null` when it is. */
|
|
59
|
+
export const mcpRefusalOf = (endpoint: McpExposureEndpoint, { readOnly }: McpExposureOption = {}): string | null => {
|
|
60
|
+
|
|
61
|
+
if (!endpoint.guards?.length)
|
|
62
|
+
return "it declares no guards, and exposure follows them — write `guards: [Public]` if anonymous access is the intent.";
|
|
63
|
+
if (endpoint.type === "prompt") return mcpPromptRefusalOf(endpoint);
|
|
64
|
+
if (endpoint.type === "pubsub" || endpoint.type === "message")
|
|
65
|
+
return `\`${endpoint.type}\` rides the websocket, and its internal arguments read a socket an MCP request does not have.`;
|
|
66
|
+
if (readOnly && endpoint.type !== "query")
|
|
67
|
+
return "this deployment is read-only, which drops every endpoint that is not a query.";
|
|
68
|
+
if (endpoint.returns.refName === "Any" || endpoint.returns.refName === "Upload")
|
|
69
|
+
return `a return typed \`${endpoint.returns.refName}\` cannot be described to a model.`;
|
|
70
|
+
if (endpoint.fileUpload || endpoint.args.some((arg) => arg.refName === "Upload"))
|
|
71
|
+
return "a file upload has no MCP representation.";
|
|
72
|
+
if (endpoint.type === "mutation" && !endpoint.guards.some((name) => name !== "Public"))
|
|
73
|
+
return "a mutation needs a real guard — `[Public]` is having none, spelled out.";
|
|
74
|
+
const opaque = endpoint.args.find((arg) => !isMcpDescribableArg(arg) && arg.type !== "search" && !arg.nullable);
|
|
75
|
+
if (opaque)
|
|
76
|
+
return `its required argument \`${opaque.name}\` is typed \`Any\`, which is left out of the published schema — expose a named filter slice instead.`;
|
|
77
|
+
return null;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* A prompt is a read exposed on the same terms as a query, so every rejection here is one thing: an argument
|
|
82
|
+
* `prompts/get` cannot carry. Its `arguments` is a flat string map — one string per name, and no schema beside it
|
|
83
|
+
* — which rules out the argument *kinds* the builder already refuses and, just as surely, two argument *types* it
|
|
84
|
+
* accepts. A tool escapes both because it publishes a real JSON Schema.
|
|
85
|
+
*/
|
|
86
|
+
export const mcpPromptRefusalOf = (endpoint: McpExposureEndpoint): string | null => {
|
|
87
|
+
const carried = endpoint.args.find((arg) => arg.type === "body" || arg.type === "msg" || arg.type === "room");
|
|
88
|
+
if (carried)
|
|
89
|
+
return `a prompt's arguments travel as a flat string map, so its \`${carried.type}\` argument \`${carried.name}\` cannot be carried.`;
|
|
90
|
+
|
|
91
|
+
const list = endpoint.args.find((arg) => arg.arrDepth);
|
|
92
|
+
if (list)
|
|
93
|
+
return `a prompt argument is one string, so its list argument \`${list.name}\` could never carry more than one value.`;
|
|
94
|
+
|
|
95
|
+
const opaque = endpoint.args.find((arg) => !isMcpDescribableArg(arg));
|
|
96
|
+
if (opaque)
|
|
97
|
+
return `its argument \`${opaque.name}\` is typed \`Any\`, and a prompt has no schema in which to describe one.`;
|
|
98
|
+
return null;
|
|
99
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type Indexable = Record<string, unknown>;
|
|
2
|
+
|
|
3
|
+
const isIndexable = (value: unknown): value is Indexable => Object(value) === value;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Reads a dotted path whose segments may themselves contain the separator.
|
|
7
|
+
*
|
|
8
|
+
* Dictionary keys are built as `<refName>.<value>` and an enum value is a real-world identifier — `gpt-5.6-terra`,
|
|
9
|
+
* `v1.2` — so the key is not a clean dotted path and `pathGet` splits it into segments that were never nodes.
|
|
10
|
+
* The tree stores such a key literally, so resolution has to try joined prefixes too.
|
|
11
|
+
*/
|
|
12
|
+
export const pathGetLoose = (
|
|
13
|
+
path: string | readonly string[],
|
|
14
|
+
obj: unknown,
|
|
15
|
+
separator = ".",
|
|
16
|
+
fallback: unknown = null,
|
|
17
|
+
): unknown => {
|
|
18
|
+
const walk = (node: unknown, rest: readonly string[]): unknown => {
|
|
19
|
+
if (!rest.length) return node;
|
|
20
|
+
if (!isIndexable(node)) return undefined;
|
|
21
|
+
|
|
22
|
+
for (let take = 1; take <= rest.length; take += 1) {
|
|
23
|
+
const child = node[rest.slice(0, take).join(separator)];
|
|
24
|
+
if (child === undefined) continue;
|
|
25
|
+
const found = walk(child, rest.slice(take));
|
|
26
|
+
if (found !== undefined) return found;
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
};
|
|
30
|
+
return walk(obj, Array.isArray(path) ? [...path] : (path as string).split(separator)) ?? fallback;
|
|
31
|
+
};
|