@intentcomputing/koko-agent-sdk 1.0.1
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 +10 -0
- package/CODE_OF_CONDUCT.md +3 -0
- package/CONTRIBUTING.md +9 -0
- package/LICENSE +21 -0
- package/README.md +65 -0
- package/README.zh-CN.md +50 -0
- package/SECURITY.md +5 -0
- package/android/build.gradle +40 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/cn/intentcomputing/kokoagentsdk/KokoAgentSdkModule.java +1356 -0
- package/android/src/main/java/cn/intentcomputing/kokoagentsdk/KokoAgentSdkPackage.java +23 -0
- package/docs/INTEGRATION.md +168 -0
- package/docs/INTEGRATION.zh-CN.md +140 -0
- package/docs/PRIVACY.md +11 -0
- package/docs/PRIVACY.zh-CN.md +11 -0
- package/docs/PUBLISH.md +11 -0
- package/docs/PUBLISH.zh-CN.md +11 -0
- package/ios/KokoAgentSdk/KokoAgentSdk.h +5 -0
- package/ios/KokoAgentSdk/KokoAgentSdk.m +2464 -0
- package/ios/KokoAgentSdk/KokoOcrBounds.h +20 -0
- package/ios/KokoAgentSdk/KokoScrollBounds.h +21 -0
- package/koko-agent-sdk.podspec +23 -0
- package/lib/commonjs/KokoAgent.js +1427 -0
- package/lib/commonjs/KokoAgent.js.map +1 -0
- package/lib/commonjs/assist/OnDeviceAssist.js +94 -0
- package/lib/commonjs/assist/OnDeviceAssist.js.map +1 -0
- package/lib/commonjs/assist/intentClassify.js +100 -0
- package/lib/commonjs/assist/intentClassify.js.map +1 -0
- package/lib/commonjs/assist/nodeRank.js +120 -0
- package/lib/commonjs/assist/nodeRank.js.map +1 -0
- package/lib/commonjs/assist/ocrTarget.js +135 -0
- package/lib/commonjs/assist/ocrTarget.js.map +1 -0
- package/lib/commonjs/assist/webVisualChange.js +29 -0
- package/lib/commonjs/assist/webVisualChange.js.map +1 -0
- package/lib/commonjs/client/ActionOutcomeUnknownError.js +28 -0
- package/lib/commonjs/client/ActionOutcomeUnknownError.js.map +1 -0
- package/lib/commonjs/client/AgentSession.js +858 -0
- package/lib/commonjs/client/AgentSession.js.map +1 -0
- package/lib/commonjs/client/GatewayClient.js +302 -0
- package/lib/commonjs/client/GatewayClient.js.map +1 -0
- package/lib/commonjs/client/OperationReplayGuard.js +62 -0
- package/lib/commonjs/client/OperationReplayGuard.js.map +1 -0
- package/lib/commonjs/client/RunCheckpoint.js +139 -0
- package/lib/commonjs/client/RunCheckpoint.js.map +1 -0
- package/lib/commonjs/client/loopDetect.js +184 -0
- package/lib/commonjs/client/loopDetect.js.map +1 -0
- package/lib/commonjs/client/recentSearch.js +50 -0
- package/lib/commonjs/client/recentSearch.js.map +1 -0
- package/lib/commonjs/client/walletChoiceGuard.js +18 -0
- package/lib/commonjs/client/walletChoiceGuard.js.map +1 -0
- package/lib/commonjs/client/webResultCategory.js +38 -0
- package/lib/commonjs/client/webResultCategory.js.map +1 -0
- package/lib/commonjs/commercial/AccountStore.js +78 -0
- package/lib/commonjs/commercial/AccountStore.js.map +1 -0
- package/lib/commonjs/commercial/AgentDebug.js +104 -0
- package/lib/commonjs/commercial/AgentDebug.js.map +1 -0
- package/lib/commonjs/commercial/ExecutionGuard.js +53 -0
- package/lib/commonjs/commercial/ExecutionGuard.js.map +1 -0
- package/lib/commonjs/commercial/UsageBus.js +42 -0
- package/lib/commonjs/commercial/UsageBus.js.map +1 -0
- package/lib/commonjs/commercial/branding.js +69 -0
- package/lib/commonjs/commercial/branding.js.map +1 -0
- package/lib/commonjs/commercial/devMode.js +52 -0
- package/lib/commonjs/commercial/devMode.js.map +1 -0
- package/lib/commonjs/commercial/trust.js +69 -0
- package/lib/commonjs/commercial/trust.js.map +1 -0
- package/lib/commonjs/confirmation/gate.js +62 -0
- package/lib/commonjs/confirmation/gate.js.map +1 -0
- package/lib/commonjs/cursor/CursorOverlay.js +141 -0
- package/lib/commonjs/cursor/CursorOverlay.js.map +1 -0
- package/lib/commonjs/cursor/PointerHand.js +51 -0
- package/lib/commonjs/cursor/PointerHand.js.map +1 -0
- package/lib/commonjs/cursor/controller.js +91 -0
- package/lib/commonjs/cursor/controller.js.map +1 -0
- package/lib/commonjs/cursor/pointer.js +49 -0
- package/lib/commonjs/cursor/pointer.js.map +1 -0
- package/lib/commonjs/debug/KokoRemoteSmoke.js +611 -0
- package/lib/commonjs/debug/KokoRemoteSmoke.js.map +1 -0
- package/lib/commonjs/explore/ExplorationGraph.js +418 -0
- package/lib/commonjs/explore/ExplorationGraph.js.map +1 -0
- package/lib/commonjs/explore/bootstrapExplore.js +59 -0
- package/lib/commonjs/explore/bootstrapExplore.js.map +1 -0
- package/lib/commonjs/host/HostActions.js +266 -0
- package/lib/commonjs/host/HostActions.js.map +1 -0
- package/lib/commonjs/i18n/index.js +169 -0
- package/lib/commonjs/i18n/index.js.map +1 -0
- package/lib/commonjs/i18n/runtimeMessages.js +184 -0
- package/lib/commonjs/i18n/runtimeMessages.js.map +1 -0
- package/lib/commonjs/index.js +640 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/native/NativeBridge.js +132 -0
- package/lib/commonjs/native/NativeBridge.js.map +1 -0
- package/lib/commonjs/native/navigationLabel.js +16 -0
- package/lib/commonjs/native/navigationLabel.js.map +1 -0
- package/lib/commonjs/native/normalizeViewTree.js +28 -0
- package/lib/commonjs/native/normalizeViewTree.js.map +1 -0
- package/lib/commonjs/native/pruneOffscreen.js +76 -0
- package/lib/commonjs/native/pruneOffscreen.js.map +1 -0
- package/lib/commonjs/native/scrollViewport.js +69 -0
- package/lib/commonjs/native/scrollViewport.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/privacy/redact.js +108 -0
- package/lib/commonjs/privacy/redact.js.map +1 -0
- package/lib/commonjs/privacy/screenEvidence.js +59 -0
- package/lib/commonjs/privacy/screenEvidence.js.map +1 -0
- package/lib/commonjs/privacy/screenModel.js +404 -0
- package/lib/commonjs/privacy/screenModel.js.map +1 -0
- package/lib/commonjs/privacy/sensitiveScreen.js +58 -0
- package/lib/commonjs/privacy/sensitiveScreen.js.map +1 -0
- package/lib/commonjs/privacy/userGate.js +213 -0
- package/lib/commonjs/privacy/userGate.js.map +1 -0
- package/lib/commonjs/protocol/actions.js +112 -0
- package/lib/commonjs/protocol/actions.js.map +1 -0
- package/lib/commonjs/provider/HostAppearanceStore.js +111 -0
- package/lib/commonjs/provider/HostAppearanceStore.js.map +1 -0
- package/lib/commonjs/provider/KokoProvider.js +81 -0
- package/lib/commonjs/provider/KokoProvider.js.map +1 -0
- package/lib/commonjs/provider/KokoUiContext.js +102 -0
- package/lib/commonjs/provider/KokoUiContext.js.map +1 -0
- package/lib/commonjs/selector/match.js +378 -0
- package/lib/commonjs/selector/match.js.map +1 -0
- package/lib/commonjs/task/TaskStore.js +361 -0
- package/lib/commonjs/task/TaskStore.js.map +1 -0
- package/lib/commonjs/task/types.js +2 -0
- package/lib/commonjs/task/types.js.map +1 -0
- package/lib/commonjs/task/useTaskStore.js +14 -0
- package/lib/commonjs/task/useTaskStore.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/ui/KokoChatSheet.js +885 -0
- package/lib/commonjs/ui/KokoChatSheet.js.map +1 -0
- package/lib/commonjs/ui/KokoComposer.js +161 -0
- package/lib/commonjs/ui/KokoComposer.js.map +1 -0
- package/lib/commonjs/ui/KokoDialogHost.js +254 -0
- package/lib/commonjs/ui/KokoDialogHost.js.map +1 -0
- package/lib/commonjs/ui/KokoEntryButton.js +81 -0
- package/lib/commonjs/ui/KokoEntryButton.js.map +1 -0
- package/lib/commonjs/ui/KokoObserver.js +522 -0
- package/lib/commonjs/ui/KokoObserver.js.map +1 -0
- package/lib/commonjs/ui/KokoOverlayLayer.js +45 -0
- package/lib/commonjs/ui/KokoOverlayLayer.js.map +1 -0
- package/lib/commonjs/ui/KokoSubtitle.js +95 -0
- package/lib/commonjs/ui/KokoSubtitle.js.map +1 -0
- package/lib/commonjs/ui/KokoTaskPanel.js +322 -0
- package/lib/commonjs/ui/KokoTaskPanel.js.map +1 -0
- package/lib/commonjs/ui/hostOverlay.js +126 -0
- package/lib/commonjs/ui/hostOverlay.js.map +1 -0
- package/lib/commonjs/ui/icons.js +132 -0
- package/lib/commonjs/ui/icons.js.map +1 -0
- package/lib/commonjs/ui/progressChrome.js +66 -0
- package/lib/commonjs/ui/progressChrome.js.map +1 -0
- package/lib/commonjs/ui/safeArea.js +96 -0
- package/lib/commonjs/ui/safeArea.js.map +1 -0
- package/lib/commonjs/ui/useOverlayOrigin.js +40 -0
- package/lib/commonjs/ui/useOverlayOrigin.js.map +1 -0
- package/lib/module/KokoAgent.js +1418 -0
- package/lib/module/KokoAgent.js.map +1 -0
- package/lib/module/assist/OnDeviceAssist.js +89 -0
- package/lib/module/assist/OnDeviceAssist.js.map +1 -0
- package/lib/module/assist/intentClassify.js +95 -0
- package/lib/module/assist/intentClassify.js.map +1 -0
- package/lib/module/assist/nodeRank.js +115 -0
- package/lib/module/assist/nodeRank.js.map +1 -0
- package/lib/module/assist/ocrTarget.js +123 -0
- package/lib/module/assist/ocrTarget.js.map +1 -0
- package/lib/module/assist/webVisualChange.js +24 -0
- package/lib/module/assist/webVisualChange.js.map +1 -0
- package/lib/module/client/ActionOutcomeUnknownError.js +23 -0
- package/lib/module/client/ActionOutcomeUnknownError.js.map +1 -0
- package/lib/module/client/AgentSession.js +854 -0
- package/lib/module/client/AgentSession.js.map +1 -0
- package/lib/module/client/GatewayClient.js +293 -0
- package/lib/module/client/GatewayClient.js.map +1 -0
- package/lib/module/client/OperationReplayGuard.js +58 -0
- package/lib/module/client/OperationReplayGuard.js.map +1 -0
- package/lib/module/client/RunCheckpoint.js +135 -0
- package/lib/module/client/RunCheckpoint.js.map +1 -0
- package/lib/module/client/loopDetect.js +177 -0
- package/lib/module/client/loopDetect.js.map +1 -0
- package/lib/module/client/recentSearch.js +46 -0
- package/lib/module/client/recentSearch.js.map +1 -0
- package/lib/module/client/walletChoiceGuard.js +14 -0
- package/lib/module/client/walletChoiceGuard.js.map +1 -0
- package/lib/module/client/webResultCategory.js +34 -0
- package/lib/module/client/webResultCategory.js.map +1 -0
- package/lib/module/commercial/AccountStore.js +75 -0
- package/lib/module/commercial/AccountStore.js.map +1 -0
- package/lib/module/commercial/AgentDebug.js +99 -0
- package/lib/module/commercial/AgentDebug.js.map +1 -0
- package/lib/module/commercial/ExecutionGuard.js +49 -0
- package/lib/module/commercial/ExecutionGuard.js.map +1 -0
- package/lib/module/commercial/UsageBus.js +38 -0
- package/lib/module/commercial/UsageBus.js.map +1 -0
- package/lib/module/commercial/branding.js +63 -0
- package/lib/module/commercial/branding.js.map +1 -0
- package/lib/module/commercial/devMode.js +45 -0
- package/lib/module/commercial/devMode.js.map +1 -0
- package/lib/module/commercial/trust.js +62 -0
- package/lib/module/commercial/trust.js.map +1 -0
- package/lib/module/confirmation/gate.js +54 -0
- package/lib/module/confirmation/gate.js.map +1 -0
- package/lib/module/cursor/CursorOverlay.js +136 -0
- package/lib/module/cursor/CursorOverlay.js.map +1 -0
- package/lib/module/cursor/PointerHand.js +47 -0
- package/lib/module/cursor/PointerHand.js.map +1 -0
- package/lib/module/cursor/controller.js +87 -0
- package/lib/module/cursor/controller.js.map +1 -0
- package/lib/module/cursor/pointer.js +45 -0
- package/lib/module/cursor/pointer.js.map +1 -0
- package/lib/module/debug/KokoRemoteSmoke.js +608 -0
- package/lib/module/debug/KokoRemoteSmoke.js.map +1 -0
- package/lib/module/explore/ExplorationGraph.js +406 -0
- package/lib/module/explore/ExplorationGraph.js.map +1 -0
- package/lib/module/explore/bootstrapExplore.js +55 -0
- package/lib/module/explore/bootstrapExplore.js.map +1 -0
- package/lib/module/host/HostActions.js +255 -0
- package/lib/module/host/HostActions.js.map +1 -0
- package/lib/module/i18n/index.js +159 -0
- package/lib/module/i18n/index.js.map +1 -0
- package/lib/module/i18n/runtimeMessages.js +180 -0
- package/lib/module/i18n/runtimeMessages.js.map +1 -0
- package/lib/module/index.js +44 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/native/NativeBridge.js +128 -0
- package/lib/module/native/NativeBridge.js.map +1 -0
- package/lib/module/native/navigationLabel.js +12 -0
- package/lib/module/native/navigationLabel.js.map +1 -0
- package/lib/module/native/normalizeViewTree.js +25 -0
- package/lib/module/native/normalizeViewTree.js.map +1 -0
- package/lib/module/native/pruneOffscreen.js +72 -0
- package/lib/module/native/pruneOffscreen.js.map +1 -0
- package/lib/module/native/scrollViewport.js +63 -0
- package/lib/module/native/scrollViewport.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/privacy/redact.js +103 -0
- package/lib/module/privacy/redact.js.map +1 -0
- package/lib/module/privacy/screenEvidence.js +50 -0
- package/lib/module/privacy/screenEvidence.js.map +1 -0
- package/lib/module/privacy/screenModel.js +397 -0
- package/lib/module/privacy/screenModel.js.map +1 -0
- package/lib/module/privacy/sensitiveScreen.js +52 -0
- package/lib/module/privacy/sensitiveScreen.js.map +1 -0
- package/lib/module/privacy/userGate.js +202 -0
- package/lib/module/privacy/userGate.js.map +1 -0
- package/lib/module/protocol/actions.js +108 -0
- package/lib/module/protocol/actions.js.map +1 -0
- package/lib/module/provider/HostAppearanceStore.js +101 -0
- package/lib/module/provider/HostAppearanceStore.js.map +1 -0
- package/lib/module/provider/KokoProvider.js +74 -0
- package/lib/module/provider/KokoProvider.js.map +1 -0
- package/lib/module/provider/KokoUiContext.js +96 -0
- package/lib/module/provider/KokoUiContext.js.map +1 -0
- package/lib/module/selector/match.js +366 -0
- package/lib/module/selector/match.js.map +1 -0
- package/lib/module/task/TaskStore.js +356 -0
- package/lib/module/task/TaskStore.js.map +1 -0
- package/lib/module/task/types.js +2 -0
- package/lib/module/task/types.js.map +1 -0
- package/lib/module/task/useTaskStore.js +10 -0
- package/lib/module/task/useTaskStore.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/ui/KokoChatSheet.js +879 -0
- package/lib/module/ui/KokoChatSheet.js.map +1 -0
- package/lib/module/ui/KokoComposer.js +155 -0
- package/lib/module/ui/KokoComposer.js.map +1 -0
- package/lib/module/ui/KokoDialogHost.js +247 -0
- package/lib/module/ui/KokoDialogHost.js.map +1 -0
- package/lib/module/ui/KokoEntryButton.js +74 -0
- package/lib/module/ui/KokoEntryButton.js.map +1 -0
- package/lib/module/ui/KokoObserver.js +516 -0
- package/lib/module/ui/KokoObserver.js.map +1 -0
- package/lib/module/ui/KokoOverlayLayer.js +39 -0
- package/lib/module/ui/KokoOverlayLayer.js.map +1 -0
- package/lib/module/ui/KokoSubtitle.js +90 -0
- package/lib/module/ui/KokoSubtitle.js.map +1 -0
- package/lib/module/ui/KokoTaskPanel.js +316 -0
- package/lib/module/ui/KokoTaskPanel.js.map +1 -0
- package/lib/module/ui/hostOverlay.js +120 -0
- package/lib/module/ui/hostOverlay.js.map +1 -0
- package/lib/module/ui/icons.js +124 -0
- package/lib/module/ui/icons.js.map +1 -0
- package/lib/module/ui/progressChrome.js +58 -0
- package/lib/module/ui/progressChrome.js.map +1 -0
- package/lib/module/ui/safeArea.js +92 -0
- package/lib/module/ui/safeArea.js.map +1 -0
- package/lib/module/ui/useOverlayOrigin.js +36 -0
- package/lib/module/ui/useOverlayOrigin.js.map +1 -0
- package/lib/typescript/commonjs/KokoAgent.d.ts +167 -0
- package/lib/typescript/commonjs/KokoAgent.d.ts.map +1 -0
- package/lib/typescript/commonjs/assist/OnDeviceAssist.d.ts +31 -0
- package/lib/typescript/commonjs/assist/OnDeviceAssist.d.ts.map +1 -0
- package/lib/typescript/commonjs/assist/intentClassify.d.ts +18 -0
- package/lib/typescript/commonjs/assist/intentClassify.d.ts.map +1 -0
- package/lib/typescript/commonjs/assist/nodeRank.d.ts +32 -0
- package/lib/typescript/commonjs/assist/nodeRank.d.ts.map +1 -0
- package/lib/typescript/commonjs/assist/ocrTarget.d.ts +25 -0
- package/lib/typescript/commonjs/assist/ocrTarget.d.ts.map +1 -0
- package/lib/typescript/commonjs/assist/webVisualChange.d.ts +6 -0
- package/lib/typescript/commonjs/assist/webVisualChange.d.ts.map +1 -0
- package/lib/typescript/commonjs/client/ActionOutcomeUnknownError.d.ts +13 -0
- package/lib/typescript/commonjs/client/ActionOutcomeUnknownError.d.ts.map +1 -0
- package/lib/typescript/commonjs/client/AgentSession.d.ts +56 -0
- package/lib/typescript/commonjs/client/AgentSession.d.ts.map +1 -0
- package/lib/typescript/commonjs/client/GatewayClient.d.ts +149 -0
- package/lib/typescript/commonjs/client/GatewayClient.d.ts.map +1 -0
- package/lib/typescript/commonjs/client/OperationReplayGuard.d.ts +13 -0
- package/lib/typescript/commonjs/client/OperationReplayGuard.d.ts.map +1 -0
- package/lib/typescript/commonjs/client/RunCheckpoint.d.ts +57 -0
- package/lib/typescript/commonjs/client/RunCheckpoint.d.ts.map +1 -0
- package/lib/typescript/commonjs/client/loopDetect.d.ts +15 -0
- package/lib/typescript/commonjs/client/loopDetect.d.ts.map +1 -0
- package/lib/typescript/commonjs/client/recentSearch.d.ts +5 -0
- package/lib/typescript/commonjs/client/recentSearch.d.ts.map +1 -0
- package/lib/typescript/commonjs/client/walletChoiceGuard.d.ts +4 -0
- package/lib/typescript/commonjs/client/walletChoiceGuard.d.ts.map +1 -0
- package/lib/typescript/commonjs/client/webResultCategory.d.ts +5 -0
- package/lib/typescript/commonjs/client/webResultCategory.d.ts.map +1 -0
- package/lib/typescript/commonjs/commercial/AccountStore.d.ts +17 -0
- package/lib/typescript/commonjs/commercial/AccountStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/commercial/AgentDebug.d.ts +25 -0
- package/lib/typescript/commonjs/commercial/AgentDebug.d.ts.map +1 -0
- package/lib/typescript/commonjs/commercial/ExecutionGuard.d.ts +18 -0
- package/lib/typescript/commonjs/commercial/ExecutionGuard.d.ts.map +1 -0
- package/lib/typescript/commonjs/commercial/UsageBus.d.ts +18 -0
- package/lib/typescript/commonjs/commercial/UsageBus.d.ts.map +1 -0
- package/lib/typescript/commonjs/commercial/branding.d.ts +25 -0
- package/lib/typescript/commonjs/commercial/branding.d.ts.map +1 -0
- package/lib/typescript/commonjs/commercial/devMode.d.ts +26 -0
- package/lib/typescript/commonjs/commercial/devMode.d.ts.map +1 -0
- package/lib/typescript/commonjs/commercial/trust.d.ts +21 -0
- package/lib/typescript/commonjs/commercial/trust.d.ts.map +1 -0
- package/lib/typescript/commonjs/confirmation/gate.d.ts +18 -0
- package/lib/typescript/commonjs/confirmation/gate.d.ts.map +1 -0
- package/lib/typescript/commonjs/cursor/CursorOverlay.d.ts +13 -0
- package/lib/typescript/commonjs/cursor/CursorOverlay.d.ts.map +1 -0
- package/lib/typescript/commonjs/cursor/PointerHand.d.ts +16 -0
- package/lib/typescript/commonjs/cursor/PointerHand.d.ts.map +1 -0
- package/lib/typescript/commonjs/cursor/controller.d.ts +30 -0
- package/lib/typescript/commonjs/cursor/controller.d.ts.map +1 -0
- package/lib/typescript/commonjs/cursor/pointer.d.ts +23 -0
- package/lib/typescript/commonjs/cursor/pointer.d.ts.map +1 -0
- package/lib/typescript/commonjs/debug/KokoRemoteSmoke.d.ts +96 -0
- package/lib/typescript/commonjs/debug/KokoRemoteSmoke.d.ts.map +1 -0
- package/lib/typescript/commonjs/explore/ExplorationGraph.d.ts +96 -0
- package/lib/typescript/commonjs/explore/ExplorationGraph.d.ts.map +1 -0
- package/lib/typescript/commonjs/explore/bootstrapExplore.d.ts +40 -0
- package/lib/typescript/commonjs/explore/bootstrapExplore.d.ts.map +1 -0
- package/lib/typescript/commonjs/host/HostActions.d.ts +101 -0
- package/lib/typescript/commonjs/host/HostActions.d.ts.map +1 -0
- package/lib/typescript/commonjs/i18n/index.d.ts +20 -0
- package/lib/typescript/commonjs/i18n/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/i18n/runtimeMessages.d.ts +178 -0
- package/lib/typescript/commonjs/i18n/runtimeMessages.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +66 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/native/NativeBridge.d.ts +70 -0
- package/lib/typescript/commonjs/native/NativeBridge.d.ts.map +1 -0
- package/lib/typescript/commonjs/native/navigationLabel.d.ts +4 -0
- package/lib/typescript/commonjs/native/navigationLabel.d.ts.map +1 -0
- package/lib/typescript/commonjs/native/normalizeViewTree.d.ts +4 -0
- package/lib/typescript/commonjs/native/normalizeViewTree.d.ts.map +1 -0
- package/lib/typescript/commonjs/native/pruneOffscreen.d.ts +3 -0
- package/lib/typescript/commonjs/native/pruneOffscreen.d.ts.map +1 -0
- package/lib/typescript/commonjs/native/scrollViewport.d.ts +13 -0
- package/lib/typescript/commonjs/native/scrollViewport.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/privacy/redact.d.ts +9 -0
- package/lib/typescript/commonjs/privacy/redact.d.ts.map +1 -0
- package/lib/typescript/commonjs/privacy/screenEvidence.d.ts +14 -0
- package/lib/typescript/commonjs/privacy/screenEvidence.d.ts.map +1 -0
- package/lib/typescript/commonjs/privacy/screenModel.d.ts +26 -0
- package/lib/typescript/commonjs/privacy/screenModel.d.ts.map +1 -0
- package/lib/typescript/commonjs/privacy/sensitiveScreen.d.ts +8 -0
- package/lib/typescript/commonjs/privacy/sensitiveScreen.d.ts.map +1 -0
- package/lib/typescript/commonjs/privacy/userGate.d.ts +58 -0
- package/lib/typescript/commonjs/privacy/userGate.d.ts.map +1 -0
- package/lib/typescript/commonjs/protocol/actions.d.ts +7 -0
- package/lib/typescript/commonjs/protocol/actions.d.ts.map +1 -0
- package/lib/typescript/commonjs/provider/HostAppearanceStore.d.ts +64 -0
- package/lib/typescript/commonjs/provider/HostAppearanceStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/provider/KokoProvider.d.ts +39 -0
- package/lib/typescript/commonjs/provider/KokoProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/provider/KokoUiContext.d.ts +22 -0
- package/lib/typescript/commonjs/provider/KokoUiContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/selector/match.d.ts +27 -0
- package/lib/typescript/commonjs/selector/match.d.ts.map +1 -0
- package/lib/typescript/commonjs/task/TaskStore.d.ts +65 -0
- package/lib/typescript/commonjs/task/TaskStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/task/types.d.ts +66 -0
- package/lib/typescript/commonjs/task/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/task/useTaskStore.d.ts +3 -0
- package/lib/typescript/commonjs/task/useTaskStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/types.d.ts +372 -0
- package/lib/typescript/commonjs/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/KokoChatSheet.d.ts +8 -0
- package/lib/typescript/commonjs/ui/KokoChatSheet.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/KokoComposer.d.ts +13 -0
- package/lib/typescript/commonjs/ui/KokoComposer.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/KokoDialogHost.d.ts +32 -0
- package/lib/typescript/commonjs/ui/KokoDialogHost.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/KokoEntryButton.d.ts +18 -0
- package/lib/typescript/commonjs/ui/KokoEntryButton.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/KokoObserver.d.ts +13 -0
- package/lib/typescript/commonjs/ui/KokoObserver.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/KokoOverlayLayer.d.ts +35 -0
- package/lib/typescript/commonjs/ui/KokoOverlayLayer.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/KokoSubtitle.d.ts +7 -0
- package/lib/typescript/commonjs/ui/KokoSubtitle.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/KokoTaskPanel.d.ts +7 -0
- package/lib/typescript/commonjs/ui/KokoTaskPanel.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/hostOverlay.d.ts +28 -0
- package/lib/typescript/commonjs/ui/hostOverlay.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/icons.d.ts +26 -0
- package/lib/typescript/commonjs/ui/icons.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/progressChrome.d.ts +21 -0
- package/lib/typescript/commonjs/ui/progressChrome.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/safeArea.d.ts +12 -0
- package/lib/typescript/commonjs/ui/safeArea.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/useOverlayOrigin.d.ts +22 -0
- package/lib/typescript/commonjs/ui/useOverlayOrigin.d.ts.map +1 -0
- package/lib/typescript/module/KokoAgent.d.ts +167 -0
- package/lib/typescript/module/KokoAgent.d.ts.map +1 -0
- package/lib/typescript/module/assist/OnDeviceAssist.d.ts +31 -0
- package/lib/typescript/module/assist/OnDeviceAssist.d.ts.map +1 -0
- package/lib/typescript/module/assist/intentClassify.d.ts +18 -0
- package/lib/typescript/module/assist/intentClassify.d.ts.map +1 -0
- package/lib/typescript/module/assist/nodeRank.d.ts +32 -0
- package/lib/typescript/module/assist/nodeRank.d.ts.map +1 -0
- package/lib/typescript/module/assist/ocrTarget.d.ts +25 -0
- package/lib/typescript/module/assist/ocrTarget.d.ts.map +1 -0
- package/lib/typescript/module/assist/webVisualChange.d.ts +6 -0
- package/lib/typescript/module/assist/webVisualChange.d.ts.map +1 -0
- package/lib/typescript/module/client/ActionOutcomeUnknownError.d.ts +13 -0
- package/lib/typescript/module/client/ActionOutcomeUnknownError.d.ts.map +1 -0
- package/lib/typescript/module/client/AgentSession.d.ts +56 -0
- package/lib/typescript/module/client/AgentSession.d.ts.map +1 -0
- package/lib/typescript/module/client/GatewayClient.d.ts +149 -0
- package/lib/typescript/module/client/GatewayClient.d.ts.map +1 -0
- package/lib/typescript/module/client/OperationReplayGuard.d.ts +13 -0
- package/lib/typescript/module/client/OperationReplayGuard.d.ts.map +1 -0
- package/lib/typescript/module/client/RunCheckpoint.d.ts +57 -0
- package/lib/typescript/module/client/RunCheckpoint.d.ts.map +1 -0
- package/lib/typescript/module/client/loopDetect.d.ts +15 -0
- package/lib/typescript/module/client/loopDetect.d.ts.map +1 -0
- package/lib/typescript/module/client/recentSearch.d.ts +5 -0
- package/lib/typescript/module/client/recentSearch.d.ts.map +1 -0
- package/lib/typescript/module/client/walletChoiceGuard.d.ts +4 -0
- package/lib/typescript/module/client/walletChoiceGuard.d.ts.map +1 -0
- package/lib/typescript/module/client/webResultCategory.d.ts +5 -0
- package/lib/typescript/module/client/webResultCategory.d.ts.map +1 -0
- package/lib/typescript/module/commercial/AccountStore.d.ts +17 -0
- package/lib/typescript/module/commercial/AccountStore.d.ts.map +1 -0
- package/lib/typescript/module/commercial/AgentDebug.d.ts +25 -0
- package/lib/typescript/module/commercial/AgentDebug.d.ts.map +1 -0
- package/lib/typescript/module/commercial/ExecutionGuard.d.ts +18 -0
- package/lib/typescript/module/commercial/ExecutionGuard.d.ts.map +1 -0
- package/lib/typescript/module/commercial/UsageBus.d.ts +18 -0
- package/lib/typescript/module/commercial/UsageBus.d.ts.map +1 -0
- package/lib/typescript/module/commercial/branding.d.ts +25 -0
- package/lib/typescript/module/commercial/branding.d.ts.map +1 -0
- package/lib/typescript/module/commercial/devMode.d.ts +26 -0
- package/lib/typescript/module/commercial/devMode.d.ts.map +1 -0
- package/lib/typescript/module/commercial/trust.d.ts +21 -0
- package/lib/typescript/module/commercial/trust.d.ts.map +1 -0
- package/lib/typescript/module/confirmation/gate.d.ts +18 -0
- package/lib/typescript/module/confirmation/gate.d.ts.map +1 -0
- package/lib/typescript/module/cursor/CursorOverlay.d.ts +13 -0
- package/lib/typescript/module/cursor/CursorOverlay.d.ts.map +1 -0
- package/lib/typescript/module/cursor/PointerHand.d.ts +16 -0
- package/lib/typescript/module/cursor/PointerHand.d.ts.map +1 -0
- package/lib/typescript/module/cursor/controller.d.ts +30 -0
- package/lib/typescript/module/cursor/controller.d.ts.map +1 -0
- package/lib/typescript/module/cursor/pointer.d.ts +23 -0
- package/lib/typescript/module/cursor/pointer.d.ts.map +1 -0
- package/lib/typescript/module/debug/KokoRemoteSmoke.d.ts +96 -0
- package/lib/typescript/module/debug/KokoRemoteSmoke.d.ts.map +1 -0
- package/lib/typescript/module/explore/ExplorationGraph.d.ts +96 -0
- package/lib/typescript/module/explore/ExplorationGraph.d.ts.map +1 -0
- package/lib/typescript/module/explore/bootstrapExplore.d.ts +40 -0
- package/lib/typescript/module/explore/bootstrapExplore.d.ts.map +1 -0
- package/lib/typescript/module/host/HostActions.d.ts +101 -0
- package/lib/typescript/module/host/HostActions.d.ts.map +1 -0
- package/lib/typescript/module/i18n/index.d.ts +20 -0
- package/lib/typescript/module/i18n/index.d.ts.map +1 -0
- package/lib/typescript/module/i18n/runtimeMessages.d.ts +178 -0
- package/lib/typescript/module/i18n/runtimeMessages.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +66 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/native/NativeBridge.d.ts +70 -0
- package/lib/typescript/module/native/NativeBridge.d.ts.map +1 -0
- package/lib/typescript/module/native/navigationLabel.d.ts +4 -0
- package/lib/typescript/module/native/navigationLabel.d.ts.map +1 -0
- package/lib/typescript/module/native/normalizeViewTree.d.ts +4 -0
- package/lib/typescript/module/native/normalizeViewTree.d.ts.map +1 -0
- package/lib/typescript/module/native/pruneOffscreen.d.ts +3 -0
- package/lib/typescript/module/native/pruneOffscreen.d.ts.map +1 -0
- package/lib/typescript/module/native/scrollViewport.d.ts +13 -0
- package/lib/typescript/module/native/scrollViewport.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/privacy/redact.d.ts +9 -0
- package/lib/typescript/module/privacy/redact.d.ts.map +1 -0
- package/lib/typescript/module/privacy/screenEvidence.d.ts +14 -0
- package/lib/typescript/module/privacy/screenEvidence.d.ts.map +1 -0
- package/lib/typescript/module/privacy/screenModel.d.ts +26 -0
- package/lib/typescript/module/privacy/screenModel.d.ts.map +1 -0
- package/lib/typescript/module/privacy/sensitiveScreen.d.ts +8 -0
- package/lib/typescript/module/privacy/sensitiveScreen.d.ts.map +1 -0
- package/lib/typescript/module/privacy/userGate.d.ts +58 -0
- package/lib/typescript/module/privacy/userGate.d.ts.map +1 -0
- package/lib/typescript/module/protocol/actions.d.ts +7 -0
- package/lib/typescript/module/protocol/actions.d.ts.map +1 -0
- package/lib/typescript/module/provider/HostAppearanceStore.d.ts +64 -0
- package/lib/typescript/module/provider/HostAppearanceStore.d.ts.map +1 -0
- package/lib/typescript/module/provider/KokoProvider.d.ts +39 -0
- package/lib/typescript/module/provider/KokoProvider.d.ts.map +1 -0
- package/lib/typescript/module/provider/KokoUiContext.d.ts +22 -0
- package/lib/typescript/module/provider/KokoUiContext.d.ts.map +1 -0
- package/lib/typescript/module/selector/match.d.ts +27 -0
- package/lib/typescript/module/selector/match.d.ts.map +1 -0
- package/lib/typescript/module/task/TaskStore.d.ts +65 -0
- package/lib/typescript/module/task/TaskStore.d.ts.map +1 -0
- package/lib/typescript/module/task/types.d.ts +66 -0
- package/lib/typescript/module/task/types.d.ts.map +1 -0
- package/lib/typescript/module/task/useTaskStore.d.ts +3 -0
- package/lib/typescript/module/task/useTaskStore.d.ts.map +1 -0
- package/lib/typescript/module/types.d.ts +372 -0
- package/lib/typescript/module/types.d.ts.map +1 -0
- package/lib/typescript/module/ui/KokoChatSheet.d.ts +8 -0
- package/lib/typescript/module/ui/KokoChatSheet.d.ts.map +1 -0
- package/lib/typescript/module/ui/KokoComposer.d.ts +13 -0
- package/lib/typescript/module/ui/KokoComposer.d.ts.map +1 -0
- package/lib/typescript/module/ui/KokoDialogHost.d.ts +32 -0
- package/lib/typescript/module/ui/KokoDialogHost.d.ts.map +1 -0
- package/lib/typescript/module/ui/KokoEntryButton.d.ts +18 -0
- package/lib/typescript/module/ui/KokoEntryButton.d.ts.map +1 -0
- package/lib/typescript/module/ui/KokoObserver.d.ts +13 -0
- package/lib/typescript/module/ui/KokoObserver.d.ts.map +1 -0
- package/lib/typescript/module/ui/KokoOverlayLayer.d.ts +35 -0
- package/lib/typescript/module/ui/KokoOverlayLayer.d.ts.map +1 -0
- package/lib/typescript/module/ui/KokoSubtitle.d.ts +7 -0
- package/lib/typescript/module/ui/KokoSubtitle.d.ts.map +1 -0
- package/lib/typescript/module/ui/KokoTaskPanel.d.ts +7 -0
- package/lib/typescript/module/ui/KokoTaskPanel.d.ts.map +1 -0
- package/lib/typescript/module/ui/hostOverlay.d.ts +28 -0
- package/lib/typescript/module/ui/hostOverlay.d.ts.map +1 -0
- package/lib/typescript/module/ui/icons.d.ts +26 -0
- package/lib/typescript/module/ui/icons.d.ts.map +1 -0
- package/lib/typescript/module/ui/progressChrome.d.ts +21 -0
- package/lib/typescript/module/ui/progressChrome.d.ts.map +1 -0
- package/lib/typescript/module/ui/safeArea.d.ts +12 -0
- package/lib/typescript/module/ui/safeArea.d.ts.map +1 -0
- package/lib/typescript/module/ui/useOverlayOrigin.d.ts +22 -0
- package/lib/typescript/module/ui/useOverlayOrigin.d.ts.map +1 -0
- package/package.json +153 -0
- package/react-native.config.js +12 -0
- package/src/KokoAgent.ts +1415 -0
- package/src/assist/OnDeviceAssist.ts +133 -0
- package/src/assist/intentClassify.ts +122 -0
- package/src/assist/nodeRank.ts +167 -0
- package/src/assist/ocrTarget.ts +146 -0
- package/src/assist/webVisualChange.ts +24 -0
- package/src/client/ActionOutcomeUnknownError.ts +18 -0
- package/src/client/AgentSession.ts +952 -0
- package/src/client/GatewayClient.ts +439 -0
- package/src/client/OperationReplayGuard.ts +61 -0
- package/src/client/RunCheckpoint.ts +154 -0
- package/src/client/loopDetect.ts +213 -0
- package/src/client/recentSearch.ts +47 -0
- package/src/client/walletChoiceGuard.ts +15 -0
- package/src/client/webResultCategory.ts +28 -0
- package/src/commercial/AccountStore.ts +85 -0
- package/src/commercial/AgentDebug.ts +142 -0
- package/src/commercial/ExecutionGuard.ts +67 -0
- package/src/commercial/UsageBus.ts +44 -0
- package/src/commercial/branding.ts +97 -0
- package/src/commercial/devMode.ts +48 -0
- package/src/commercial/trust.ts +67 -0
- package/src/confirmation/gate.ts +82 -0
- package/src/cursor/CursorOverlay.tsx +138 -0
- package/src/cursor/PointerHand.tsx +49 -0
- package/src/cursor/controller.ts +98 -0
- package/src/cursor/pointer.ts +40 -0
- package/src/debug/KokoRemoteSmoke.tsx +561 -0
- package/src/explore/ExplorationGraph.ts +518 -0
- package/src/explore/bootstrapExplore.ts +89 -0
- package/src/host/HostActions.ts +349 -0
- package/src/i18n/index.ts +229 -0
- package/src/i18n/runtimeMessages.ts +180 -0
- package/src/index.ts +203 -0
- package/src/native/NativeBridge.ts +207 -0
- package/src/native/navigationLabel.ts +11 -0
- package/src/native/normalizeViewTree.ts +16 -0
- package/src/native/pruneOffscreen.ts +72 -0
- package/src/native/scrollViewport.ts +51 -0
- package/src/privacy/redact.ts +115 -0
- package/src/privacy/screenEvidence.ts +55 -0
- package/src/privacy/screenModel.ts +504 -0
- package/src/privacy/sensitiveScreen.ts +55 -0
- package/src/privacy/userGate.ts +233 -0
- package/src/protocol/actions.ts +66 -0
- package/src/provider/HostAppearanceStore.ts +148 -0
- package/src/provider/KokoProvider.tsx +118 -0
- package/src/provider/KokoUiContext.tsx +162 -0
- package/src/selector/match.ts +417 -0
- package/src/task/TaskStore.ts +387 -0
- package/src/task/types.ts +82 -0
- package/src/task/useTaskStore.ts +9 -0
- package/src/types.ts +318 -0
- package/src/ui/KokoChatSheet.tsx +930 -0
- package/src/ui/KokoComposer.tsx +174 -0
- package/src/ui/KokoDialogHost.tsx +249 -0
- package/src/ui/KokoEntryButton.tsx +74 -0
- package/src/ui/KokoObserver.tsx +587 -0
- package/src/ui/KokoOverlayLayer.tsx +53 -0
- package/src/ui/KokoSubtitle.tsx +80 -0
- package/src/ui/KokoTaskPanel.tsx +299 -0
- package/src/ui/hostOverlay.tsx +148 -0
- package/src/ui/icons.tsx +145 -0
- package/src/ui/progressChrome.ts +73 -0
- package/src/ui/safeArea.ts +95 -0
- package/src/ui/useOverlayOrigin.ts +29 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* On-device exploration graph — screen fingerprints + labeled transitions.
|
|
3
|
+
* No host feature catalog required. Persist best-effort (AsyncStorage if present).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type ExploreNode = {
|
|
7
|
+
id: string;
|
|
8
|
+
/** Compact affordance labels used for matching. */
|
|
9
|
+
labels: string[];
|
|
10
|
+
fingerprint: string;
|
|
11
|
+
seenAt: number;
|
|
12
|
+
visitCount: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type ExploreEdge = {
|
|
16
|
+
id: string;
|
|
17
|
+
fromId: string;
|
|
18
|
+
toId: string;
|
|
19
|
+
/** Tap / host label that caused the transition. */
|
|
20
|
+
label: string;
|
|
21
|
+
count: number;
|
|
22
|
+
lastAt: number;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type ExplorationGraphSnapshot = {
|
|
26
|
+
version: 1;
|
|
27
|
+
appKey: string;
|
|
28
|
+
updatedAt: number;
|
|
29
|
+
nodes: ExploreNode[];
|
|
30
|
+
edges: ExploreEdge[];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type PathStep = {
|
|
34
|
+
fromId: string;
|
|
35
|
+
toId: string;
|
|
36
|
+
label: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const STORAGE_KEY_PREFIX = '@koko/exploration-graph/v1/';
|
|
40
|
+
|
|
41
|
+
function stableHash(parts: string[]): string {
|
|
42
|
+
// FNV-1a 32-bit — good enough for local fingerprints.
|
|
43
|
+
let h = 0x811c9dc5;
|
|
44
|
+
const s = parts.join('\u0001');
|
|
45
|
+
for (let i = 0; i < s.length; i++) {
|
|
46
|
+
h ^= s.charCodeAt(i);
|
|
47
|
+
h = Math.imul(h, 0x01000193);
|
|
48
|
+
}
|
|
49
|
+
return (h >>> 0).toString(16).padStart(8, '0');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Normalize labels for graph identity (locale-ish noise trimmed). */
|
|
53
|
+
export function normalizeExploreLabel(label: string): string {
|
|
54
|
+
return String(label || '')
|
|
55
|
+
.replace(/\s+/g, ' ')
|
|
56
|
+
.trim()
|
|
57
|
+
.slice(0, 64);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Cross-locale synonyms for explore edge labels.
|
|
62
|
+
* Stale graphs often store JP「環境設定」while the live UI shows「偏好设置」.
|
|
63
|
+
*/
|
|
64
|
+
const EXPLORE_LABEL_GROUPS: string[][] = [
|
|
65
|
+
['偏好设置', '偏好設定', '環境設定', 'Preferences', '偏好'],
|
|
66
|
+
['设置', '設定', 'Settings'],
|
|
67
|
+
['语言', '語言', 'Language', '言語'],
|
|
68
|
+
['主题', 'Theme', 'テーマ', '外观'],
|
|
69
|
+
['更多', '选项', '選項', 'More', 'Options', 'オプション'],
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
/** All synonym spellings for an explore / affordance label. */
|
|
73
|
+
export function exploreLabelSynonyms(label: string): string[] {
|
|
74
|
+
const n = normalizeExploreLabel(label);
|
|
75
|
+
if (!n) return [];
|
|
76
|
+
const lower = n.toLowerCase();
|
|
77
|
+
for (const group of EXPLORE_LABEL_GROUPS) {
|
|
78
|
+
if (
|
|
79
|
+
group.some((g) => {
|
|
80
|
+
const ng = normalizeExploreLabel(g);
|
|
81
|
+
return ng === n || ng.toLowerCase() === lower;
|
|
82
|
+
})
|
|
83
|
+
) {
|
|
84
|
+
return [...new Set(group.map(normalizeExploreLabel))];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return [n];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Map a historical explore tap label onto a label currently on screen
|
|
92
|
+
* (exact / synonym). Returns null when nothing matches.
|
|
93
|
+
*/
|
|
94
|
+
export function resolveExploreLabelOnScreen(
|
|
95
|
+
desired: string,
|
|
96
|
+
available: string[],
|
|
97
|
+
): string | null {
|
|
98
|
+
if (!desired || !available.length) return null;
|
|
99
|
+
const syns = exploreLabelSynonyms(desired);
|
|
100
|
+
const pairs = available.map((raw) => ({
|
|
101
|
+
raw,
|
|
102
|
+
norm: normalizeExploreLabel(raw),
|
|
103
|
+
}));
|
|
104
|
+
for (const s of syns) {
|
|
105
|
+
const hit = pairs.find(
|
|
106
|
+
(p) => p.norm === s || p.norm.toLowerCase() === s.toLowerCase(),
|
|
107
|
+
);
|
|
108
|
+
if (hit) return hit.raw;
|
|
109
|
+
}
|
|
110
|
+
for (const s of syns) {
|
|
111
|
+
if (s.length < 2) continue;
|
|
112
|
+
const hit = pairs.find(
|
|
113
|
+
(p) => p.norm.includes(s) || s.includes(p.norm),
|
|
114
|
+
);
|
|
115
|
+
if (hit) return hit.raw;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Fingerprint a screen from affordance labels (order-insensitive top-N).
|
|
122
|
+
*/
|
|
123
|
+
export function fingerprintFromLabels(labels: string[], max = 16): string {
|
|
124
|
+
const norm = [
|
|
125
|
+
...new Set(
|
|
126
|
+
labels
|
|
127
|
+
.map(normalizeExploreLabel)
|
|
128
|
+
.filter((l) => l.length >= 1 && l.length <= 40),
|
|
129
|
+
),
|
|
130
|
+
]
|
|
131
|
+
.sort((a, b) => a.localeCompare(b))
|
|
132
|
+
.slice(0, max);
|
|
133
|
+
return stableHash(norm.length ? norm : ['(empty)']);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function edgeId(fromId: string, label: string, toId: string): string {
|
|
137
|
+
return `${fromId}|${normalizeExploreLabel(label)}|${toId}`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
type AsyncStorageLike = {
|
|
141
|
+
getItem(key: string): Promise<string | null>;
|
|
142
|
+
setItem(key: string, value: string): Promise<void>;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
function tryAsyncStorage(): AsyncStorageLike | null {
|
|
146
|
+
try {
|
|
147
|
+
// Optional peer — many RN hosts already ship it.
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
149
|
+
const mod = require('@react-native-async-storage/async-storage');
|
|
150
|
+
const store = mod?.default ?? mod;
|
|
151
|
+
if (store && typeof store.getItem === 'function') return store;
|
|
152
|
+
} catch {
|
|
153
|
+
// optional
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export class ExplorationGraphStore {
|
|
159
|
+
private appKey = 'default';
|
|
160
|
+
private nodes = new Map<string, ExploreNode>();
|
|
161
|
+
private edges = new Map<string, ExploreEdge>();
|
|
162
|
+
private loaded = false;
|
|
163
|
+
private saveTimer: ReturnType<typeof setTimeout> | null = null;
|
|
164
|
+
|
|
165
|
+
setAppKey(appKey: string) {
|
|
166
|
+
const next = String(appKey || 'default').trim() || 'default';
|
|
167
|
+
if (next === this.appKey && this.loaded) return;
|
|
168
|
+
if (next !== this.appKey) {
|
|
169
|
+
this.nodes.clear();
|
|
170
|
+
this.edges.clear();
|
|
171
|
+
this.loaded = false;
|
|
172
|
+
}
|
|
173
|
+
this.appKey = next;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
getAppKey() {
|
|
177
|
+
return this.appKey;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async ensureLoaded() {
|
|
181
|
+
if (this.loaded) return;
|
|
182
|
+
this.loaded = true;
|
|
183
|
+
const storage = tryAsyncStorage();
|
|
184
|
+
if (!storage) return;
|
|
185
|
+
try {
|
|
186
|
+
const raw = await storage.getItem(STORAGE_KEY_PREFIX + this.appKey);
|
|
187
|
+
if (!raw) return;
|
|
188
|
+
const snap = JSON.parse(raw) as ExplorationGraphSnapshot;
|
|
189
|
+
if (snap?.version !== 1 || !Array.isArray(snap.nodes)) return;
|
|
190
|
+
for (const n of snap.nodes) this.nodes.set(n.id, n);
|
|
191
|
+
for (const e of snap.edges || []) this.edges.set(e.id, e);
|
|
192
|
+
} catch {
|
|
193
|
+
// corrupt — start fresh
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private scheduleSave() {
|
|
198
|
+
if (this.saveTimer) clearTimeout(this.saveTimer);
|
|
199
|
+
this.saveTimer = setTimeout(() => {
|
|
200
|
+
this.saveTimer = null;
|
|
201
|
+
void this.persist();
|
|
202
|
+
}, 400);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async persist() {
|
|
206
|
+
const storage = tryAsyncStorage();
|
|
207
|
+
if (!storage) return;
|
|
208
|
+
try {
|
|
209
|
+
const snap = this.snapshot();
|
|
210
|
+
await storage.setItem(
|
|
211
|
+
STORAGE_KEY_PREFIX + this.appKey,
|
|
212
|
+
JSON.stringify(snap),
|
|
213
|
+
);
|
|
214
|
+
} catch {
|
|
215
|
+
// ignore quota / unavailable
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
snapshot(): ExplorationGraphSnapshot {
|
|
220
|
+
return {
|
|
221
|
+
version: 1,
|
|
222
|
+
appKey: this.appKey,
|
|
223
|
+
updatedAt: Date.now(),
|
|
224
|
+
nodes: [...this.nodes.values()],
|
|
225
|
+
edges: [...this.edges.values()],
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
clear() {
|
|
230
|
+
this.nodes.clear();
|
|
231
|
+
this.edges.clear();
|
|
232
|
+
// Persist immediately so a stale debounce cannot resurrect old edges.
|
|
233
|
+
if (this.saveTimer) {
|
|
234
|
+
clearTimeout(this.saveTimer);
|
|
235
|
+
this.saveTimer = null;
|
|
236
|
+
}
|
|
237
|
+
void this.persist();
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** Upsert a screen node; returns node id (= fingerprint). */
|
|
241
|
+
observeScreen(labels: string[]): ExploreNode {
|
|
242
|
+
const clean = labels
|
|
243
|
+
.map(normalizeExploreLabel)
|
|
244
|
+
.filter(
|
|
245
|
+
(l) =>
|
|
246
|
+
l &&
|
|
247
|
+
!/Open debugger|view warnings|^!,/i.test(l) &&
|
|
248
|
+
!/^LogBox/i.test(l),
|
|
249
|
+
);
|
|
250
|
+
// Empty dumps are transient overlays — still fingerprint, but don't
|
|
251
|
+
// inflate visit noise by merging junk labels into an existing rich node.
|
|
252
|
+
const id = fingerprintFromLabels(clean);
|
|
253
|
+
const prev = this.nodes.get(id);
|
|
254
|
+
const node: ExploreNode = {
|
|
255
|
+
id,
|
|
256
|
+
labels:
|
|
257
|
+
clean.length > 0
|
|
258
|
+
? clean.slice(0, 24)
|
|
259
|
+
: prev?.labels?.length
|
|
260
|
+
? prev.labels
|
|
261
|
+
: [],
|
|
262
|
+
fingerprint: id,
|
|
263
|
+
seenAt: Date.now(),
|
|
264
|
+
visitCount: (prev?.visitCount ?? 0) + 1,
|
|
265
|
+
};
|
|
266
|
+
this.nodes.set(id, node);
|
|
267
|
+
this.scheduleSave();
|
|
268
|
+
return node;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Record a transition after a tap. No-op if screen did not change.
|
|
273
|
+
*/
|
|
274
|
+
recordTransition(fromLabels: string[], label: string, toLabels: string[]) {
|
|
275
|
+
const from = this.observeScreen(fromLabels);
|
|
276
|
+
const to = this.observeScreen(toLabels);
|
|
277
|
+
const action = normalizeExploreLabel(label);
|
|
278
|
+
if (!action || from.id === to.id) return null;
|
|
279
|
+
const id = edgeId(from.id, action, to.id);
|
|
280
|
+
const prev = this.edges.get(id);
|
|
281
|
+
const edge: ExploreEdge = {
|
|
282
|
+
id,
|
|
283
|
+
fromId: from.id,
|
|
284
|
+
toId: to.id,
|
|
285
|
+
label: action,
|
|
286
|
+
count: (prev?.count ?? 0) + 1,
|
|
287
|
+
lastAt: Date.now(),
|
|
288
|
+
};
|
|
289
|
+
this.edges.set(id, edge);
|
|
290
|
+
this.scheduleSave();
|
|
291
|
+
return edge;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/** Nodes whose labels match any of the query tokens. */
|
|
295
|
+
findNodesMatching(tokens: string[]): ExploreNode[] {
|
|
296
|
+
const toks = tokens
|
|
297
|
+
.map((t) => normalizeExploreLabel(t).toLowerCase())
|
|
298
|
+
.filter((t) => t.length >= 2);
|
|
299
|
+
if (!toks.length) return [];
|
|
300
|
+
const hits: ExploreNode[] = [];
|
|
301
|
+
for (const n of this.nodes.values()) {
|
|
302
|
+
const blob = n.labels.join('\n').toLowerCase();
|
|
303
|
+
if (toks.some((t) => blob.includes(t))) hits.push(n);
|
|
304
|
+
}
|
|
305
|
+
return hits.sort((a, b) => b.visitCount - a.visitCount);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* BFS shortest path of tap labels from current fingerprint toward any
|
|
310
|
+
* node matching goal tokens.
|
|
311
|
+
*/
|
|
312
|
+
findPathToGoal(
|
|
313
|
+
fromLabels: string[],
|
|
314
|
+
goalTokens: string[],
|
|
315
|
+
maxDepth = 6,
|
|
316
|
+
): PathStep[] | null {
|
|
317
|
+
const fromId = fingerprintFromLabels(fromLabels);
|
|
318
|
+
// Prefer nodes matching the most *specific* tokens (语言 > 偏好 > 设置).
|
|
319
|
+
const tokenWeight = (t: string) => {
|
|
320
|
+
if (/语言|語言|language|locale/i.test(t)) return 4;
|
|
321
|
+
if (/偏好|preferences/i.test(t)) return 2;
|
|
322
|
+
if (/设置|設定|settings/i.test(t)) return 1;
|
|
323
|
+
return 1;
|
|
324
|
+
};
|
|
325
|
+
const scored = [...this.nodes.values()]
|
|
326
|
+
.map((n) => {
|
|
327
|
+
const blob = n.labels.join('\n').toLowerCase();
|
|
328
|
+
let score = 0;
|
|
329
|
+
for (const t of goalTokens) {
|
|
330
|
+
if (blob.includes(t.toLowerCase())) score += tokenWeight(t);
|
|
331
|
+
}
|
|
332
|
+
return { n, score };
|
|
333
|
+
})
|
|
334
|
+
.filter((x) => x.score > 0)
|
|
335
|
+
.sort((a, b) => b.score - a.score || b.n.visitCount - a.n.visitCount);
|
|
336
|
+
if (!scored.length) return null;
|
|
337
|
+
// If the goal cares about language, prefer screens that literally show it
|
|
338
|
+
// over parent menus that only mention 偏好/设置.
|
|
339
|
+
const wantsLanguage = goalTokens.some((t) =>
|
|
340
|
+
/语言|語言|language|locale/i.test(t),
|
|
341
|
+
);
|
|
342
|
+
const languageHits = wantsLanguage
|
|
343
|
+
? scored.filter((x) =>
|
|
344
|
+
x.n.labels.some((l) => /语言|語言|language|locale/i.test(l)),
|
|
345
|
+
)
|
|
346
|
+
: [];
|
|
347
|
+
// A specific goal that no explored screen actually satisfies must not fall
|
|
348
|
+
// back to screens that merely scored on an incidental token: the caller
|
|
349
|
+
// walks this path blindly, so a confident wrong answer costs real taps and
|
|
350
|
+
// can strand the App somewhere worse than where it started. Say "no path"
|
|
351
|
+
// and let the planner read the current screen instead.
|
|
352
|
+
if (wantsLanguage && !languageHits.length) return null;
|
|
353
|
+
const pool = languageHits.length ? languageHits : scored;
|
|
354
|
+
const best = pool[0]!.score;
|
|
355
|
+
const targets = new Set(
|
|
356
|
+
pool.filter((x) => x.score === best).map((x) => x.n.id),
|
|
357
|
+
);
|
|
358
|
+
if (targets.has(fromId)) return [];
|
|
359
|
+
|
|
360
|
+
const adj = new Map<string, ExploreEdge[]>();
|
|
361
|
+
for (const e of this.edges.values()) {
|
|
362
|
+
const list = adj.get(e.fromId) ?? [];
|
|
363
|
+
list.push(e);
|
|
364
|
+
adj.set(e.fromId, list);
|
|
365
|
+
}
|
|
366
|
+
for (const list of adj.values()) {
|
|
367
|
+
list.sort((a, b) => b.count - a.count);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const queue: Array<{ id: string; path: PathStep[] }> = [
|
|
371
|
+
{ id: fromId, path: [] },
|
|
372
|
+
];
|
|
373
|
+
const seen = new Set<string>([fromId]);
|
|
374
|
+
while (queue.length) {
|
|
375
|
+
const cur = queue.shift()!;
|
|
376
|
+
if (cur.path.length >= maxDepth) continue;
|
|
377
|
+
const outs = adj.get(cur.id) ?? [];
|
|
378
|
+
// First hop must be tappable on the live screen (or a synonym of one).
|
|
379
|
+
for (const e of outs) {
|
|
380
|
+
if (seen.has(e.toId)) continue;
|
|
381
|
+
if (
|
|
382
|
+
cur.path.length === 0 &&
|
|
383
|
+
!resolveExploreLabelOnScreen(e.label, fromLabels)
|
|
384
|
+
) {
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
const nextPath = [
|
|
388
|
+
...cur.path,
|
|
389
|
+
{ fromId: e.fromId, toId: e.toId, label: e.label },
|
|
390
|
+
];
|
|
391
|
+
if (targets.has(e.toId)) return nextPath;
|
|
392
|
+
seen.add(e.toId);
|
|
393
|
+
queue.push({ id: e.toId, path: nextPath });
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Soft hints for the planner: known outgoing labels from current screen
|
|
401
|
+
* that historically led toward goal-matching screens.
|
|
402
|
+
*/
|
|
403
|
+
hintLabelsTowardGoal(fromLabels: string[], goalTokens: string[], limit = 6): string[] {
|
|
404
|
+
const path = this.findPathToGoal(fromLabels, goalTokens, 6);
|
|
405
|
+
if (path?.length) {
|
|
406
|
+
return [...new Set(path.map((p) => p.label))].slice(0, limit);
|
|
407
|
+
}
|
|
408
|
+
// Fallback: any edge label that appears on a goal-matching node as well.
|
|
409
|
+
const goalNodes = this.findNodesMatching(goalTokens);
|
|
410
|
+
if (!goalNodes.length) return [];
|
|
411
|
+
const goalIds = new Set(goalNodes.map((n) => n.id));
|
|
412
|
+
const fromId = fingerprintFromLabels(fromLabels);
|
|
413
|
+
const labels: string[] = [];
|
|
414
|
+
for (const e of this.edges.values()) {
|
|
415
|
+
if (e.fromId === fromId && goalIds.has(e.toId)) labels.push(e.label);
|
|
416
|
+
}
|
|
417
|
+
// Also surface labels that appear ON goal screens (what to look for).
|
|
418
|
+
for (const n of goalNodes.slice(0, 3)) {
|
|
419
|
+
for (const l of n.labels.slice(0, 8)) {
|
|
420
|
+
if (goalTokens.some((t) => l.toLowerCase().includes(t.toLowerCase()))) {
|
|
421
|
+
labels.push(l);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return [...new Set(labels)].slice(0, limit);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
stats() {
|
|
429
|
+
return {
|
|
430
|
+
nodes: this.nodes.size,
|
|
431
|
+
edges: this.edges.size,
|
|
432
|
+
appKey: this.appKey,
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
export const ExplorationGraph = new ExplorationGraphStore();
|
|
438
|
+
|
|
439
|
+
/** Extract goal tokens for graph search (structural NL bits). */
|
|
440
|
+
export function goalTokensForExplore(goal: string): string[] {
|
|
441
|
+
return goalExploreQuery(goal).allTokens;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Split explore query into destination tokens vs broader keywords.
|
|
446
|
+
* E.g. 「设置语言」targets 语言 screens, not every screen that merely says 设置.
|
|
447
|
+
*/
|
|
448
|
+
export function goalExploreQuery(goal: string): {
|
|
449
|
+
targetTokens: string[];
|
|
450
|
+
allTokens: string[];
|
|
451
|
+
} {
|
|
452
|
+
const g = String(goal || '').trim();
|
|
453
|
+
const all: string[] = [];
|
|
454
|
+
const add = (list: string[], s: string) => {
|
|
455
|
+
const t = normalizeExploreLabel(s);
|
|
456
|
+
if (t.length >= 2) list.push(t);
|
|
457
|
+
};
|
|
458
|
+
const targetTokens: string[] = [];
|
|
459
|
+
if (/语言|語言|language|locale|言語/i.test(g)) {
|
|
460
|
+
add(targetTokens, '语言');
|
|
461
|
+
add(targetTokens, 'Language');
|
|
462
|
+
add(targetTokens, '言語');
|
|
463
|
+
add(targetTokens, 'locale');
|
|
464
|
+
// Preferences screens usually host the language control.
|
|
465
|
+
add(targetTokens, '偏好');
|
|
466
|
+
add(targetTokens, 'Preferences');
|
|
467
|
+
add(targetTokens, '偏好设置');
|
|
468
|
+
add(targetTokens, '環境設定');
|
|
469
|
+
} else if (/主题|theme|テーマ/i.test(g)) {
|
|
470
|
+
add(targetTokens, '主题');
|
|
471
|
+
add(targetTokens, 'Theme');
|
|
472
|
+
add(targetTokens, 'テーマ');
|
|
473
|
+
} else if (/偏好|preferences|環境設定/i.test(g)) {
|
|
474
|
+
add(targetTokens, '偏好');
|
|
475
|
+
add(targetTokens, 'Preferences');
|
|
476
|
+
add(targetTokens, '環境設定');
|
|
477
|
+
} else if (/设置|設定|settings/i.test(g)) {
|
|
478
|
+
add(targetTokens, '设置');
|
|
479
|
+
add(targetTokens, 'Settings');
|
|
480
|
+
add(targetTokens, '設定');
|
|
481
|
+
}
|
|
482
|
+
for (const t of targetTokens) add(all, t);
|
|
483
|
+
if (/设置|設定|settings/i.test(g)) {
|
|
484
|
+
add(all, '设置');
|
|
485
|
+
add(all, 'Settings');
|
|
486
|
+
add(all, '設定');
|
|
487
|
+
}
|
|
488
|
+
if (/偏好|preferences|環境設定/i.test(g)) {
|
|
489
|
+
add(all, '偏好');
|
|
490
|
+
add(all, 'Preferences');
|
|
491
|
+
add(all, '環境設定');
|
|
492
|
+
}
|
|
493
|
+
if (/更多|选项|More|Options|オプション|選項/i.test(g)) {
|
|
494
|
+
add(all, '更多');
|
|
495
|
+
add(all, '选项');
|
|
496
|
+
add(all, 'オプション');
|
|
497
|
+
}
|
|
498
|
+
const stripped = g
|
|
499
|
+
.replace(
|
|
500
|
+
/^(请|帮我|帮忙|麻烦|我想|我要|打开|进入|点击|点|切换|设置|把)/g,
|
|
501
|
+
'',
|
|
502
|
+
)
|
|
503
|
+
.replace(/一下|这个|那个/g, '');
|
|
504
|
+
for (const m of stripped.match(/[\u4e00-\u9fff]{2,8}|[A-Za-z]{3,16}/g) ?? []) {
|
|
505
|
+
add(all, m);
|
|
506
|
+
}
|
|
507
|
+
const uniq = (xs: string[]) => [...new Set(xs)].slice(0, 12);
|
|
508
|
+
const targets = uniq(targetTokens);
|
|
509
|
+
return {
|
|
510
|
+
targetTokens: targets.length ? targets : uniq(all),
|
|
511
|
+
allTokens: uniq(all),
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
export function exploreHintsModelText(hints: string[]): string {
|
|
516
|
+
if (!hints.length) return '';
|
|
517
|
+
return `- [explore] 本机探索图建议优先尝试:${hints.map((h) => `「${h}」`).join(' → ')}(非强制;以当前 dump 为准)`;
|
|
518
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/** Capture the current public screen as local exploration metadata. */
|
|
2
|
+
import type { KokoAgent } from '../KokoAgent';
|
|
3
|
+
import { extractAffordances } from '../privacy/screenModel';
|
|
4
|
+
import { redactOutbound } from '../privacy/redact';
|
|
5
|
+
import { detectAppUserGate } from '../privacy/userGate';
|
|
6
|
+
import { findNodeById } from '../selector/match';
|
|
7
|
+
import type { ViewNode } from '../types';
|
|
8
|
+
import { ExplorationGraph, normalizeExploreLabel, type ExplorationGraphSnapshot } from './ExplorationGraph';
|
|
9
|
+
|
|
10
|
+
export type BootstrapExploreOptions = {
|
|
11
|
+
/** @deprecated Exploration only observes the current screen; no crawling. */
|
|
12
|
+
mode?: 'full' | 'quick';
|
|
13
|
+
/** @deprecated No actions are executed. */
|
|
14
|
+
maxSteps?: number;
|
|
15
|
+
/** @deprecated Only the current screen is observed. */
|
|
16
|
+
maxScreens?: number;
|
|
17
|
+
/** @deprecated There are no candidate actions to prioritize. */
|
|
18
|
+
priorityPatterns?: RegExp[];
|
|
19
|
+
/** @deprecated There are no candidate actions to skip. */
|
|
20
|
+
skipPatterns?: RegExp[];
|
|
21
|
+
/** @deprecated No action progress events are emitted. */
|
|
22
|
+
onProgress?: (info: {
|
|
23
|
+
step: number;
|
|
24
|
+
label: string;
|
|
25
|
+
nodes: number;
|
|
26
|
+
edges: number;
|
|
27
|
+
depth: number;
|
|
28
|
+
}) => void;
|
|
29
|
+
/** App key for local graph persistence (bundle id / flavor). */
|
|
30
|
+
appKey?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type BootstrapExploreResult = {
|
|
34
|
+
success: boolean;
|
|
35
|
+
/** Always zero: observation never moves or operates the host. */
|
|
36
|
+
steps: number;
|
|
37
|
+
summary: string;
|
|
38
|
+
graph: ExplorationGraphSnapshot;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Compatibility entry point for read-only observation. Uses the caller's
|
|
43
|
+
* existing dump permission; never mints a permit, starts a task, navigates,
|
|
44
|
+
* changes LogBox settings or invokes host callbacks. Graphs are soft hints,
|
|
45
|
+
* and never constitute permission to execute a historical transition.
|
|
46
|
+
*/
|
|
47
|
+
export async function bootstrapExplore(
|
|
48
|
+
agent: KokoAgent,
|
|
49
|
+
opts: BootstrapExploreOptions = {},
|
|
50
|
+
): Promise<BootstrapExploreResult> {
|
|
51
|
+
const failure = (summary: string): BootstrapExploreResult => ({
|
|
52
|
+
success: false, steps: 0, summary, graph: ExplorationGraph.snapshot(),
|
|
53
|
+
});
|
|
54
|
+
try {
|
|
55
|
+
// dump() enforces the current execution permission. A failed read must not
|
|
56
|
+
// be turned into a blind dismiss, a synthetic tap or a local permit.
|
|
57
|
+
const tree = await agent.dump({ silent: true });
|
|
58
|
+
if (detectAppUserGate(tree)) return failure('Current screen requires user input; no exploration data was recorded.');
|
|
59
|
+
// Field values and read-only body copy do not belong in persistent maps.
|
|
60
|
+
const hasIndependentInputOrAction = (node: ViewNode): boolean => node.children.some(child =>
|
|
61
|
+
child.clickable || /textfield|textinput|edittext|textview|textarea/i.test(child.type) ||
|
|
62
|
+
hasIndependentInputOrAction(child));
|
|
63
|
+
const labels = [...new Set(extractAffordances(tree, 80)
|
|
64
|
+
.filter(action => action.kind !== 'field')
|
|
65
|
+
.filter(action => {
|
|
66
|
+
const target = findNodeById(tree, action.nodeId);
|
|
67
|
+
// Aggregate keyboard-dismiss/root wrappers can contain a field's
|
|
68
|
+
// current value; they are not standalone public control labels.
|
|
69
|
+
return target && !(target === tree && target.children.length) && !hasIndependentInputOrAction(target);
|
|
70
|
+
})
|
|
71
|
+
.map(action => normalizeExploreLabel(redactOutbound(action.label, tree)))
|
|
72
|
+
.filter(Boolean))];
|
|
73
|
+
if (!labels.length) return failure('No public controls were identified on the current screen.');
|
|
74
|
+
if (opts.appKey) ExplorationGraph.setAppKey(opts.appKey);
|
|
75
|
+
await ExplorationGraph.ensureLoaded();
|
|
76
|
+
ExplorationGraph.observeScreen(labels);
|
|
77
|
+
await ExplorationGraph.persist();
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
steps: 0,
|
|
81
|
+
summary: 'Observed the current public screen without performing any actions.',
|
|
82
|
+
graph: ExplorationGraph.snapshot(),
|
|
83
|
+
};
|
|
84
|
+
} catch {
|
|
85
|
+
// Native / host errors may contain field values. Do not copy them into a
|
|
86
|
+
// returned graph, task history or progress message.
|
|
87
|
+
return failure('Unable to read the current screen with the existing execution permission.');
|
|
88
|
+
}
|
|
89
|
+
}
|