@beeos-ai/device-agent 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.pi/extensions/android-tools.ts +139 -0
- package/.pi/skills/.gitkeep +0 -0
- package/.pi/skills/ground-mobile-fallback/SKILL.md +50 -0
- package/LICENSE +201 -0
- package/dist/action/handler.d.ts +9 -0
- package/dist/action/handler.js +124 -0
- package/dist/action/handler.js.map +1 -0
- package/dist/adapters/agent-gateway-client.d.ts +256 -0
- package/dist/adapters/agent-gateway-client.js +332 -0
- package/dist/adapters/agent-gateway-client.js.map +1 -0
- package/dist/adapters/agentcore-inner-loop.d.ts +29 -0
- package/dist/adapters/agentcore-inner-loop.js +72 -0
- package/dist/adapters/agentcore-inner-loop.js.map +1 -0
- package/dist/adapters/agentcore-pi.d.ts +215 -0
- package/dist/adapters/agentcore-pi.js +464 -0
- package/dist/adapters/agentcore-pi.js.map +1 -0
- package/dist/adapters/agentcore-runner.d.ts +70 -0
- package/dist/adapters/agentcore-runner.js +255 -0
- package/dist/adapters/agentcore-runner.js.map +1 -0
- package/dist/adapters/device-android-adb.d.ts +41 -0
- package/dist/adapters/device-android-adb.js +279 -0
- package/dist/adapters/device-android-adb.js.map +1 -0
- package/dist/adapters/device-desktop.d.ts +37 -0
- package/dist/adapters/device-desktop.js +101 -0
- package/dist/adapters/device-desktop.js.map +1 -0
- package/dist/adapters/identity-file.d.ts +30 -0
- package/dist/adapters/identity-file.js +50 -0
- package/dist/adapters/identity-file.js.map +1 -0
- package/dist/adapters/transport-bridge-ws.d.ts +39 -0
- package/dist/adapters/transport-bridge-ws.js +49 -0
- package/dist/adapters/transport-bridge-ws.js.map +1 -0
- package/dist/adapters/vlm-inner-loop.d.ts +88 -0
- package/dist/adapters/vlm-inner-loop.js +199 -0
- package/dist/adapters/vlm-inner-loop.js.map +1 -0
- package/dist/agent-runtime/adapters/base.d.ts +145 -0
- package/dist/agent-runtime/adapters/base.js +29 -0
- package/dist/agent-runtime/adapters/base.js.map +1 -0
- package/dist/agent-runtime/adapters/index.d.ts +17 -0
- package/dist/agent-runtime/adapters/index.js +17 -0
- package/dist/agent-runtime/adapters/index.js.map +1 -0
- package/dist/agent-runtime/adapters/mock.d.ts +44 -0
- package/dist/agent-runtime/adapters/mock.js +54 -0
- package/dist/agent-runtime/adapters/mock.js.map +1 -0
- package/dist/agent-runtime/adapters/openai.d.ts +63 -0
- package/dist/agent-runtime/adapters/openai.js +302 -0
- package/dist/agent-runtime/adapters/openai.js.map +1 -0
- package/dist/agent-runtime/adapters/registry.d.ts +49 -0
- package/dist/agent-runtime/adapters/registry.js +129 -0
- package/dist/agent-runtime/adapters/registry.js.map +1 -0
- package/dist/agent-runtime/adapters/ui-tars.d.ts +13 -0
- package/dist/agent-runtime/adapters/ui-tars.js +22 -0
- package/dist/agent-runtime/adapters/ui-tars.js.map +1 -0
- package/dist/agent-runtime/agent-runner.d.ts +149 -0
- package/dist/agent-runtime/agent-runner.js +356 -0
- package/dist/agent-runtime/agent-runner.js.map +1 -0
- package/dist/agent-runtime/core.d.ts +170 -0
- package/dist/agent-runtime/core.js +624 -0
- package/dist/agent-runtime/core.js.map +1 -0
- package/dist/agent-runtime/index.d.ts +16 -0
- package/dist/agent-runtime/index.js +17 -0
- package/dist/agent-runtime/index.js.map +1 -0
- package/dist/agent-runtime/plan-executor.d.ts +118 -0
- package/dist/agent-runtime/plan-executor.js +501 -0
- package/dist/agent-runtime/plan-executor.js.map +1 -0
- package/dist/agent-runtime/planner/base.d.ts +128 -0
- package/dist/agent-runtime/planner/base.js +157 -0
- package/dist/agent-runtime/planner/base.js.map +1 -0
- package/dist/agent-runtime/planner/llm-planner.d.ts +58 -0
- package/dist/agent-runtime/planner/llm-planner.js +112 -0
- package/dist/agent-runtime/planner/llm-planner.js.map +1 -0
- package/dist/agent-runtime/planner/noop-planner.d.ts +13 -0
- package/dist/agent-runtime/planner/noop-planner.js +30 -0
- package/dist/agent-runtime/planner/noop-planner.js.map +1 -0
- package/dist/agent-runtime/planner/prompts.d.ts +33 -0
- package/dist/agent-runtime/planner/prompts.js +165 -0
- package/dist/agent-runtime/planner/prompts.js.map +1 -0
- package/dist/agent-runtime/reflection.d.ts +81 -0
- package/dist/agent-runtime/reflection.js +189 -0
- package/dist/agent-runtime/reflection.js.map +1 -0
- package/dist/agent-runtime/reflectors/action-reflector.d.ts +97 -0
- package/dist/agent-runtime/reflectors/action-reflector.js +233 -0
- package/dist/agent-runtime/reflectors/action-reflector.js.map +1 -0
- package/dist/agent-runtime/reflectors/policy.d.ts +53 -0
- package/dist/agent-runtime/reflectors/policy.js +106 -0
- package/dist/agent-runtime/reflectors/policy.js.map +1 -0
- package/dist/agent-runtime/reflectors/trajectory-reflector.d.ts +94 -0
- package/dist/agent-runtime/reflectors/trajectory-reflector.js +223 -0
- package/dist/agent-runtime/reflectors/trajectory-reflector.js.map +1 -0
- package/dist/agent-runtime/skills/embedding.d.ts +53 -0
- package/dist/agent-runtime/skills/embedding.js +134 -0
- package/dist/agent-runtime/skills/embedding.js.map +1 -0
- package/dist/agent-runtime/skills/fs-store.d.ts +88 -0
- package/dist/agent-runtime/skills/fs-store.js +483 -0
- package/dist/agent-runtime/skills/fs-store.js.map +1 -0
- package/dist/agent-runtime/skills/index.d.ts +10 -0
- package/dist/agent-runtime/skills/index.js +10 -0
- package/dist/agent-runtime/skills/index.js.map +1 -0
- package/dist/agent-runtime/skills/matcher-evolver.d.ts +88 -0
- package/dist/agent-runtime/skills/matcher-evolver.js +110 -0
- package/dist/agent-runtime/skills/matcher-evolver.js.map +1 -0
- package/dist/agent-runtime/skills/memory-store.d.ts +23 -0
- package/dist/agent-runtime/skills/memory-store.js +94 -0
- package/dist/agent-runtime/skills/memory-store.js.map +1 -0
- package/dist/agent-runtime/skills/normalise.d.ts +40 -0
- package/dist/agent-runtime/skills/normalise.js +152 -0
- package/dist/agent-runtime/skills/normalise.js.map +1 -0
- package/dist/agent-runtime/skills/replay.d.ts +46 -0
- package/dist/agent-runtime/skills/replay.js +106 -0
- package/dist/agent-runtime/skills/replay.js.map +1 -0
- package/dist/agent-runtime/skills/sqlite-store.d.ts +60 -0
- package/dist/agent-runtime/skills/sqlite-store.js +234 -0
- package/dist/agent-runtime/skills/sqlite-store.js.map +1 -0
- package/dist/agent-runtime/skills/types.d.ts +99 -0
- package/dist/agent-runtime/skills/types.js +14 -0
- package/dist/agent-runtime/skills/types.js.map +1 -0
- package/dist/agent.d.ts +110 -0
- package/dist/agent.js +162 -0
- package/dist/agent.js.map +1 -0
- package/dist/api.d.ts +27 -0
- package/dist/api.js +48 -0
- package/dist/api.js.map +1 -0
- package/dist/app/agent-host.d.ts +59 -0
- package/dist/app/agent-host.js +263 -0
- package/dist/app/agent-host.js.map +1 -0
- package/dist/app/device-manager.d.ts +28 -0
- package/dist/app/device-manager.js +64 -0
- package/dist/app/device-manager.js.map +1 -0
- package/dist/app/message-store.d.ts +55 -0
- package/dist/app/message-store.js +99 -0
- package/dist/app/message-store.js.map +1 -0
- package/dist/app/session-manager.d.ts +132 -0
- package/dist/app/session-manager.js +350 -0
- package/dist/app/session-manager.js.map +1 -0
- package/dist/bootstrap.d.ts +94 -0
- package/dist/bootstrap.js +459 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/chat.d.ts +16 -0
- package/dist/chat.js +175 -0
- package/dist/chat.js.map +1 -0
- package/dist/config/loader.d.ts +77 -0
- package/dist/config/loader.js +292 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +162 -0
- package/dist/config/schema.js +243 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/actions.d.ts +60 -0
- package/dist/core/actions.js +120 -0
- package/dist/core/actions.js.map +1 -0
- package/dist/core/errors.d.ts +8 -0
- package/dist/core/errors.js +9 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/screen.d.ts +7 -0
- package/dist/core/screen.js +8 -0
- package/dist/core/screen.js.map +1 -0
- package/dist/core/session.d.ts +42 -0
- package/dist/core/session.js +29 -0
- package/dist/core/session.js.map +1 -0
- package/dist/debug/dump-system-prompt.d.ts +1 -0
- package/dist/debug/dump-system-prompt.js +34 -0
- package/dist/debug/dump-system-prompt.js.map +1 -0
- package/dist/device/android.d.ts +25 -0
- package/dist/device/android.js +231 -0
- package/dist/device/android.js.map +1 -0
- package/dist/device/apps.d.ts +3 -0
- package/dist/device/apps.js +77 -0
- package/dist/device/apps.js.map +1 -0
- package/dist/device/base.d.ts +20 -0
- package/dist/device/base.js +2 -0
- package/dist/device/base.js.map +1 -0
- package/dist/device/ui-xml.d.ts +29 -0
- package/dist/device/ui-xml.js +194 -0
- package/dist/device/ui-xml.js.map +1 -0
- package/dist/fleet/adapters/process/node-process-manager.d.ts +157 -0
- package/dist/fleet/adapters/process/node-process-manager.js +664 -0
- package/dist/fleet/adapters/process/node-process-manager.js.map +1 -0
- package/dist/fleet/adapters/sources/local-adb.d.ts +105 -0
- package/dist/fleet/adapters/sources/local-adb.js +353 -0
- package/dist/fleet/adapters/sources/local-adb.js.map +1 -0
- package/dist/fleet/adapters/sources/remote-adb.d.ts +97 -0
- package/dist/fleet/adapters/sources/remote-adb.js +138 -0
- package/dist/fleet/adapters/sources/remote-adb.js.map +1 -0
- package/dist/fleet/adapters/state/beeos-cli-store.d.ts +72 -0
- package/dist/fleet/adapters/state/beeos-cli-store.js +250 -0
- package/dist/fleet/adapters/state/beeos-cli-store.js.map +1 -0
- package/dist/fleet/adapters/state/port-allocator.d.ts +43 -0
- package/dist/fleet/adapters/state/port-allocator.js +173 -0
- package/dist/fleet/adapters/state/port-allocator.js.map +1 -0
- package/dist/fleet/domain/device.d.ts +138 -0
- package/dist/fleet/domain/device.js +49 -0
- package/dist/fleet/domain/device.js.map +1 -0
- package/dist/fleet/domain/events.d.ts +102 -0
- package/dist/fleet/domain/events.js +15 -0
- package/dist/fleet/domain/events.js.map +1 -0
- package/dist/fleet/domain/fsm.d.ts +122 -0
- package/dist/fleet/domain/fsm.js +475 -0
- package/dist/fleet/domain/fsm.js.map +1 -0
- package/dist/fleet/http/status-client.d.ts +31 -0
- package/dist/fleet/http/status-client.js +115 -0
- package/dist/fleet/http/status-client.js.map +1 -0
- package/dist/fleet/http/status-server.d.ts +64 -0
- package/dist/fleet/http/status-server.js +200 -0
- package/dist/fleet/http/status-server.js.map +1 -0
- package/dist/fleet/index.d.ts +27 -0
- package/dist/fleet/index.js +17 -0
- package/dist/fleet/index.js.map +1 -0
- package/dist/fleet/installer/index.d.ts +12 -0
- package/dist/fleet/installer/index.js +13 -0
- package/dist/fleet/installer/index.js.map +1 -0
- package/dist/fleet/installer/launchd-mac.d.ts +73 -0
- package/dist/fleet/installer/launchd-mac.js +291 -0
- package/dist/fleet/installer/launchd-mac.js.map +1 -0
- package/dist/fleet/installer/service-spec.d.ts +70 -0
- package/dist/fleet/installer/service-spec.js +43 -0
- package/dist/fleet/installer/service-spec.js.map +1 -0
- package/dist/fleet/installer/spawn-env.d.ts +45 -0
- package/dist/fleet/installer/spawn-env.js +224 -0
- package/dist/fleet/installer/spawn-env.js.map +1 -0
- package/dist/fleet/ports/clock.d.ts +19 -0
- package/dist/fleet/ports/clock.js +26 -0
- package/dist/fleet/ports/clock.js.map +1 -0
- package/dist/fleet/ports/device-source.d.ts +28 -0
- package/dist/fleet/ports/device-source.js +18 -0
- package/dist/fleet/ports/device-source.js.map +1 -0
- package/dist/fleet/ports/process-manager.d.ts +110 -0
- package/dist/fleet/ports/process-manager.js +27 -0
- package/dist/fleet/ports/process-manager.js.map +1 -0
- package/dist/fleet/ports/state-registry.d.ts +49 -0
- package/dist/fleet/ports/state-registry.js +12 -0
- package/dist/fleet/ports/state-registry.js.map +1 -0
- package/dist/fleet/supervisor.d.ts +107 -0
- package/dist/fleet/supervisor.js +508 -0
- package/dist/fleet/supervisor.js.map +1 -0
- package/dist/grounding/grounder.d.ts +46 -0
- package/dist/grounding/grounder.js +82 -0
- package/dist/grounding/grounder.js.map +1 -0
- package/dist/inbound/acp/handlers/device.d.ts +43 -0
- package/dist/inbound/acp/handlers/device.js +153 -0
- package/dist/inbound/acp/handlers/device.js.map +1 -0
- package/dist/inbound/acp/handlers/initialize.d.ts +71 -0
- package/dist/inbound/acp/handlers/initialize.js +53 -0
- package/dist/inbound/acp/handlers/initialize.js.map +1 -0
- package/dist/inbound/acp/handlers/models.d.ts +16 -0
- package/dist/inbound/acp/handlers/models.js +23 -0
- package/dist/inbound/acp/handlers/models.js.map +1 -0
- package/dist/inbound/acp/handlers/session.d.ts +51 -0
- package/dist/inbound/acp/handlers/session.js +61 -0
- package/dist/inbound/acp/handlers/session.js.map +1 -0
- package/dist/inbound/acp/handlers/skills.d.ts +8 -0
- package/dist/inbound/acp/handlers/skills.js +9 -0
- package/dist/inbound/acp/handlers/skills.js.map +1 -0
- package/dist/inbound/acp/notifier.d.ts +35 -0
- package/dist/inbound/acp/notifier.js +45 -0
- package/dist/inbound/acp/notifier.js.map +1 -0
- package/dist/inbound/acp/router.d.ts +67 -0
- package/dist/inbound/acp/router.js +179 -0
- package/dist/inbound/acp/router.js.map +1 -0
- package/dist/inbound/cli/fleet-command.d.ts +34 -0
- package/dist/inbound/cli/fleet-command.js +792 -0
- package/dist/inbound/cli/fleet-command.js.map +1 -0
- package/dist/inbound/cli/main.d.ts +38 -0
- package/dist/inbound/cli/main.js +364 -0
- package/dist/inbound/cli/main.js.map +1 -0
- package/dist/inbound/cli/run-command.d.ts +101 -0
- package/dist/inbound/cli/run-command.js +405 -0
- package/dist/inbound/cli/run-command.js.map +1 -0
- package/dist/inbound/cli/skills-command.d.ts +39 -0
- package/dist/inbound/cli/skills-command.js +333 -0
- package/dist/inbound/cli/skills-command.js.map +1 -0
- package/dist/inbound/http/server.d.ts +7 -0
- package/dist/inbound/http/server.js +8 -0
- package/dist/inbound/http/server.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/index.d.ts +37 -0
- package/dist/logger/index.js +84 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/mcp-client/autospawn.d.ts +67 -0
- package/dist/mcp-client/autospawn.js +173 -0
- package/dist/mcp-client/autospawn.js.map +1 -0
- package/dist/mcp-client/client.d.ts +78 -0
- package/dist/mcp-client/client.js +168 -0
- package/dist/mcp-client/client.js.map +1 -0
- package/dist/mcp-client/index.d.ts +7 -0
- package/dist/mcp-client/index.js +4 -0
- package/dist/mcp-client/index.js.map +1 -0
- package/dist/mcp-client/inproc.d.ts +47 -0
- package/dist/mcp-client/inproc.js +229 -0
- package/dist/mcp-client/inproc.js.map +1 -0
- package/dist/mcp-client/runtime.d.ts +34 -0
- package/dist/mcp-client/runtime.js +15 -0
- package/dist/mcp-client/runtime.js.map +1 -0
- package/dist/model/adapters/autoglm.d.ts +31 -0
- package/dist/model/adapters/autoglm.js +409 -0
- package/dist/model/adapters/autoglm.js.map +1 -0
- package/dist/model/adapters/base.d.ts +13 -0
- package/dist/model/adapters/base.js +27 -0
- package/dist/model/adapters/base.js.map +1 -0
- package/dist/model/adapters/guiowl.d.ts +1 -0
- package/dist/model/adapters/guiowl.js +253 -0
- package/dist/model/adapters/guiowl.js.map +1 -0
- package/dist/model/adapters/index.d.ts +6 -0
- package/dist/model/adapters/index.js +8 -0
- package/dist/model/adapters/index.js.map +1 -0
- package/dist/model/adapters/maiui.d.ts +1 -0
- package/dist/model/adapters/maiui.js +117 -0
- package/dist/model/adapters/maiui.js.map +1 -0
- package/dist/model/adapters/qwenvl.d.ts +1 -0
- package/dist/model/adapters/qwenvl.js +108 -0
- package/dist/model/adapters/qwenvl.js.map +1 -0
- package/dist/model/adapters/showui.d.ts +1 -0
- package/dist/model/adapters/showui.js +132 -0
- package/dist/model/adapters/showui.js.map +1 -0
- package/dist/model/adapters/tool-call.d.ts +6 -0
- package/dist/model/adapters/tool-call.js +102 -0
- package/dist/model/adapters/tool-call.js.map +1 -0
- package/dist/model/adapters/uitars.d.ts +1 -0
- package/dist/model/adapters/uitars.js +180 -0
- package/dist/model/adapters/uitars.js.map +1 -0
- package/dist/model/base.d.ts +32 -0
- package/dist/model/base.js +2 -0
- package/dist/model/base.js.map +1 -0
- package/dist/model/client.d.ts +26 -0
- package/dist/model/client.js +300 -0
- package/dist/model/client.js.map +1 -0
- package/dist/model/image/compress.d.ts +53 -0
- package/dist/model/image/compress.js +89 -0
- package/dist/model/image/compress.js.map +1 -0
- package/dist/model/image/transport.d.ts +134 -0
- package/dist/model/image/transport.js +154 -0
- package/dist/model/image/transport.js.map +1 -0
- package/dist/orchestrator-system-prompt.d.ts +6 -0
- package/dist/orchestrator-system-prompt.js +81 -0
- package/dist/orchestrator-system-prompt.js.map +1 -0
- package/dist/pi-context.d.ts +82 -0
- package/dist/pi-context.js +62 -0
- package/dist/pi-context.js.map +1 -0
- package/dist/pi-local-skills.d.ts +17 -0
- package/dist/pi-local-skills.js +24 -0
- package/dist/pi-local-skills.js.map +1 -0
- package/dist/plugins/acp/index.d.ts +46 -0
- package/dist/plugins/acp/index.js +111 -0
- package/dist/plugins/acp/index.js.map +1 -0
- package/dist/plugins/agent-sync/index.d.ts +40 -0
- package/dist/plugins/agent-sync/index.js +98 -0
- package/dist/plugins/agent-sync/index.js.map +1 -0
- package/dist/plugins/http-debug/index.d.ts +30 -0
- package/dist/plugins/http-debug/index.js +64 -0
- package/dist/plugins/http-debug/index.js.map +1 -0
- package/dist/plugins/http-debug/server.d.ts +92 -0
- package/dist/plugins/http-debug/server.js +464 -0
- package/dist/plugins/http-debug/server.js.map +1 -0
- package/dist/ports/agent-core.d.ts +158 -0
- package/dist/ports/agent-core.js +2 -0
- package/dist/ports/agent-core.js.map +1 -0
- package/dist/ports/agent-host.d.ts +125 -0
- package/dist/ports/agent-host.js +23 -0
- package/dist/ports/agent-host.js.map +1 -0
- package/dist/ports/device.d.ts +53 -0
- package/dist/ports/device.js +13 -0
- package/dist/ports/device.js.map +1 -0
- package/dist/ports/identity.d.ts +22 -0
- package/dist/ports/identity.js +9 -0
- package/dist/ports/identity.js.map +1 -0
- package/dist/ports/plugin.d.ts +62 -0
- package/dist/ports/plugin.js +35 -0
- package/dist/ports/plugin.js.map +1 -0
- package/dist/ports/transport.d.ts +32 -0
- package/dist/ports/transport.js +12 -0
- package/dist/ports/transport.js.map +1 -0
- package/dist/ports/vlm.d.ts +59 -0
- package/dist/ports/vlm.js +14 -0
- package/dist/ports/vlm.js.map +1 -0
- package/dist/test-lan-autoglm.d.ts +7 -0
- package/dist/test-lan-autoglm.js +46 -0
- package/dist/test-lan-autoglm.js.map +1 -0
- package/dist/test-mem-breakdown.d.ts +1 -0
- package/dist/test-mem-breakdown.js +103 -0
- package/dist/test-mem-breakdown.js.map +1 -0
- package/dist/test-mem.d.ts +1 -0
- package/dist/test-mem.js +60 -0
- package/dist/test-mem.js.map +1 -0
- package/dist/test-mobile-use.d.ts +1 -0
- package/dist/test-mobile-use.js +18 -0
- package/dist/test-mobile-use.js.map +1 -0
- package/dist/test-screenshot-loop.d.ts +1 -0
- package/dist/test-screenshot-loop.js +43 -0
- package/dist/test-screenshot-loop.js.map +1 -0
- package/dist/test-screenshot.d.ts +1 -0
- package/dist/test-screenshot.js +10 -0
- package/dist/test-screenshot.js.map +1 -0
- package/dist/test-ui-xml-dump.d.ts +15 -0
- package/dist/test-ui-xml-dump.js +49 -0
- package/dist/test-ui-xml-dump.js.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// ── Public API ────────────────────────────────────────────────────────────────
|
|
2
|
+
/**
|
|
3
|
+
* Fetch UI hierarchy from the device and return a compact, LLM-ready string.
|
|
4
|
+
*
|
|
5
|
+
* No query → all interactive + standalone-text nodes, one line each.
|
|
6
|
+
* With query → same list filtered by substring match on text / resource-id /
|
|
7
|
+
* content-desc / class (case-insensitive).
|
|
8
|
+
*/
|
|
9
|
+
export async function queryUiXml(device, query) {
|
|
10
|
+
const xml = await device.getUiXml();
|
|
11
|
+
if (!xml)
|
|
12
|
+
return "Failed to get UI XML";
|
|
13
|
+
return formatUiXmlToolOutput(xml, query);
|
|
14
|
+
}
|
|
15
|
+
/** Same string the `ui_xml` tool returns, given already-fetched XML. */
|
|
16
|
+
export function formatUiXmlToolOutput(xml, query) {
|
|
17
|
+
const root = parseXmlTree(xml);
|
|
18
|
+
if (!root)
|
|
19
|
+
return "Failed to parse UI XML";
|
|
20
|
+
const nodes = collectNodes(root);
|
|
21
|
+
const filtered = query ? filterNodes(nodes, query) : nodes;
|
|
22
|
+
if (filtered.length === 0) {
|
|
23
|
+
return query ? `No elements found matching "${query}"` : "No interactive elements found";
|
|
24
|
+
}
|
|
25
|
+
return filtered.map(formatNode).join("\n");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Search raw XML for nodes matching a query — used by test:ui-xml script.
|
|
29
|
+
* Returns UiNode[] for JSON dump; formatUiXmlToolOutput() is the tool path.
|
|
30
|
+
*/
|
|
31
|
+
export function searchUiXmlNodes(xml, query) {
|
|
32
|
+
const root = parseXmlTree(xml);
|
|
33
|
+
if (!root)
|
|
34
|
+
return [];
|
|
35
|
+
const nodes = collectNodes(root);
|
|
36
|
+
const filtered = query ? filterNodes(nodes, query) : nodes;
|
|
37
|
+
return filtered.map(treeNodeToUiNode);
|
|
38
|
+
}
|
|
39
|
+
// ── XML tree parser ───────────────────────────────────────────────────────────
|
|
40
|
+
function parseXmlTree(xml) {
|
|
41
|
+
// Tokenise: <node ...>, <node .../>, </node>
|
|
42
|
+
const re = /<(\/?)node(\s[^>]*)?(\/?)>/g;
|
|
43
|
+
let m;
|
|
44
|
+
const dummy = makeNode("");
|
|
45
|
+
const stack = [dummy];
|
|
46
|
+
while ((m = re.exec(xml)) !== null) {
|
|
47
|
+
const isClose = m[1] === "/";
|
|
48
|
+
const isSelf = m[3] === "/";
|
|
49
|
+
const attrs = m[2] ?? "";
|
|
50
|
+
if (isClose) {
|
|
51
|
+
if (stack.length > 1)
|
|
52
|
+
stack.pop();
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const node = makeNode(attrs);
|
|
56
|
+
const parent = stack[stack.length - 1];
|
|
57
|
+
node.parent = parent;
|
|
58
|
+
parent.children.push(node);
|
|
59
|
+
if (!isSelf)
|
|
60
|
+
stack.push(node);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return dummy.children[0] ?? null;
|
|
64
|
+
}
|
|
65
|
+
function makeNode(attrs) {
|
|
66
|
+
const bounds = attr(attrs, "bounds");
|
|
67
|
+
return {
|
|
68
|
+
text: attr(attrs, "text"),
|
|
69
|
+
contentDesc: attr(attrs, "content-desc"),
|
|
70
|
+
resourceId: attr(attrs, "resource-id"),
|
|
71
|
+
className: attr(attrs, "class"),
|
|
72
|
+
bounds,
|
|
73
|
+
clickable: attr(attrs, "clickable") === "true",
|
|
74
|
+
longClickable: attr(attrs, "long-clickable") === "true",
|
|
75
|
+
scrollable: attr(attrs, "scrollable") === "true",
|
|
76
|
+
focusable: attr(attrs, "focusable") === "true",
|
|
77
|
+
enabled: attr(attrs, "enabled") !== "false",
|
|
78
|
+
center: boundsCenter(bounds),
|
|
79
|
+
children: [],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function attr(attrs, name) {
|
|
83
|
+
return attrs.match(new RegExp(`${name}="([^"]*)"`, "i"))?.[1] ?? "";
|
|
84
|
+
}
|
|
85
|
+
function boundsCenter(bounds) {
|
|
86
|
+
const m = bounds.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);
|
|
87
|
+
if (!m)
|
|
88
|
+
return { x: 0, y: 0 };
|
|
89
|
+
return { x: Math.round((+m[1] + +m[3]) / 2), y: Math.round((+m[2] + +m[4]) / 2) };
|
|
90
|
+
}
|
|
91
|
+
// ── Node collection ───────────────────────────────────────────────────────────
|
|
92
|
+
function isInteractive(n) {
|
|
93
|
+
return n.enabled && (n.clickable || n.longClickable || n.scrollable || n.focusable);
|
|
94
|
+
}
|
|
95
|
+
function hasInteractiveAncestor(n) {
|
|
96
|
+
let p = n.parent;
|
|
97
|
+
while (p) {
|
|
98
|
+
if (isInteractive(p))
|
|
99
|
+
return true;
|
|
100
|
+
p = p.parent;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
function displayText(n) {
|
|
105
|
+
return n.text || n.contentDesc;
|
|
106
|
+
}
|
|
107
|
+
/** Collect interactive nodes + standalone text nodes (no interactive ancestor). */
|
|
108
|
+
function collectNodes(root) {
|
|
109
|
+
const result = [];
|
|
110
|
+
function walk(n) {
|
|
111
|
+
if (!n.enabled)
|
|
112
|
+
return;
|
|
113
|
+
if (isInteractive(n)) {
|
|
114
|
+
result.push(n);
|
|
115
|
+
}
|
|
116
|
+
else if (displayText(n) && !hasInteractiveAncestor(n)) {
|
|
117
|
+
result.push(n);
|
|
118
|
+
}
|
|
119
|
+
for (const child of n.children)
|
|
120
|
+
walk(child);
|
|
121
|
+
}
|
|
122
|
+
walk(root);
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
// ── Filtering ────────────────────────────────────────────────────────────────
|
|
126
|
+
function filterNodes(nodes, query) {
|
|
127
|
+
const q = query.toLowerCase();
|
|
128
|
+
return nodes.filter((n) => n.text.toLowerCase().includes(q) ||
|
|
129
|
+
n.contentDesc.toLowerCase().includes(q) ||
|
|
130
|
+
n.resourceId.toLowerCase().includes(q) ||
|
|
131
|
+
n.className.toLowerCase().includes(q));
|
|
132
|
+
}
|
|
133
|
+
// ── Compact line formatter ────────────────────────────────────────────────────
|
|
134
|
+
const CLASS_SHORT = {
|
|
135
|
+
Button: "Btn",
|
|
136
|
+
ImageButton: "ImgBtn",
|
|
137
|
+
TextView: "Text",
|
|
138
|
+
EditText: "Edit",
|
|
139
|
+
ImageView: "Img",
|
|
140
|
+
CheckBox: "Check",
|
|
141
|
+
Switch: "Switch",
|
|
142
|
+
RadioButton: "Radio",
|
|
143
|
+
ListView: "List",
|
|
144
|
+
RecyclerView: "List",
|
|
145
|
+
ScrollView: "Scroll",
|
|
146
|
+
HorizontalScrollView: "HScroll",
|
|
147
|
+
ViewPager: "Pager",
|
|
148
|
+
WebView: "Web",
|
|
149
|
+
FrameLayout: "Frame",
|
|
150
|
+
LinearLayout: "Layout",
|
|
151
|
+
RelativeLayout: "Layout",
|
|
152
|
+
ConstraintLayout: "Layout",
|
|
153
|
+
};
|
|
154
|
+
function shortClass(cls) {
|
|
155
|
+
const base = cls.split(".").pop() ?? cls;
|
|
156
|
+
return CLASS_SHORT[base] ?? base;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Compact one-liner: (x,y) Type "text" id=pkg:id/name *click *scroll *focus *lclick
|
|
160
|
+
* Omits empty text and false flags to minimise tokens.
|
|
161
|
+
*/
|
|
162
|
+
function formatNode(n) {
|
|
163
|
+
const parts = [];
|
|
164
|
+
parts.push(`(${n.center.x},${n.center.y})`);
|
|
165
|
+
parts.push(shortClass(n.className));
|
|
166
|
+
const label = displayText(n);
|
|
167
|
+
if (label)
|
|
168
|
+
parts.push(`"${label}"`);
|
|
169
|
+
if (n.resourceId)
|
|
170
|
+
parts.push(`id=${n.resourceId}`);
|
|
171
|
+
if (n.clickable)
|
|
172
|
+
parts.push("*click");
|
|
173
|
+
if (n.longClickable)
|
|
174
|
+
parts.push("*lclick");
|
|
175
|
+
if (n.scrollable)
|
|
176
|
+
parts.push("*scroll");
|
|
177
|
+
if (n.focusable && !n.clickable)
|
|
178
|
+
parts.push("*focus");
|
|
179
|
+
return parts.join(" ");
|
|
180
|
+
}
|
|
181
|
+
// ── UiNode conversion (for test script / backward compat) ────────────────────
|
|
182
|
+
function treeNodeToUiNode(n) {
|
|
183
|
+
return {
|
|
184
|
+
text: n.text,
|
|
185
|
+
resourceId: n.resourceId,
|
|
186
|
+
contentDesc: n.contentDesc,
|
|
187
|
+
className: n.className,
|
|
188
|
+
bounds: n.bounds,
|
|
189
|
+
center: n.center,
|
|
190
|
+
clickable: n.clickable,
|
|
191
|
+
enabled: n.enabled,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=ui-xml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-xml.js","sourceRoot":"","sources":["../../src/device/ui-xml.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter — `IProcessManager` implementation backed by `child_process.spawn`.
|
|
3
|
+
*
|
|
4
|
+
* Spawns and supervises up to three long-running siblings per bound device:
|
|
5
|
+
*
|
|
6
|
+
* - **mcp** `device-mcp-server --backend <kind> --adb-serial <serial>
|
|
7
|
+
* --host 127.0.0.1 --port <mcpPort>`
|
|
8
|
+
* - **daemon** `device-agent --key <keyFile> --agent-gateway-url <url>
|
|
9
|
+
* --mcp-url http://127.0.0.1:<mcpPort> --adb <serial>
|
|
10
|
+
* [--http --http-port <httpPort>]`
|
|
11
|
+
* - **scrcpy** `scrcpy-bridge` (no args; configured via env mirroring
|
|
12
|
+
* `web/packages/core/src/runtime/scrcpy-bridge.ts` `buildEnv`).
|
|
13
|
+
* Optional — only spawned when the binding's `videoMode === "scrcpy"`.
|
|
14
|
+
*
|
|
15
|
+
* Lifecycle responsibilities:
|
|
16
|
+
*
|
|
17
|
+
* - `spawnMcp` waits for `GET /healthz` to return 200 (configurable timeout)
|
|
18
|
+
* before emitting `mcp_started`. If readiness times out the spawn is
|
|
19
|
+
* killed and an `mcp_exited` event is reported (so the FSM treats the
|
|
20
|
+
* attempt as a crash and either retries or backs off).
|
|
21
|
+
* - `spawnDaemon` emits `daemon_started` as soon as the child has a PID
|
|
22
|
+
* (the daemon's own readiness is observable through ACP traffic which is
|
|
23
|
+
* out of fleet scope; the daemon process itself dying is what we react to
|
|
24
|
+
* here). Optional `daemonHttpPort` is probed similarly when set.
|
|
25
|
+
* - `spawnScrcpy` is best-effort — a missing binary yields a synthetic
|
|
26
|
+
* `scrcpy_exited` event (with `reason`) instead of a thrown error.
|
|
27
|
+
* scrcpy-bridge has no `/healthz`, so readiness is degraded to
|
|
28
|
+
* "process still alive `scrcpyStartupGraceMs` after spawn"; before that
|
|
29
|
+
* window elapses we don't emit `scrcpy_started`. If the child exits
|
|
30
|
+
* within the grace, we emit `scrcpy_exited` instead.
|
|
31
|
+
* - `kill*` sends SIGTERM, then SIGKILL after `shutdownGraceMs`. When the
|
|
32
|
+
* supervisor initiates the kill we mark the resulting exit as `expected`
|
|
33
|
+
* so the pure FSM (`fsm.ts`) doesn't penalise restartCount.
|
|
34
|
+
* - When a child dies on its own (`expected=false`), we emit the matching
|
|
35
|
+
* `*_exited` event and let the supervisor (driving the FSM) decide whether
|
|
36
|
+
* to respawn. We never auto-restart from inside this adapter — the FSM
|
|
37
|
+
* owns the policy.
|
|
38
|
+
*
|
|
39
|
+
* Binary discovery:
|
|
40
|
+
* - mcp: `BEEOS_DEVICE_MCP_BIN` → `device-mcp-server` on PATH (override via opts.mcpBin).
|
|
41
|
+
* - daemon: `BEEOS_DEVICE_AGENT_BIN` → `device-agent` on PATH (override via opts.daemonBin).
|
|
42
|
+
* - scrcpy: `BEEOS_SCRCPY_BRIDGE_BIN` env → `~/.beeos/bin/scrcpy-bridge[.exe]` (managed install).
|
|
43
|
+
* Override via `opts.scrcpyBin` (absolute path) or `opts.findScrcpyBinFn` (test hook).
|
|
44
|
+
*
|
|
45
|
+
* The implementation deliberately exposes a hookable `spawnFn` /
|
|
46
|
+
* `httpProbeFn` / `findScrcpyBinFn` so unit tests can drive the manager with
|
|
47
|
+
* fake children and synthetic /healthz responses without touching the OS.
|
|
48
|
+
*/
|
|
49
|
+
import type { IProcessManager, ManagedProcess, ProcessEventListener, SpawnOptions, SpawnScrcpyOptions } from "../../ports/process-manager.js";
|
|
50
|
+
export interface ProcessManagerLogger {
|
|
51
|
+
debug(msg: string, data?: Record<string, unknown>): void;
|
|
52
|
+
info(msg: string, data?: Record<string, unknown>): void;
|
|
53
|
+
warn(msg: string, data?: Record<string, unknown>): void;
|
|
54
|
+
error(msg: string, data?: Record<string, unknown>): void;
|
|
55
|
+
}
|
|
56
|
+
/** Minimal subset of `child_process.ChildProcess` we depend on. */
|
|
57
|
+
export interface ManagedChild {
|
|
58
|
+
readonly pid: number | null | undefined;
|
|
59
|
+
kill(signal?: NodeJS.Signals): boolean;
|
|
60
|
+
once(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): void;
|
|
61
|
+
once(event: "error", listener: (err: Error) => void): void;
|
|
62
|
+
}
|
|
63
|
+
export type SpawnFn = (bin: string, args: readonly string[], env: NodeJS.ProcessEnv) => ManagedChild;
|
|
64
|
+
export type HttpProbeFn = (url: string, timeoutMs: number) => Promise<boolean>;
|
|
65
|
+
export interface NodeProcessManagerOptions {
|
|
66
|
+
/** Path / argv0 for `device-mcp-server` (split via shlex if it has spaces). */
|
|
67
|
+
mcpBin?: string;
|
|
68
|
+
/** Path / argv0 for `device-agent` (the daemon entry). Defaults to current `argv[1]`. */
|
|
69
|
+
daemonBin?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Path / argv0 for `scrcpy-bridge`. When unset the manager falls back to
|
|
72
|
+
* `BEEOS_SCRCPY_BRIDGE_BIN` env then `~/.beeos/bin/scrcpy-bridge[.exe]`
|
|
73
|
+
* (the cargo-dist managed install location used by `scrcpyBridgeRuntime`).
|
|
74
|
+
*/
|
|
75
|
+
scrcpyBin?: string;
|
|
76
|
+
/** mcp backend (`android`, `desktop`, `macos`, …). Defaults to `android`. */
|
|
77
|
+
mcpBackend?: string;
|
|
78
|
+
/** Bind host for mcp-server (default `127.0.0.1`). */
|
|
79
|
+
mcpHost?: string;
|
|
80
|
+
/** Public Agent Gateway URL forwarded to daemons. */
|
|
81
|
+
agentGatewayUrl?: string;
|
|
82
|
+
/** Bridge URL forwarded to daemons (rarely needed; default discovers via Agent Gateway). */
|
|
83
|
+
bridgeUrl?: string;
|
|
84
|
+
/** Optional region passed to daemon. */
|
|
85
|
+
region?: string;
|
|
86
|
+
/** Initial readiness probe timeout for mcp `/healthz`. */
|
|
87
|
+
mcpHealthTimeoutMs?: number;
|
|
88
|
+
/**
|
|
89
|
+
* Window we wait for scrcpy-bridge to keep running before declaring it
|
|
90
|
+
* healthy (defaults to 5 s, matching the launchd `KeepAlive=on-failure`
|
|
91
|
+
* grace). Tests should set this to a small value (e.g. 10 ms) to keep the
|
|
92
|
+
* suite fast.
|
|
93
|
+
*/
|
|
94
|
+
scrcpyStartupGraceMs?: number;
|
|
95
|
+
/** SIGTERM → SIGKILL grace. */
|
|
96
|
+
shutdownGraceMs?: number;
|
|
97
|
+
/** Hook for unit tests; defaults to `child_process.spawn`. */
|
|
98
|
+
spawnFn?: SpawnFn;
|
|
99
|
+
/** Hook for unit tests; defaults to a real HTTP GET. */
|
|
100
|
+
httpProbeFn?: HttpProbeFn;
|
|
101
|
+
/**
|
|
102
|
+
* Hook for unit tests + dependency injection — when supplied, takes
|
|
103
|
+
* precedence over the default discovery chain (`scrcpyBin` →
|
|
104
|
+
* `BEEOS_SCRCPY_BRIDGE_BIN` → `~/.beeos/bin/scrcpy-bridge`).
|
|
105
|
+
* Returns `null` when the binary cannot be located.
|
|
106
|
+
*/
|
|
107
|
+
findScrcpyBinFn?: () => Promise<string | null>;
|
|
108
|
+
/** Optional logger. */
|
|
109
|
+
logger?: ProcessManagerLogger;
|
|
110
|
+
/** Extra env vars to merge into every child (e.g. `MCP_URL`). */
|
|
111
|
+
extraEnv?: NodeJS.ProcessEnv;
|
|
112
|
+
}
|
|
113
|
+
export declare class NodeProcessManager implements IProcessManager {
|
|
114
|
+
private readonly mcpBin;
|
|
115
|
+
private readonly daemonBin;
|
|
116
|
+
private readonly scrcpyBinOverride?;
|
|
117
|
+
private readonly mcpBackend;
|
|
118
|
+
private readonly mcpHost;
|
|
119
|
+
private readonly agentGatewayUrl?;
|
|
120
|
+
private readonly bridgeUrl?;
|
|
121
|
+
private readonly region?;
|
|
122
|
+
private readonly mcpHealthTimeoutMs;
|
|
123
|
+
private readonly scrcpyStartupGraceMs;
|
|
124
|
+
private readonly shutdownGraceMs;
|
|
125
|
+
private readonly spawnFn;
|
|
126
|
+
private readonly httpProbeFn;
|
|
127
|
+
private readonly findScrcpyBinFn;
|
|
128
|
+
private readonly logger;
|
|
129
|
+
private readonly extraEnv;
|
|
130
|
+
private readonly slots;
|
|
131
|
+
private readonly listeners;
|
|
132
|
+
private started;
|
|
133
|
+
constructor(opts?: NodeProcessManagerOptions);
|
|
134
|
+
start(): Promise<void>;
|
|
135
|
+
stop(): Promise<void>;
|
|
136
|
+
on(listener: ProcessEventListener): () => void;
|
|
137
|
+
isAlive(serial: string, which: ManagedProcess): boolean;
|
|
138
|
+
pid(serial: string, which: ManagedProcess): number | null;
|
|
139
|
+
private slotFor;
|
|
140
|
+
private setSlot;
|
|
141
|
+
spawnMcp(opts: SpawnOptions): Promise<void>;
|
|
142
|
+
spawnDaemon(opts: SpawnOptions): Promise<void>;
|
|
143
|
+
spawnScrcpy(opts: SpawnScrcpyOptions): Promise<void>;
|
|
144
|
+
killMcp(serial: string, opts?: {
|
|
145
|
+
expected?: boolean;
|
|
146
|
+
}): Promise<void>;
|
|
147
|
+
killDaemon(serial: string, opts?: {
|
|
148
|
+
expected?: boolean;
|
|
149
|
+
}): Promise<void>;
|
|
150
|
+
killScrcpy(serial: string, opts?: {
|
|
151
|
+
expected?: boolean;
|
|
152
|
+
}): Promise<void>;
|
|
153
|
+
private ensureSlot;
|
|
154
|
+
private attachExitListener;
|
|
155
|
+
private killChild;
|
|
156
|
+
private emit;
|
|
157
|
+
}
|