@ashx-j/lunr 0.2.25 → 0.2.27
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 +31 -1
- package/LICENSE +22 -0
- package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -1
- package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-thinking.js +1 -1
- package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.d.ts +11 -1
- package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.js +6 -10
- package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
- package/dist/builtin-extensions/index.d.ts.map +1 -1
- package/dist/builtin-extensions/index.js +1 -0
- package/dist/builtin-extensions/index.js.map +1 -1
- package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
- package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
- package/dist/builtin-extensions/lunr-computer-use.js +179 -0
- package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
- package/dist/builtin-extensions/lunr-cron.d.ts +4 -5
- package/dist/builtin-extensions/lunr-cron.d.ts.map +1 -1
- package/dist/builtin-extensions/lunr-cron.js +94 -108
- package/dist/builtin-extensions/lunr-cron.js.map +1 -1
- package/dist/builtin-extensions/lunr-local-providers/local-servers.d.ts.map +1 -1
- package/dist/builtin-extensions/lunr-local-providers/local-servers.js +3 -1
- package/dist/builtin-extensions/lunr-local-providers/local-servers.js.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js +2 -2
- package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.js +2 -2
- package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/index.js +1 -15
- package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts +6 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js +187 -132
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts +8 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js +142 -112
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts +12 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js +14 -7
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts +11 -3
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js +67 -41
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts +4 -2
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js +3 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts +2 -1
- package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/commands.js +6 -6
- package/dist/builtin-extensions/pi-mcp-adapter/commands.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/config.js +11 -5
- package/dist/builtin-extensions/pi-mcp-adapter/config.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +2 -2
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/index.js +48 -40
- package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.js +3 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts +12 -40
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js +166 -235
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts +5 -0
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js +43 -13
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts +14 -3
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js +73 -21
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js +4 -4
- package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +2 -2
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts +2 -0
- package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/state.js.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.js +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.js.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts +11 -5
- package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/models.js +12 -32
- package/dist/builtin-extensions/pi-ollama-cloud/models.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/index.js +5 -3
- package/dist/builtin-extensions/pi-prompt-template-model/index.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts +2 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +21 -12
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +7 -24
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +39 -77
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -4
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +8 -5
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +15 -31
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +7 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +21 -4
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +11 -4
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +121 -25
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +25 -5
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js +5 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +7 -8
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js +60 -32
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.js +15 -5
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +4 -3
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +22 -11
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +3 -3
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
- package/dist/builtin-extensions/pi-tps.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-tps.js +20 -17
- package/dist/builtin-extensions/pi-tps.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/activity.d.ts +1 -0
- package/dist/builtin-extensions/pi-web-access/activity.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/activity.js +27 -5
- package/dist/builtin-extensions/pi-web-access/activity.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts +3 -0
- package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-web-access/bounded-body.js +43 -0
- package/dist/builtin-extensions/pi-web-access/bounded-body.js.map +1 -0
- package/dist/builtin-extensions/pi-web-access/content-page.d.ts +24 -0
- package/dist/builtin-extensions/pi-web-access/content-page.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-web-access/content-page.js +57 -0
- package/dist/builtin-extensions/pi-web-access/content-page.js.map +1 -0
- package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/extract.js +7 -2
- package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.d.ts +0 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.js +147 -36
- package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.js +48 -73
- package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +12 -4
- package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/session-cleanup.js +35 -12
- package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/storage.d.ts +9 -6
- package/dist/builtin-extensions/pi-web-access/storage.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/storage.js +36 -24
- package/dist/builtin-extensions/pi-web-access/storage.js.map +1 -1
- package/dist/builtin-extensions/simple-pi-memory.d.ts +1 -1
- package/dist/builtin-extensions/simple-pi-memory.d.ts.map +1 -1
- package/dist/builtin-extensions/simple-pi-memory.js +1 -1
- package/dist/builtin-extensions/simple-pi-memory.js.map +1 -1
- package/dist/cli/install-cli.d.ts.map +1 -1
- package/dist/cli/install-cli.js +38 -30
- package/dist/cli/install-cli.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +13 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +75 -11
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +40 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +309 -76
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/browser/runtime.d.ts +2 -0
- package/dist/core/browser/runtime.d.ts.map +1 -1
- package/dist/core/browser/runtime.js +80 -45
- package/dist/core/browser/runtime.js.map +1 -1
- package/dist/core/browser/setup.d.ts.map +1 -1
- package/dist/core/browser/setup.js +12 -1
- package/dist/core/browser/setup.js.map +1 -1
- package/dist/core/computer-use/adapter.d.ts +28 -0
- package/dist/core/computer-use/adapter.d.ts.map +1 -0
- package/dist/core/computer-use/adapter.js +138 -0
- package/dist/core/computer-use/adapter.js.map +1 -0
- package/dist/core/computer-use/image.d.ts +27 -0
- package/dist/core/computer-use/image.d.ts.map +1 -0
- package/dist/core/computer-use/image.js +84 -0
- package/dist/core/computer-use/image.js.map +1 -0
- package/dist/core/computer-use/lease.d.ts +18 -0
- package/dist/core/computer-use/lease.d.ts.map +1 -0
- package/dist/core/computer-use/lease.js +129 -0
- package/dist/core/computer-use/lease.js.map +1 -0
- package/dist/core/computer-use/macos-runtime.d.ts +14 -0
- package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
- package/dist/core/computer-use/macos-runtime.js +148 -0
- package/dist/core/computer-use/macos-runtime.js.map +1 -0
- package/dist/core/computer-use/policy.d.ts +19 -0
- package/dist/core/computer-use/policy.d.ts.map +1 -0
- package/dist/core/computer-use/policy.js +67 -0
- package/dist/core/computer-use/policy.js.map +1 -0
- package/dist/core/computer-use/release.generated.d.ts +31 -0
- package/dist/core/computer-use/release.generated.d.ts.map +1 -0
- package/dist/core/computer-use/release.generated.js +36 -0
- package/dist/core/computer-use/release.generated.js.map +1 -0
- package/dist/core/computer-use/runtime.d.ts +13 -0
- package/dist/core/computer-use/runtime.d.ts.map +1 -0
- package/dist/core/computer-use/runtime.js +158 -0
- package/dist/core/computer-use/runtime.js.map +1 -0
- package/dist/core/computer-use/schemas.d.ts +100 -0
- package/dist/core/computer-use/schemas.d.ts.map +1 -0
- package/dist/core/computer-use/schemas.js +96 -0
- package/dist/core/computer-use/schemas.js.map +1 -0
- package/dist/core/computer-use/windows-desktop.d.ts +3 -0
- package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
- package/dist/core/computer-use/windows-desktop.js +48 -0
- package/dist/core/computer-use/windows-desktop.js.map +1 -0
- package/dist/core/computer-use/workflow.d.ts +38 -0
- package/dist/core/computer-use/workflow.d.ts.map +1 -0
- package/dist/core/computer-use/workflow.js +900 -0
- package/dist/core/computer-use/workflow.js.map +1 -0
- package/dist/core/cron/jobs.d.ts +26 -8
- package/dist/core/cron/jobs.d.ts.map +1 -1
- package/dist/core/cron/jobs.js +357 -232
- package/dist/core/cron/jobs.js.map +1 -1
- package/dist/core/cron/origin-context.d.ts +1 -0
- package/dist/core/cron/origin-context.d.ts.map +1 -1
- package/dist/core/cron/origin-context.js.map +1 -1
- package/dist/core/cron/scheduler.d.ts +22 -17
- package/dist/core/cron/scheduler.d.ts.map +1 -1
- package/dist/core/cron/scheduler.js +153 -73
- package/dist/core/cron/scheduler.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +4 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +8 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +8 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +4 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +22 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/large-subagent-launch.d.ts +1 -1
- package/dist/core/large-subagent-launch.d.ts.map +1 -1
- package/dist/core/large-subagent-launch.js +7 -7
- package/dist/core/large-subagent-launch.js.map +1 -1
- package/dist/core/model-registry.d.ts +2 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +5 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-runtime.d.ts +4 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +40 -4
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/permissions.d.ts +4 -4
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +25 -38
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/plan-mode.d.ts +5 -13
- package/dist/core/plan-mode.d.ts.map +1 -1
- package/dist/core/plan-mode.js +135 -116
- package/dist/core/plan-mode.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/prompt-resource-bridge.d.ts +12 -0
- package/dist/core/prompt-resource-bridge.d.ts.map +1 -0
- package/dist/core/prompt-resource-bridge.js +9 -0
- package/dist/core/prompt-resource-bridge.js.map +1 -0
- package/dist/core/protected-targets.d.ts +6 -0
- package/dist/core/protected-targets.d.ts.map +1 -0
- package/dist/core/protected-targets.js +45 -0
- package/dist/core/protected-targets.js.map +1 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +7 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/rollback.d.ts +19 -3
- package/dist/core/rollback.d.ts.map +1 -1
- package/dist/core/rollback.js +172 -56
- package/dist/core/rollback.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +3 -0
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js +14 -1
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts +3 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +6 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +95 -32
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-ownership.d.ts.map +1 -1
- package/dist/core/session-ownership.js +8 -3
- package/dist/core/session-ownership.js.map +1 -1
- package/dist/core/session-retention.d.ts.map +1 -1
- package/dist/core/session-retention.js +18 -7
- package/dist/core/session-retention.js.map +1 -1
- package/dist/core/session-startup-settings.d.ts +10 -0
- package/dist/core/session-startup-settings.d.ts.map +1 -0
- package/dist/core/session-startup-settings.js +70 -0
- package/dist/core/session-startup-settings.js.map +1 -0
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +19 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/subagent-event-transport.d.ts +3 -0
- package/dist/core/subagent-event-transport.d.ts.map +1 -0
- package/dist/core/subagent-event-transport.js +61 -0
- package/dist/core/subagent-event-transport.js.map +1 -0
- package/dist/core/subscriptions.d.ts +16 -7
- package/dist/core/subscriptions.d.ts.map +1 -1
- package/dist/core/subscriptions.js +96 -55
- package/dist/core/subscriptions.js.map +1 -1
- package/dist/core/trust-manager.d.ts +2 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +6 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/update-check.d.ts.map +1 -1
- package/dist/core/update-check.js.map +1 -1
- package/dist/core/usage-adapters/kimi-coding.d.ts +2 -2
- package/dist/core/usage-adapters/kimi-coding.d.ts.map +1 -1
- package/dist/core/usage-adapters/kimi-coding.js +2 -2
- package/dist/core/usage-adapters/kimi-coding.js.map +1 -1
- package/dist/core/usage-adapters/openai-codex.d.ts +3 -2
- package/dist/core/usage-adapters/openai-codex.d.ts.map +1 -1
- package/dist/core/usage-adapters/openai-codex.js +3 -3
- package/dist/core/usage-adapters/openai-codex.js.map +1 -1
- package/dist/core/usage-adapters/xai.d.ts +2 -2
- package/dist/core/usage-adapters/xai.d.ts.map +1 -1
- package/dist/core/usage-adapters/xai.js +3 -3
- package/dist/core/usage-adapters/xai.js.map +1 -1
- package/dist/core/usage-adapters/zai.d.ts +2 -2
- package/dist/core/usage-adapters/zai.d.ts.map +1 -1
- package/dist/core/usage-adapters/zai.js +2 -2
- package/dist/core/usage-adapters/zai.js.map +1 -1
- package/dist/core/usage-service.d.ts +9 -2
- package/dist/core/usage-service.d.ts.map +1 -1
- package/dist/core/usage-service.js +95 -50
- package/dist/core/usage-service.js.map +1 -1
- package/dist/gateway/adapters/discord.d.ts.map +1 -1
- package/dist/gateway/adapters/discord.js +2 -2
- package/dist/gateway/adapters/discord.js.map +1 -1
- package/dist/gateway/agent-bridge.d.ts +9 -1
- package/dist/gateway/agent-bridge.d.ts.map +1 -1
- package/dist/gateway/agent-bridge.js +91 -37
- package/dist/gateway/agent-bridge.js.map +1 -1
- package/dist/gateway/approval.d.ts.map +1 -1
- package/dist/gateway/approval.js +3 -3
- package/dist/gateway/approval.js.map +1 -1
- package/dist/gateway/authz.d.ts +4 -4
- package/dist/gateway/authz.d.ts.map +1 -1
- package/dist/gateway/authz.js +8 -12
- package/dist/gateway/authz.js.map +1 -1
- package/dist/gateway/buttons.d.ts +8 -1
- package/dist/gateway/buttons.d.ts.map +1 -1
- package/dist/gateway/buttons.js +76 -18
- package/dist/gateway/buttons.js.map +1 -1
- package/dist/gateway/commands.d.ts +1 -0
- package/dist/gateway/commands.d.ts.map +1 -1
- package/dist/gateway/commands.js +12 -10
- package/dist/gateway/commands.js.map +1 -1
- package/dist/gateway/cron.d.ts +12 -11
- package/dist/gateway/cron.d.ts.map +1 -1
- package/dist/gateway/cron.js +85 -62
- package/dist/gateway/cron.js.map +1 -1
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js +5 -4
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/mobile-commands.d.ts +1 -0
- package/dist/gateway/mobile-commands.d.ts.map +1 -1
- package/dist/gateway/mobile-commands.js +64 -22
- package/dist/gateway/mobile-commands.js.map +1 -1
- package/dist/gateway/presenter.d.ts +12 -2
- package/dist/gateway/presenter.d.ts.map +1 -1
- package/dist/gateway/presenter.js +74 -39
- package/dist/gateway/presenter.js.map +1 -1
- package/dist/gateway/router.d.ts +2 -2
- package/dist/gateway/router.d.ts.map +1 -1
- package/dist/gateway/router.js +22 -9
- package/dist/gateway/router.js.map +1 -1
- package/dist/gateway/service.d.ts +2 -0
- package/dist/gateway/service.d.ts.map +1 -1
- package/dist/gateway/service.js +153 -0
- package/dist/gateway/service.js.map +1 -1
- package/dist/gateway/setup.d.ts.map +1 -1
- package/dist/gateway/setup.js +6 -4
- package/dist/gateway/setup.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +86 -33
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +6 -4
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
- package/dist/modes/interactive/components/copyable-text.js +3 -2
- package/dist/modes/interactive/components/copyable-text.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +1 -1
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +20 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +104 -109
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/smooth-streaming.d.ts.map +1 -1
- package/dist/modes/interactive/smooth-streaming.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +9 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/node-runtime/adapter-247RTYLS.js +16 -0
- package/dist/node-runtime/agent-session-services-KDMSPQDY.js +53 -0
- package/dist/node-runtime/{brave-UWDA3I22.js → brave-2AFFAXNN.js} +1 -1
- package/dist/node-runtime/{builtin-extensions-ZLAX7TUH.js → builtin-extensions-OX6KELNX.js} +9 -7
- package/dist/node-runtime/{chunk-QH6YL7VK.js → chunk-252ZVPPF.js} +3 -3
- package/dist/node-runtime/{chunk-PCEW76PM.js → chunk-2OIPYKLZ.js} +6 -6
- package/dist/node-runtime/{chunk-XBWPBZBN.js → chunk-2SWW7KMW.js} +1 -1
- package/dist/node-runtime/{chunk-UQUCFAJ3.js → chunk-2VIW3IMF.js} +40 -7
- package/dist/node-runtime/{chunk-UOEDI7RP.js → chunk-4KNKQGHM.js} +2 -2
- package/dist/node-runtime/{chunk-FQMM2EZ2.js → chunk-64XTQNLA.js} +29 -7
- package/dist/node-runtime/{chunk-NRKGMJYU.js → chunk-6O3IW3IA.js} +2 -2
- package/dist/node-runtime/{chunk-5ZQXRPMC.js → chunk-6ZZHGUSA.js} +2 -2
- package/dist/node-runtime/chunk-A2WO6WIN.js +1197 -0
- package/dist/node-runtime/{chunk-ZXSGTGJ6.js → chunk-APVM5NEU.js} +169 -148
- package/dist/node-runtime/{chunk-RC7DMV45.js → chunk-AYHH7YSD.js} +205 -144
- package/dist/node-runtime/{chunk-LWYIVUGV.js → chunk-B2IBAXNX.js} +48 -31
- package/dist/node-runtime/{chunk-M3LZLQW2.js → chunk-BDRGN3L2.js} +1 -0
- package/dist/node-runtime/{chunk-GJ2RDBRL.js → chunk-BYC6RKCN.js} +4 -2
- package/dist/node-runtime/{chunk-KWIYUUZK.js → chunk-C3P6Q3B2.js} +469 -283
- package/dist/node-runtime/{chunk-YCUZEGJG.js → chunk-DQSCFU7R.js} +17 -8
- package/dist/node-runtime/chunk-EBLAZVSA.js +4170 -0
- package/dist/node-runtime/{chunk-2KIPT4HJ.js → chunk-EPR2F3GU.js} +68 -20
- package/dist/node-runtime/{chunk-CSFI6YXL.js → chunk-ES6PBSIE.js} +1 -1
- package/dist/node-runtime/{chunk-IF24A3FH.js → chunk-EVM653DD.js} +4 -4
- package/dist/node-runtime/{chunk-HTFRRDSF.js → chunk-F2SMQ6ES.js} +3 -2
- package/dist/node-runtime/chunk-F2V2F4ZG.js +114 -0
- package/dist/node-runtime/chunk-FE3WZI7F.js +290 -0
- package/dist/node-runtime/{chunk-GYIXXQAO.js → chunk-FIRA54AC.js} +2 -5
- package/dist/node-runtime/{chunk-6VYZ5UFP.js → chunk-FLGEEH27.js} +1 -1
- package/dist/node-runtime/{chunk-5EFIU3OM.js → chunk-FTKEZL27.js} +1 -1
- package/dist/node-runtime/chunk-FY4A63RK.js +73 -0
- package/dist/node-runtime/chunk-FYIFPFXE.js +98 -0
- package/dist/node-runtime/{chunk-HMBGROQK.js → chunk-GLDXBBL6.js} +3 -3
- package/dist/node-runtime/{chunk-KWA4OC2J.js → chunk-H6YBCWKG.js} +1 -1
- package/dist/node-runtime/{chunk-2MI5OPMN.js → chunk-HNNHHJAB.js} +68 -50
- package/dist/node-runtime/{chunk-6XL67VVY.js → chunk-HUD2RFJW.js} +17 -2
- package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-I2H5QMWW.js} +3 -3
- package/dist/node-runtime/chunk-IAZSK7KK.js +108 -0
- package/dist/node-runtime/{chunk-2HHLJWGD.js → chunk-IHHTWSXN.js} +9 -9
- package/dist/node-runtime/{chunk-DAPBPCBP.js → chunk-IPP5BIV5.js} +25 -3
- package/dist/node-runtime/{chunk-QFWG2RVL.js → chunk-IXG6F4NT.js} +11 -0
- package/dist/node-runtime/{chunk-RDDAZOMU.js → chunk-JL4HYQXK.js} +1 -1
- package/dist/node-runtime/{chunk-CDVHZOOK.js → chunk-JQYNHAKX.js} +1 -1
- package/dist/node-runtime/{chunk-WF7PGWRZ.js → chunk-JWEVT363.js} +37 -28
- package/dist/node-runtime/{chunk-2HMIRK7W.js → chunk-LHV3V67B.js} +5 -5
- package/dist/node-runtime/{chunk-UAEOTO52.js → chunk-MNQXDFPV.js} +6 -2
- package/dist/node-runtime/{chunk-IJIFHRTB.js → chunk-MQPKUHRN.js} +165 -85
- package/dist/node-runtime/{chunk-MPKSOJBT.js → chunk-NHATCSOI.js} +4 -7
- package/dist/node-runtime/{chunk-RMQZU2YU.js → chunk-NNNR3QIY.js} +1 -1
- package/dist/node-runtime/{chunk-RWTKOC3B.js → chunk-QBTJG3UM.js} +1 -1
- package/dist/node-runtime/{chunk-E4D3IGP2.js → chunk-QNVMKNNN.js} +20 -17
- package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
- package/dist/node-runtime/{chunk-7S3T6YEA.js → chunk-R4WSB2MQ.js} +5 -5
- package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
- package/dist/node-runtime/{chunk-3XPLBUEM.js → chunk-RLGY2QIL.js} +49 -59
- package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
- package/dist/node-runtime/{chunk-AD6VXAO7.js → chunk-TCT6PCUR.js} +47 -115
- package/dist/node-runtime/chunk-U5F4IC7R.js +53 -0
- package/dist/node-runtime/{chunk-OCVIXVTZ.js → chunk-UBWW2PID.js} +13 -2
- package/dist/node-runtime/{chunk-HFVZUPFJ.js → chunk-UNUZICC4.js} +3 -3
- package/dist/node-runtime/{chunk-LQP3RB67.js → chunk-UYRKUKFE.js} +1 -1
- package/dist/node-runtime/{chunk-DSIKTUPW.js → chunk-VSUEAI7O.js} +2993 -3820
- package/dist/node-runtime/{chunk-NAY6UUQZ.js → chunk-WDIVLMOH.js} +1 -1
- package/dist/node-runtime/{chunk-E24EO34J.js → chunk-WPXUR3HE.js} +1 -1
- package/dist/node-runtime/{chunk-SLVOAQOY.js → chunk-WXYNALHD.js} +113 -1
- package/dist/node-runtime/{chunk-KJ6DWS3K.js → chunk-XEOCUEUJ.js} +121 -60
- package/dist/node-runtime/chunk-YD3IZAZ7.js +47 -0
- package/dist/node-runtime/chunk-YSB6URMT.js +41 -0
- package/dist/node-runtime/{chunk-VQFSUJJG.js → chunk-ZDJUR45D.js} +430 -129
- package/dist/node-runtime/{chunk-YDO2F2IA.js → chunk-ZEVFBFNF.js} +95 -142
- package/dist/node-runtime/chunk-ZIQUS5QO.js +180 -0
- package/dist/node-runtime/cli-runtime.js +4 -4
- package/dist/node-runtime/{command-6WDOYKS6.js → command-3HMSY6W2.js} +5 -5
- package/dist/node-runtime/{commands-NZLSOHPE.js → commands-D6A6H4TS.js} +11 -16
- package/dist/node-runtime/commands-OCSSEEWJ.js +37 -0
- package/dist/node-runtime/{config-QDD5PUE2.js → config-CU7M7BTK.js} +1 -1
- package/dist/node-runtime/{config-D4QUPAHX.js → config-DS7XLMEM.js} +2 -2
- package/dist/node-runtime/{direct-tool-executor-77GW4F5P.js → direct-tool-executor-2QJXVQD2.js} +8 -10
- package/dist/node-runtime/{exa-LL64QZR2.js → exa-6VBZNPGE.js} +1 -1
- package/dist/node-runtime/{export-html-VM4J2MNR.js → export-html-BRWF5AHI.js} +4 -4
- package/dist/node-runtime/{extension-input-E7BJZ35H.js → extension-input-VBBMX7YV.js} +5 -5
- package/dist/node-runtime/{extension-selector-WU42XDTU.js → extension-selector-T5AOG5XB.js} +5 -5
- package/dist/node-runtime/{extract-EQJE7FZZ.js → extract-BFX2N35A.js} +3 -3
- package/dist/node-runtime/{gateway-INAYBF4Q.js → gateway-6623C2U3.js} +61 -53
- package/dist/node-runtime/{gemini-search-35OCRFLN.js → gemini-search-C66QHDT6.js} +2 -2
- package/dist/node-runtime/{gemini-url-context-UQY3PHHW.js → gemini-url-context-T7DEK73R.js} +3 -3
- package/dist/node-runtime/{github-extract-F64RZOEA.js → github-extract-HOGE3D6F.js} +107 -38
- package/dist/node-runtime/{goal-NJEE5CTU.js → goal-AIHEDUYA.js} +5 -5
- package/dist/node-runtime/index.js +54 -48
- package/dist/node-runtime/{init-HS6NQXSK.js → init-JBQJIPYI.js} +3 -4
- package/dist/node-runtime/{install-cli-KL4UDDAD.js → install-cli-INGHIVBY.js} +30 -25
- package/dist/node-runtime/interactive-mode-FM5DNUSW.js +74 -0
- package/dist/node-runtime/{interactive-view-NGFAMHPW.js → interactive-view-K33PM4OS.js} +8 -8
- package/dist/node-runtime/{lsp-manager-3ASUSO4T.js → lsp-manager-S554V5HR.js} +240 -155
- package/dist/node-runtime/{lunr-browser-IR7TL3J7.js → lunr-browser-H4FDOR3C.js} +7 -7
- package/dist/node-runtime/lunr-computer-use-VDP2QNRQ.js +158 -0
- package/dist/node-runtime/{lunr-cron-LWIZJM2N.js → lunr-cron-LKVA5CZZ.js} +94 -79
- package/dist/node-runtime/main.js +42 -39
- package/dist/node-runtime/{mobile-commands-J7OJEKFO.js → mobile-commands-XT3NQXLD.js} +13 -12
- package/dist/node-runtime/{model-runtime-OO5HFLWE.js → model-runtime-MZ2JMDV4.js} +4 -4
- package/dist/node-runtime/{openai-search-B3MSNCQA.js → openai-search-K72LJDYN.js} +1 -1
- package/dist/node-runtime/{package-manager-cli-VYZM5WHN.js → package-manager-cli-CYM262SI.js} +20 -19
- package/dist/node-runtime/{parallel-AI2MNSCU.js → parallel-X724NCNU.js} +1 -1
- package/dist/node-runtime/{perplexity-QVJW3I35.js → perplexity-RDHQHVMK.js} +2 -2
- package/dist/node-runtime/{pi-intercom-QM53RLTS.js → pi-intercom-NHHEPBMI.js} +2 -2
- package/dist/node-runtime/{pi-mcp-adapter-5UKBZP44.js → pi-mcp-adapter-PP3GQJQ2.js} +98 -94
- package/dist/node-runtime/{pi-ollama-cloud-2F3Y2QNM.js → pi-ollama-cloud-4MNWIMFN.js} +11 -24
- package/dist/node-runtime/{pi-prompt-template-model-QWTCGLJU.js → pi-prompt-template-model-FTGELLS5.js} +32 -36
- package/dist/node-runtime/{pi-subagents-DNY7EAIG.js → pi-subagents-LT3CTO4E.js} +114 -116
- package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
- package/dist/node-runtime/{print-mode-XSFM26EL.js → print-mode-2XHN5SUA.js} +4 -3
- package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
- package/dist/node-runtime/{proxy-modes-LGEUYD7R.js → proxy-modes-VEGC6QG5.js} +9 -13
- package/dist/node-runtime/rpc-entry.js +42 -39
- package/dist/node-runtime/{rpc-mode-O3XV4SID.js → rpc-mode-32DHJPEJ.js} +4 -4
- package/dist/node-runtime/{runtime-4VA6JKNF.js → runtime-EDUUGAQD.js} +56 -46
- package/dist/node-runtime/runtime-UGXM4NPQ.js +21 -0
- package/dist/node-runtime/{runtime-bridges-VRDDR73P.js → runtime-bridges-DNKMNJCF.js} +8 -7
- package/dist/node-runtime/{service-MDQIPQ26.js → service-IHLGFLBT.js} +6 -4
- package/dist/node-runtime/{session-handoff-GWARVEWT.js → session-handoff-LNSPDTKY.js} +4 -4
- package/dist/node-runtime/{session-manager-JB5J6XBN.js → session-manager-YIFIAVGC.js} +3 -3
- package/dist/node-runtime/{session-selector-GIM4DHQ2.js → session-selector-I73U3EIO.js} +7 -7
- package/dist/node-runtime/{settings-manager-J4SPQPDJ.js → settings-manager-P2TKGYTR.js} +6 -5
- package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
- package/dist/node-runtime/{setup-CQ2NLVK5.js → setup-OLQ4GXWS.js} +22 -21
- package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
- package/dist/node-runtime/{subagent-executor-KZZQGAKV.js → subagent-executor-Q5F7DBVM.js} +141 -62
- package/dist/node-runtime/{tavily-WEZFVFP7.js → tavily-KZBFYQB6.js} +1 -1
- package/dist/node-runtime/{theme-UOO5RVFN.js → theme-YLVZKKZD.js} +2 -2
- package/dist/node-runtime/{trust-manager-MMISNCYO.js → trust-manager-ZCU76D23.js} +2 -2
- package/dist/node-runtime/{update-cli-GTFJC7XK.js → update-cli-F3XXJANQ.js} +7 -6
- package/dist/node-runtime/{usage-service-LFB2SWYV.js → usage-service-CPAGBED5.js} +1 -1
- package/dist/node-runtime/{video-extract-OOZHR7SU.js → video-extract-UPKYIBW3.js} +3 -3
- package/dist/node-runtime/workflow-ICDI4N3J.js +767 -0
- package/dist/node-runtime/{youtube-extract-FNPAUNHU.js → youtube-extract-77NT7FWH.js} +4 -4
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js +25 -10
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts +2 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js +12 -0
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/paths.d.ts +4 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +33 -2
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/sanitize-terminal-text.d.ts +7 -0
- package/dist/utils/sanitize-terminal-text.d.ts.map +1 -0
- package/dist/utils/sanitize-terminal-text.js +67 -0
- package/dist/utils/sanitize-terminal-text.js.map +1 -0
- package/docs/browser.md +1 -1
- package/docs/computer-use.md +362 -0
- package/docs/custom-provider.md +3 -3
- package/docs/extensions.md +8 -4
- package/docs/features.md +22 -12
- package/docs/keybindings.md +1 -1
- package/docs/models.md +5 -5
- package/docs/packages.md +1 -1
- package/docs/providers.md +2 -2
- package/docs/rpc.md +7 -7
- package/docs/security.md +10 -5
- package/docs/sessions.md +2 -2
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +7 -7
- package/docs/themes.md +1 -1
- package/docs/usage.md +1 -1
- package/examples/extensions/auto-commit-on-exit.ts +1 -1
- package/examples/extensions/bash-spawn-hook.ts +1 -1
- package/examples/extensions/built-in-tool-renderer.ts +1 -1
- package/examples/extensions/claude-rules.ts +1 -1
- package/examples/extensions/commands.ts +1 -1
- package/examples/extensions/custom-compaction.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/doom-overlay/index.ts +1 -1
- package/examples/extensions/git-merge-and-resolve.ts +2 -2
- package/examples/extensions/gondolin/index.ts +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/hidden-thinking-label.ts +1 -1
- package/examples/extensions/inline-bash.ts +2 -2
- package/examples/extensions/input-transform-streaming.ts +2 -2
- package/examples/extensions/input-transform.ts +2 -2
- package/examples/extensions/interactive-shell.ts +1 -1
- package/examples/extensions/kimi-deferred-tools.ts +1 -1
- package/examples/extensions/mac-system-theme.ts +1 -1
- package/examples/extensions/minimal-mode.ts +1 -1
- package/examples/extensions/modal-editor.ts +1 -1
- package/examples/extensions/model-status.ts +1 -1
- package/examples/extensions/notify.ts +3 -3
- package/examples/extensions/overlay-qa-tests.ts +1 -1
- package/examples/extensions/overlay-test.ts +1 -1
- package/examples/extensions/pirate.ts +1 -1
- package/examples/extensions/preset.ts +3 -3
- package/examples/extensions/project-trust.ts +4 -4
- package/examples/extensions/prompt-customizer.ts +1 -1
- package/examples/extensions/rainbow-editor.ts +1 -1
- package/examples/extensions/rpc-demo.ts +1 -1
- package/examples/extensions/sandbox/index.ts +7 -7
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/shutdown-command.ts +5 -5
- package/examples/extensions/ssh.ts +2 -2
- package/examples/extensions/subagent/README.md +3 -3
- package/examples/extensions/subagent/index.ts +2 -2
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/tool-override.ts +1 -1
- package/examples/extensions/tools.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/extensions/working-indicator.ts +1 -1
- package/examples/extensions/working-message-test.ts +1 -1
- package/examples/sdk/01-minimal.ts +1 -1
- package/examples/sdk/03-custom-prompt.ts +1 -1
- package/examples/sdk/04-skills.ts +1 -1
- package/examples/sdk/06-extensions.ts +2 -2
- package/examples/sdk/08-prompt-templates.ts +1 -1
- package/install-lock/package-lock.json +3841 -0
- package/install-lock/package.json +18 -0
- package/native/computer-use/LICENSE.md +21 -0
- package/npm-shrinkwrap.json +3858 -0
- package/package.json +15 -9
- package/dist/modes/interactive/components/exit-card.d.ts +0 -22
- package/dist/modes/interactive/components/exit-card.d.ts.map +0 -1
- package/dist/modes/interactive/components/exit-card.js +0 -69
- package/dist/modes/interactive/components/exit-card.js.map +0 -1
- package/dist/node-runtime/agent-session-services-YXXFCP5J.js +0 -49
- package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
- package/dist/node-runtime/chunk-4TLO4PO2.js +0 -3427
- package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
- package/dist/node-runtime/chunk-OVX6X377.js +0 -50
- package/dist/node-runtime/chunk-QTU6AKNJ.js +0 -773
- package/dist/node-runtime/chunk-TORR5XBV.js +0 -356
- package/dist/node-runtime/commands-QC6VUZJQ.js +0 -36
- package/dist/node-runtime/interactive-mode-Z5M7WYYZ.js +0 -72
- package/dist/node-runtime/mcp-auth-flow-QIXHW6QN.js +0 -32
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, realpath, rm } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
5
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
6
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
7
|
+
import { MacRuntime } from "./macos-runtime.js";
|
|
8
|
+
import { CUA_VERSION, installRuntime, runtimeEnvironment } from "./runtime.js";
|
|
9
|
+
import { assertInteractiveDesktop } from "./windows-desktop.js";
|
|
10
|
+
export class DriverCallError extends Error {
|
|
11
|
+
phase;
|
|
12
|
+
dispatched;
|
|
13
|
+
constructor(phase, dispatched) {
|
|
14
|
+
super(phase === "adapter_preflight" ? "Computer adapter preflight failed." : "Computer native request failed.");
|
|
15
|
+
this.phase = phase;
|
|
16
|
+
this.dispatched = dispatched;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class CuaAdapter {
|
|
20
|
+
client;
|
|
21
|
+
transport;
|
|
22
|
+
mac;
|
|
23
|
+
stateDirectory;
|
|
24
|
+
connecting;
|
|
25
|
+
closing;
|
|
26
|
+
abort = new AbortController();
|
|
27
|
+
processObserver;
|
|
28
|
+
setProcessObserver(observer) {
|
|
29
|
+
this.processObserver = observer;
|
|
30
|
+
}
|
|
31
|
+
async connect(signal) {
|
|
32
|
+
const { command, app } = await installRuntime(signal);
|
|
33
|
+
signal.throwIfAborted();
|
|
34
|
+
let args = ["mcp", "--direct", "--embedded", "--no-overlay"];
|
|
35
|
+
if (app) {
|
|
36
|
+
this.mac = new MacRuntime();
|
|
37
|
+
const socket = await this.mac.start(app, signal);
|
|
38
|
+
args = ["mcp", "--embedded", "--socket", socket, "--no-overlay"];
|
|
39
|
+
}
|
|
40
|
+
signal.throwIfAborted();
|
|
41
|
+
const state = await mkdtemp(join(await realpath(tmpdir()), "lunr-cua-client-"));
|
|
42
|
+
this.stateDirectory = state;
|
|
43
|
+
const appData = join(state, "AppData");
|
|
44
|
+
await mkdir(appData);
|
|
45
|
+
signal.throwIfAborted();
|
|
46
|
+
this.transport = new StdioClientTransport({
|
|
47
|
+
command,
|
|
48
|
+
args,
|
|
49
|
+
stderr: "pipe",
|
|
50
|
+
env: {
|
|
51
|
+
...runtimeEnvironment(),
|
|
52
|
+
HOME: state,
|
|
53
|
+
USERPROFILE: state,
|
|
54
|
+
APPDATA: appData,
|
|
55
|
+
LOCALAPPDATA: appData,
|
|
56
|
+
XDG_CONFIG_HOME: appData,
|
|
57
|
+
XDG_STATE_HOME: appData,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
// Drain diagnostics without retaining desktop or runtime data in session history.
|
|
61
|
+
this.transport.stderr?.on("data", () => { });
|
|
62
|
+
this.client = new Client({ name: "lunr-computer-use", version: CUA_VERSION });
|
|
63
|
+
await this.client.connect(this.transport, { timeout: 15000, signal });
|
|
64
|
+
signal.throwIfAborted();
|
|
65
|
+
if (this.client.getServerVersion()?.version !== CUA_VERSION)
|
|
66
|
+
throw new Error("Computer runtime version mismatch.");
|
|
67
|
+
const pids = [this.transport.pid, ...(this.mac ? [this.mac.processId] : [])];
|
|
68
|
+
for (const pid of pids) {
|
|
69
|
+
if (typeof pid !== "number" || !Number.isInteger(pid) || pid < 1)
|
|
70
|
+
throw new Error("Computer runtime process identity is missing. Input refused.");
|
|
71
|
+
await this.processObserver?.(pid);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async call(name, args, signal) {
|
|
75
|
+
const combined = AbortSignal.any([this.abort.signal, ...(signal ? [signal] : [])]);
|
|
76
|
+
combined.throwIfAborted();
|
|
77
|
+
let dispatched = false;
|
|
78
|
+
try {
|
|
79
|
+
await assertInteractiveDesktop(combined);
|
|
80
|
+
combined.throwIfAborted();
|
|
81
|
+
this.connecting ??= this.connect(AbortSignal.any([combined, AbortSignal.timeout(60000)]));
|
|
82
|
+
await this.connecting;
|
|
83
|
+
combined.throwIfAborted();
|
|
84
|
+
if (!this.client)
|
|
85
|
+
throw new Error("Computer connection closed.");
|
|
86
|
+
dispatched = true;
|
|
87
|
+
return await this.client.callTool({ name, arguments: args }, undefined, {
|
|
88
|
+
timeout: name === "launch_app" ? 45000 : 15000,
|
|
89
|
+
signal: combined,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
const wasCancelled = combined.aborted;
|
|
94
|
+
try {
|
|
95
|
+
await this.close();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
/* The workflow retains the lease if shutdown is unconfirmed. */
|
|
99
|
+
}
|
|
100
|
+
if (wasCancelled)
|
|
101
|
+
throw error;
|
|
102
|
+
throw new DriverCallError(dispatched ? "native_request" : "adapter_preflight", dispatched);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
close() {
|
|
106
|
+
this.abort.abort();
|
|
107
|
+
this.closing ??= this.stop();
|
|
108
|
+
return this.closing;
|
|
109
|
+
}
|
|
110
|
+
async stop() {
|
|
111
|
+
await this.connecting?.catch(() => undefined);
|
|
112
|
+
const pid = this.transport?.pid;
|
|
113
|
+
await this.client?.close();
|
|
114
|
+
await this.transport?.close();
|
|
115
|
+
if (pid) {
|
|
116
|
+
const deadline = Date.now() + 5000;
|
|
117
|
+
for (;;) {
|
|
118
|
+
try {
|
|
119
|
+
process.kill(pid, 0);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (error instanceof Error && "code" in error && error.code === "ESRCH")
|
|
123
|
+
break;
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
if (Date.now() >= deadline)
|
|
127
|
+
throw new Error("Owned computer process shutdown is unconfirmed. Desktop lease retained.");
|
|
128
|
+
await delay(50);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
await this.mac?.close();
|
|
132
|
+
if (this.stateDirectory)
|
|
133
|
+
await rm(this.stateDirectory, { recursive: true, force: true });
|
|
134
|
+
this.client = undefined;
|
|
135
|
+
this.transport = undefined;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/core/computer-use/adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir, mkdtemp, realpath, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { MacRuntime } from \"./macos-runtime.ts\";\nimport { CUA_VERSION, installRuntime, runtimeEnvironment } from \"./runtime.ts\";\nimport { assertInteractiveDesktop } from \"./windows-desktop.ts\";\n\nexport type DriverReply = Awaited<ReturnType<Client[\"callTool\"]>>;\nexport class DriverCallError extends Error {\n\treadonly phase: \"adapter_preflight\" | \"native_request\";\n\treadonly dispatched: boolean;\n\tconstructor(phase: \"adapter_preflight\" | \"native_request\", dispatched: boolean) {\n\t\tsuper(phase === \"adapter_preflight\" ? \"Computer adapter preflight failed.\" : \"Computer native request failed.\");\n\t\tthis.phase = phase;\n\t\tthis.dispatched = dispatched;\n\t}\n}\nexport interface ComputerDriver {\n\tcall(name: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<DriverReply>;\n\tclose(): Promise<void>;\n\tsetProcessObserver?(observer: (pid: number) => Promise<void>): void;\n}\n\nexport class CuaAdapter implements ComputerDriver {\n\tprivate client?: Client;\n\tprivate transport?: StdioClientTransport;\n\tprivate mac?: MacRuntime;\n\tprivate stateDirectory?: string;\n\tprivate connecting?: Promise<void>;\n\tprivate closing?: Promise<void>;\n\tprivate readonly abort = new AbortController();\n\tprivate processObserver?: (pid: number) => Promise<void>;\n\tsetProcessObserver(observer: (pid: number) => Promise<void>): void {\n\t\tthis.processObserver = observer;\n\t}\n\n\tprivate async connect(signal: AbortSignal): Promise<void> {\n\t\tconst { command, app } = await installRuntime(signal);\n\t\tsignal.throwIfAborted();\n\t\tlet args = [\"mcp\", \"--direct\", \"--embedded\", \"--no-overlay\"];\n\t\tif (app) {\n\t\t\tthis.mac = new MacRuntime();\n\t\t\tconst socket = await this.mac.start(app, signal);\n\t\t\targs = [\"mcp\", \"--embedded\", \"--socket\", socket, \"--no-overlay\"];\n\t\t}\n\t\tsignal.throwIfAborted();\n\t\tconst state = await mkdtemp(join(await realpath(tmpdir()), \"lunr-cua-client-\"));\n\t\tthis.stateDirectory = state;\n\t\tconst appData = join(state, \"AppData\");\n\t\tawait mkdir(appData);\n\t\tsignal.throwIfAborted();\n\t\tthis.transport = new StdioClientTransport({\n\t\t\tcommand,\n\t\t\targs,\n\t\t\tstderr: \"pipe\",\n\t\t\tenv: {\n\t\t\t\t...runtimeEnvironment(),\n\t\t\t\tHOME: state,\n\t\t\t\tUSERPROFILE: state,\n\t\t\t\tAPPDATA: appData,\n\t\t\t\tLOCALAPPDATA: appData,\n\t\t\t\tXDG_CONFIG_HOME: appData,\n\t\t\t\tXDG_STATE_HOME: appData,\n\t\t\t},\n\t\t});\n\t\t// Drain diagnostics without retaining desktop or runtime data in session history.\n\t\tthis.transport.stderr?.on(\"data\", () => {});\n\t\tthis.client = new Client({ name: \"lunr-computer-use\", version: CUA_VERSION });\n\t\tawait this.client.connect(this.transport, { timeout: 15000, signal });\n\t\tsignal.throwIfAborted();\n\t\tif (this.client.getServerVersion()?.version !== CUA_VERSION)\n\t\t\tthrow new Error(\"Computer runtime version mismatch.\");\n\t\tconst pids = [this.transport.pid, ...(this.mac ? [this.mac.processId] : [])];\n\t\tfor (const pid of pids) {\n\t\t\tif (typeof pid !== \"number\" || !Number.isInteger(pid) || pid < 1)\n\t\t\t\tthrow new Error(\"Computer runtime process identity is missing. Input refused.\");\n\t\t\tawait this.processObserver?.(pid);\n\t\t}\n\t}\n\n\tasync call(name: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<DriverReply> {\n\t\tconst combined = AbortSignal.any([this.abort.signal, ...(signal ? [signal] : [])]);\n\t\tcombined.throwIfAborted();\n\t\tlet dispatched = false;\n\t\ttry {\n\t\t\tawait assertInteractiveDesktop(combined);\n\t\t\tcombined.throwIfAborted();\n\t\t\tthis.connecting ??= this.connect(AbortSignal.any([combined, AbortSignal.timeout(60000)]));\n\t\t\tawait this.connecting;\n\t\t\tcombined.throwIfAborted();\n\t\t\tif (!this.client) throw new Error(\"Computer connection closed.\");\n\t\t\tdispatched = true;\n\t\t\treturn await this.client.callTool({ name, arguments: args }, undefined, {\n\t\t\t\ttimeout: name === \"launch_app\" ? 45000 : 15000,\n\t\t\t\tsignal: combined,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconst wasCancelled = combined.aborted;\n\t\t\ttry {\n\t\t\t\tawait this.close();\n\t\t\t} catch {\n\t\t\t\t/* The workflow retains the lease if shutdown is unconfirmed. */\n\t\t\t}\n\t\t\tif (wasCancelled) throw error;\n\t\t\tthrow new DriverCallError(dispatched ? \"native_request\" : \"adapter_preflight\", dispatched);\n\t\t}\n\t}\n\n\tclose(): Promise<void> {\n\t\tthis.abort.abort();\n\t\tthis.closing ??= this.stop();\n\t\treturn this.closing;\n\t}\n\n\tprivate async stop(): Promise<void> {\n\t\tawait this.connecting?.catch(() => undefined);\n\t\tconst pid = this.transport?.pid;\n\t\tawait this.client?.close();\n\t\tawait this.transport?.close();\n\t\tif (pid) {\n\t\t\tconst deadline = Date.now() + 5000;\n\t\t\tfor (;;) {\n\t\t\t\ttry {\n\t\t\t\t\tprocess.kill(pid, 0);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"ESRCH\") break;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (Date.now() >= deadline)\n\t\t\t\t\tthrow new Error(\"Owned computer process shutdown is unconfirmed. Desktop lease retained.\");\n\t\t\t\tawait delay(50);\n\t\t\t}\n\t\t}\n\t\tawait this.mac?.close();\n\t\tif (this.stateDirectory) await rm(this.stateDirectory, { recursive: true, force: true });\n\t\tthis.client = undefined;\n\t\tthis.transport = undefined;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ImageContent } from "@ashx-j/lunr-ai";
|
|
2
|
+
export interface ImageRegion {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function screenshotDimensions(image: ImageContent): {
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function prepareComputerImage(image: ImageContent, crop?: ImageRegion): Promise<{
|
|
13
|
+
fingerprint: string;
|
|
14
|
+
image: {
|
|
15
|
+
type: "image";
|
|
16
|
+
data: string;
|
|
17
|
+
mimeType: string;
|
|
18
|
+
};
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
sourceWidth: number;
|
|
22
|
+
sourceHeight: number;
|
|
23
|
+
region: ImageRegion;
|
|
24
|
+
scaleX: number;
|
|
25
|
+
scaleY: number;
|
|
26
|
+
}>;
|
|
27
|
+
//# sourceMappingURL=image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/image.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAI1D,MAAM,WAAW,WAAW;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAW3F;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,WAAW;;;;;;;;;;;;;;GAuEjF","sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { ImageContent } from \"@ashx-j/lunr-ai\";\nimport { resizeImage } from \"../../utils/image-resize.ts\";\nimport { loadPhoton } from \"../../utils/photon.ts\";\n\nexport interface ImageRegion {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\nexport function screenshotDimensions(image: ImageContent): { width: number; height: number } {\n\tif (image.mimeType !== \"image/png\" || image.data.length > 64 * 1024 * 1024)\n\t\tthrow new Error(\"Expected a bounded PNG screenshot.\");\n\tconst bytes = Buffer.from(image.data, \"base64\");\n\tif (bytes.length < 24 || !bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])))\n\t\tthrow new Error(\"Invalid screenshot PNG.\");\n\tconst width = bytes.readUInt32BE(16);\n\tconst height = bytes.readUInt32BE(20);\n\tif (!width || !height || width > 16384 || height > 16384 || width * height > 40_000_000)\n\t\tthrow new Error(\"Screenshot dimensions exceed the supported capture budget.\");\n\treturn { width, height };\n}\n\nexport async function prepareComputerImage(image: ImageContent, crop?: ImageRegion) {\n\tconst source = screenshotDimensions(image);\n\tconst region = crop ?? { x: 0, y: 0, ...source };\n\tif (\n\t\t![region.x, region.y, region.width, region.height].every(Number.isInteger) ||\n\t\tregion.x < 0 ||\n\t\tregion.y < 0 ||\n\t\tregion.width < 1 ||\n\t\tregion.height < 1 ||\n\t\tregion.x + region.width > source.width ||\n\t\tregion.y + region.height > source.height\n\t)\n\t\tthrow new Error(\"Crop is outside the captured image.\");\n\tlet bytes: Uint8Array = Buffer.from(image.data, \"base64\");\n\tlet fingerprint: string | undefined;\n\tif (crop) {\n\t\tconst photon = await loadPhoton();\n\t\tif (!photon) throw new Error(\"Image processing is unavailable; crop refused.\");\n\t\tconst original = photon.PhotonImage.new_from_byteslice(bytes);\n\t\ttry {\n\t\t\tif (original.get_width() !== source.width || original.get_height() !== source.height)\n\t\t\t\tthrow new Error(\"Decoded screenshot dimensions changed.\");\n\t\t\tfingerprint = createHash(\"sha256\")\n\t\t\t\t.update(`${source.width}x${source.height}:`)\n\t\t\t\t.update(original.get_raw_pixels())\n\t\t\t\t.digest(\"hex\");\n\t\t\tconst cropped = photon.crop(original, region.x, region.y, region.x + region.width, region.y + region.height);\n\t\t\ttry {\n\t\t\t\tbytes = cropped.get_bytes();\n\t\t\t} finally {\n\t\t\t\tcropped.free();\n\t\t\t}\n\t\t} finally {\n\t\t\toriginal.free();\n\t\t}\n\t}\n\tconst ratio = Math.min(\n\t\t1,\n\t\t1280 / Math.max(region.width, region.height),\n\t\tMath.sqrt(1_000_000 / (region.width * region.height)),\n\t);\n\tconst resized = await resizeImage(bytes, \"image/png\", {\n\t\tmaxWidth: Math.max(1, Math.floor(region.width * ratio)),\n\t\tmaxHeight: Math.max(1, Math.floor(region.height * ratio)),\n\t\tmaxBytes: 1.5 * 1024 * 1024,\n\t\tincludePixelFingerprint: !crop,\n\t});\n\tif (\n\t\t!resized ||\n\t\tresized.originalWidth !== region.width ||\n\t\tresized.originalHeight !== region.height ||\n\t\tresized.width < 1 ||\n\t\tresized.height < 1 ||\n\t\tresized.width > 1280 ||\n\t\tresized.height > 1280 ||\n\t\tresized.width * resized.height > 1_000_000\n\t)\n\t\tthrow new Error(\"Screenshot could not be decoded within the image budget.\");\n\tfingerprint ??= resized.fingerprint;\n\tif (!fingerprint) throw new Error(\"Screenshot pixel identity could not be verified.\");\n\treturn {\n\t\tfingerprint,\n\t\timage: { type: \"image\", data: resized.data, mimeType: resized.mimeType } satisfies ImageContent,\n\t\twidth: resized.width,\n\t\theight: resized.height,\n\t\tsourceWidth: source.width,\n\t\tsourceHeight: source.height,\n\t\tregion,\n\t\tscaleX: region.width / resized.width,\n\t\tscaleY: region.height / resized.height,\n\t};\n}\n"]}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { resizeImage } from "../../utils/image-resize.js";
|
|
3
|
+
import { loadPhoton } from "../../utils/photon.js";
|
|
4
|
+
export function screenshotDimensions(image) {
|
|
5
|
+
if (image.mimeType !== "image/png" || image.data.length > 64 * 1024 * 1024)
|
|
6
|
+
throw new Error("Expected a bounded PNG screenshot.");
|
|
7
|
+
const bytes = Buffer.from(image.data, "base64");
|
|
8
|
+
if (bytes.length < 24 || !bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])))
|
|
9
|
+
throw new Error("Invalid screenshot PNG.");
|
|
10
|
+
const width = bytes.readUInt32BE(16);
|
|
11
|
+
const height = bytes.readUInt32BE(20);
|
|
12
|
+
if (!width || !height || width > 16384 || height > 16384 || width * height > 40_000_000)
|
|
13
|
+
throw new Error("Screenshot dimensions exceed the supported capture budget.");
|
|
14
|
+
return { width, height };
|
|
15
|
+
}
|
|
16
|
+
export async function prepareComputerImage(image, crop) {
|
|
17
|
+
const source = screenshotDimensions(image);
|
|
18
|
+
const region = crop ?? { x: 0, y: 0, ...source };
|
|
19
|
+
if (![region.x, region.y, region.width, region.height].every(Number.isInteger) ||
|
|
20
|
+
region.x < 0 ||
|
|
21
|
+
region.y < 0 ||
|
|
22
|
+
region.width < 1 ||
|
|
23
|
+
region.height < 1 ||
|
|
24
|
+
region.x + region.width > source.width ||
|
|
25
|
+
region.y + region.height > source.height)
|
|
26
|
+
throw new Error("Crop is outside the captured image.");
|
|
27
|
+
let bytes = Buffer.from(image.data, "base64");
|
|
28
|
+
let fingerprint;
|
|
29
|
+
if (crop) {
|
|
30
|
+
const photon = await loadPhoton();
|
|
31
|
+
if (!photon)
|
|
32
|
+
throw new Error("Image processing is unavailable; crop refused.");
|
|
33
|
+
const original = photon.PhotonImage.new_from_byteslice(bytes);
|
|
34
|
+
try {
|
|
35
|
+
if (original.get_width() !== source.width || original.get_height() !== source.height)
|
|
36
|
+
throw new Error("Decoded screenshot dimensions changed.");
|
|
37
|
+
fingerprint = createHash("sha256")
|
|
38
|
+
.update(`${source.width}x${source.height}:`)
|
|
39
|
+
.update(original.get_raw_pixels())
|
|
40
|
+
.digest("hex");
|
|
41
|
+
const cropped = photon.crop(original, region.x, region.y, region.x + region.width, region.y + region.height);
|
|
42
|
+
try {
|
|
43
|
+
bytes = cropped.get_bytes();
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
cropped.free();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
original.free();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const ratio = Math.min(1, 1280 / Math.max(region.width, region.height), Math.sqrt(1_000_000 / (region.width * region.height)));
|
|
54
|
+
const resized = await resizeImage(bytes, "image/png", {
|
|
55
|
+
maxWidth: Math.max(1, Math.floor(region.width * ratio)),
|
|
56
|
+
maxHeight: Math.max(1, Math.floor(region.height * ratio)),
|
|
57
|
+
maxBytes: 1.5 * 1024 * 1024,
|
|
58
|
+
includePixelFingerprint: !crop,
|
|
59
|
+
});
|
|
60
|
+
if (!resized ||
|
|
61
|
+
resized.originalWidth !== region.width ||
|
|
62
|
+
resized.originalHeight !== region.height ||
|
|
63
|
+
resized.width < 1 ||
|
|
64
|
+
resized.height < 1 ||
|
|
65
|
+
resized.width > 1280 ||
|
|
66
|
+
resized.height > 1280 ||
|
|
67
|
+
resized.width * resized.height > 1_000_000)
|
|
68
|
+
throw new Error("Screenshot could not be decoded within the image budget.");
|
|
69
|
+
fingerprint ??= resized.fingerprint;
|
|
70
|
+
if (!fingerprint)
|
|
71
|
+
throw new Error("Screenshot pixel identity could not be verified.");
|
|
72
|
+
return {
|
|
73
|
+
fingerprint,
|
|
74
|
+
image: { type: "image", data: resized.data, mimeType: resized.mimeType },
|
|
75
|
+
width: resized.width,
|
|
76
|
+
height: resized.height,
|
|
77
|
+
sourceWidth: source.width,
|
|
78
|
+
sourceHeight: source.height,
|
|
79
|
+
region,
|
|
80
|
+
scaleX: region.width / resized.width,
|
|
81
|
+
scaleY: region.height / resized.height,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../../src/core/computer-use/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AASnD,MAAM,UAAU,oBAAoB,CAAC,KAAmB,EAAqC;IAC5F,IAAI,KAAK,CAAC,QAAQ,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;QACzE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChD,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACpG,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,KAAK,GAAG,KAAK,IAAI,MAAM,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,GAAG,UAAU;QACtF,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAAA,CACzB;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAmB,EAAE,IAAkB,EAAE;IACnF,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;IACjD,IACC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;QAC1E,MAAM,CAAC,CAAC,GAAG,CAAC;QACZ,MAAM,CAAC,CAAC,GAAG,CAAC;QACZ,MAAM,CAAC,KAAK,GAAG,CAAC;QAChB,MAAM,CAAC,MAAM,GAAG,CAAC;QACjB,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK;QACtC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM;QAExC,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACxD,IAAI,KAAK,GAAe,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1D,IAAI,WAA+B,CAAC;IACpC,IAAI,IAAI,EAAE,CAAC;QACV,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC/E,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC9D,IAAI,CAAC;YACJ,IAAI,QAAQ,CAAC,SAAS,EAAE,KAAK,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,EAAE,KAAK,MAAM,CAAC,MAAM;gBACnF,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAC3D,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC;iBAChC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;iBAC3C,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;iBACjC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAC7G,IAAI,CAAC;gBACJ,KAAK,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YAC7B,CAAC;oBAAS,CAAC;gBACV,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,QAAQ,CAAC,IAAI,EAAE,CAAC;QACjB,CAAC;IACF,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACrB,CAAC,EACD,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAC5C,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CACrD,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE;QACrD,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;QACvD,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;QACzD,QAAQ,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI;QAC3B,uBAAuB,EAAE,CAAC,IAAI;KAC9B,CAAC,CAAC;IACH,IACC,CAAC,OAAO;QACR,OAAO,CAAC,aAAa,KAAK,MAAM,CAAC,KAAK;QACtC,OAAO,CAAC,cAAc,KAAK,MAAM,CAAC,MAAM;QACxC,OAAO,CAAC,KAAK,GAAG,CAAC;QACjB,OAAO,CAAC,MAAM,GAAG,CAAC;QAClB,OAAO,CAAC,KAAK,GAAG,IAAI;QACpB,OAAO,CAAC,MAAM,GAAG,IAAI;QACrB,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS;QAE1C,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC7E,WAAW,KAAK,OAAO,CAAC,WAAW,CAAC;IACpC,IAAI,CAAC,WAAW;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtF,OAAO;QACN,WAAW;QACX,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAyB;QAC/F,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,MAAM,CAAC,KAAK;QACzB,YAAY,EAAE,MAAM,CAAC,MAAM;QAC3B,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK;QACpC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM;KACtC,CAAC;AAAA,CACF","sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { ImageContent } from \"@ashx-j/lunr-ai\";\nimport { resizeImage } from \"../../utils/image-resize.ts\";\nimport { loadPhoton } from \"../../utils/photon.ts\";\n\nexport interface ImageRegion {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\nexport function screenshotDimensions(image: ImageContent): { width: number; height: number } {\n\tif (image.mimeType !== \"image/png\" || image.data.length > 64 * 1024 * 1024)\n\t\tthrow new Error(\"Expected a bounded PNG screenshot.\");\n\tconst bytes = Buffer.from(image.data, \"base64\");\n\tif (bytes.length < 24 || !bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])))\n\t\tthrow new Error(\"Invalid screenshot PNG.\");\n\tconst width = bytes.readUInt32BE(16);\n\tconst height = bytes.readUInt32BE(20);\n\tif (!width || !height || width > 16384 || height > 16384 || width * height > 40_000_000)\n\t\tthrow new Error(\"Screenshot dimensions exceed the supported capture budget.\");\n\treturn { width, height };\n}\n\nexport async function prepareComputerImage(image: ImageContent, crop?: ImageRegion) {\n\tconst source = screenshotDimensions(image);\n\tconst region = crop ?? { x: 0, y: 0, ...source };\n\tif (\n\t\t![region.x, region.y, region.width, region.height].every(Number.isInteger) ||\n\t\tregion.x < 0 ||\n\t\tregion.y < 0 ||\n\t\tregion.width < 1 ||\n\t\tregion.height < 1 ||\n\t\tregion.x + region.width > source.width ||\n\t\tregion.y + region.height > source.height\n\t)\n\t\tthrow new Error(\"Crop is outside the captured image.\");\n\tlet bytes: Uint8Array = Buffer.from(image.data, \"base64\");\n\tlet fingerprint: string | undefined;\n\tif (crop) {\n\t\tconst photon = await loadPhoton();\n\t\tif (!photon) throw new Error(\"Image processing is unavailable; crop refused.\");\n\t\tconst original = photon.PhotonImage.new_from_byteslice(bytes);\n\t\ttry {\n\t\t\tif (original.get_width() !== source.width || original.get_height() !== source.height)\n\t\t\t\tthrow new Error(\"Decoded screenshot dimensions changed.\");\n\t\t\tfingerprint = createHash(\"sha256\")\n\t\t\t\t.update(`${source.width}x${source.height}:`)\n\t\t\t\t.update(original.get_raw_pixels())\n\t\t\t\t.digest(\"hex\");\n\t\t\tconst cropped = photon.crop(original, region.x, region.y, region.x + region.width, region.y + region.height);\n\t\t\ttry {\n\t\t\t\tbytes = cropped.get_bytes();\n\t\t\t} finally {\n\t\t\t\tcropped.free();\n\t\t\t}\n\t\t} finally {\n\t\t\toriginal.free();\n\t\t}\n\t}\n\tconst ratio = Math.min(\n\t\t1,\n\t\t1280 / Math.max(region.width, region.height),\n\t\tMath.sqrt(1_000_000 / (region.width * region.height)),\n\t);\n\tconst resized = await resizeImage(bytes, \"image/png\", {\n\t\tmaxWidth: Math.max(1, Math.floor(region.width * ratio)),\n\t\tmaxHeight: Math.max(1, Math.floor(region.height * ratio)),\n\t\tmaxBytes: 1.5 * 1024 * 1024,\n\t\tincludePixelFingerprint: !crop,\n\t});\n\tif (\n\t\t!resized ||\n\t\tresized.originalWidth !== region.width ||\n\t\tresized.originalHeight !== region.height ||\n\t\tresized.width < 1 ||\n\t\tresized.height < 1 ||\n\t\tresized.width > 1280 ||\n\t\tresized.height > 1280 ||\n\t\tresized.width * resized.height > 1_000_000\n\t)\n\t\tthrow new Error(\"Screenshot could not be decoded within the image budget.\");\n\tfingerprint ??= resized.fingerprint;\n\tif (!fingerprint) throw new Error(\"Screenshot pixel identity could not be verified.\");\n\treturn {\n\t\tfingerprint,\n\t\timage: { type: \"image\", data: resized.data, mimeType: resized.mimeType } satisfies ImageContent,\n\t\twidth: resized.width,\n\t\theight: resized.height,\n\t\tsourceWidth: source.width,\n\t\tsourceHeight: source.height,\n\t\tregion,\n\t\tscaleX: region.width / resized.width,\n\t\tscaleY: region.height / resized.height,\n\t};\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare class DesktopLease {
|
|
2
|
+
private readonly identity;
|
|
3
|
+
private owned;
|
|
4
|
+
private tail;
|
|
5
|
+
private closed;
|
|
6
|
+
private readonly controller;
|
|
7
|
+
get signal(): AbortSignal;
|
|
8
|
+
private readonly directory;
|
|
9
|
+
constructor(directory?: string);
|
|
10
|
+
private owner;
|
|
11
|
+
private withOwnerLock;
|
|
12
|
+
private writeOwner;
|
|
13
|
+
private acquire;
|
|
14
|
+
trackProcess(pid: number): Promise<void>;
|
|
15
|
+
run<T>(operation: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
16
|
+
close(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=lease.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/lease.ts"],"names":[],"mappings":"AAOA,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAuC;IACnD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,IAAI,MAAM,IAAI,WAAW,CAExB;IACD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,YAAY,SAAS,SAA+C,EAEnE;YAEa,KAAK;YAwBL,aAAa;YAab,UAAU;YAUV,OAAO;IAwBf,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ7C;IAED,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAepE;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAU3B;CACD","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { userInfo } from \"node:os\";\nimport { join } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { assertOwnedPath } from \"./runtime.ts\";\n\nexport class DesktopLease {\n\tprivate readonly identity = randomUUID();\n\tprivate owned = false;\n\tprivate tail: Promise<unknown> = Promise.resolve();\n\tprivate closed = false;\n\tprivate readonly controller = new AbortController();\n\tget signal(): AbortSignal {\n\t\treturn this.controller.signal;\n\t}\n\tprivate readonly directory: string;\n\tconstructor(directory = join(userInfo().homedir, \".lunr\", \"desktop\")) {\n\t\tthis.directory = directory;\n\t}\n\n\tprivate async owner(): Promise<{ pid: number; identity: string; processes: number[] } | undefined> {\n\t\ttry {\n\t\t\tconst value: unknown = JSON.parse(await readFile(join(this.directory, \"workflow-owner.json\"), \"utf8\"));\n\t\t\tif (\n\t\t\t\t!value ||\n\t\t\t\ttypeof value !== \"object\" ||\n\t\t\t\t!(\"pid\" in value) ||\n\t\t\t\ttypeof value.pid !== \"number\" ||\n\t\t\t\t!Number.isInteger(value.pid) ||\n\t\t\t\tvalue.pid < 1 ||\n\t\t\t\t!(\"identity\" in value) ||\n\t\t\t\ttypeof value.identity !== \"string\"\n\t\t\t)\n\t\t\t\tthrow new Error(\"Invalid desktop owner record; refusing takeover.\");\n\t\t\tconst processes = \"processes\" in value ? value.processes : [];\n\t\t\tif (!Array.isArray(processes) || !processes.every((pid) => Number.isInteger(pid) && pid > 0))\n\t\t\t\tthrow new Error(\"Invalid runtime owner record; refusing takeover.\");\n\t\t\treturn { pid: value.pid, identity: value.identity, processes };\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async withOwnerLock(operation: () => Promise<void>): Promise<void> {\n\t\tconst release = await lockfile.lock(this.directory, {\n\t\t\tlockfilePath: join(this.directory, \"workflow-acquire.lock\"),\n\t\t\tretries: 0,\n\t\t\tstale: 10000,\n\t\t});\n\t\ttry {\n\t\t\tawait operation();\n\t\t} finally {\n\t\t\tawait release();\n\t\t}\n\t}\n\n\tprivate async writeOwner(owner: { pid: number; identity: string; processes?: number[] }): Promise<void> {\n\t\tconst temporary = join(this.directory, `workflow-owner-${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait writeFile(temporary, JSON.stringify(owner), { mode: 0o600, flag: \"wx\" });\n\t\t\tawait rename(temporary, join(this.directory, \"workflow-owner.json\"));\n\t\t} finally {\n\t\t\tawait rm(temporary, { force: true });\n\t\t}\n\t}\n\n\tprivate async acquire(): Promise<void> {\n\t\tawait assertOwnedPath(this.directory);\n\t\tawait mkdir(this.directory, { recursive: true, mode: 0o700 });\n\t\tawait this.withOwnerLock(async () => {\n\t\t\tconst owner = await this.owner();\n\t\t\tif (owner) {\n\t\t\t\tconst alive = [owner.pid, ...owner.processes].some((pid) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tprocess.kill(pid, 0);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn !(error instanceof Error && \"code\" in error && error.code === \"ESRCH\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (alive)\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"Desktop busy: another lunR workflow owns this user's desktop. Retry only after it ends.\",\n\t\t\t\t\t);\n\t\t\t}\n\t\t\tawait this.writeOwner({ pid: process.pid, identity: this.identity });\n\t\t\tthis.owned = true;\n\t\t});\n\t}\n\n\tasync trackProcess(pid: number): Promise<void> {\n\t\tawait this.withOwnerLock(async () => {\n\t\t\tconst owner = await this.owner();\n\t\t\tif (!owner || owner.identity !== this.identity || !Number.isInteger(pid) || pid < 1)\n\t\t\t\tthrow new Error(\"Cannot bind runtime to the desktop lease.\");\n\t\t\tif (!owner.processes.includes(pid)) owner.processes.push(pid);\n\t\t\tawait this.writeOwner(owner);\n\t\t});\n\t}\n\n\trun<T>(operation: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n\t\tconst result = this.tail.then(async () => {\n\t\t\tif (this.closed) throw new Error(\"Desktop workflow ended. Start a new workflow and observe again.\");\n\t\t\tsignal?.throwIfAborted();\n\t\t\tif (!this.owned) await this.acquire();\n\t\t\tif ((await this.owner())?.identity !== this.identity) {\n\t\t\t\tthis.closed = true;\n\t\t\t\tthis.controller.abort(new Error(\"Desktop lease lost.\"));\n\t\t\t\tthrow new Error(\"Desktop lease lost. Input refused.\");\n\t\t\t}\n\t\t\tsignal?.throwIfAborted();\n\t\t\treturn operation();\n\t\t});\n\t\tthis.tail = result.catch(() => undefined);\n\t\treturn result;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.closed = true;\n\t\tthis.controller.abort();\n\t\tawait this.tail;\n\t\tif (this.owned) {\n\t\t\tawait this.withOwnerLock(async () => {\n\t\t\t\tif ((await this.owner())?.identity === this.identity) await rm(join(this.directory, \"workflow-owner.json\"));\n\t\t\t});\n\t\t\tthis.owned = false;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { userInfo } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import lockfile from "proper-lockfile";
|
|
6
|
+
import { assertOwnedPath } from "./runtime.js";
|
|
7
|
+
export class DesktopLease {
|
|
8
|
+
identity = randomUUID();
|
|
9
|
+
owned = false;
|
|
10
|
+
tail = Promise.resolve();
|
|
11
|
+
closed = false;
|
|
12
|
+
controller = new AbortController();
|
|
13
|
+
get signal() {
|
|
14
|
+
return this.controller.signal;
|
|
15
|
+
}
|
|
16
|
+
directory;
|
|
17
|
+
constructor(directory = join(userInfo().homedir, ".lunr", "desktop")) {
|
|
18
|
+
this.directory = directory;
|
|
19
|
+
}
|
|
20
|
+
async owner() {
|
|
21
|
+
try {
|
|
22
|
+
const value = JSON.parse(await readFile(join(this.directory, "workflow-owner.json"), "utf8"));
|
|
23
|
+
if (!value ||
|
|
24
|
+
typeof value !== "object" ||
|
|
25
|
+
!("pid" in value) ||
|
|
26
|
+
typeof value.pid !== "number" ||
|
|
27
|
+
!Number.isInteger(value.pid) ||
|
|
28
|
+
value.pid < 1 ||
|
|
29
|
+
!("identity" in value) ||
|
|
30
|
+
typeof value.identity !== "string")
|
|
31
|
+
throw new Error("Invalid desktop owner record; refusing takeover.");
|
|
32
|
+
const processes = "processes" in value ? value.processes : [];
|
|
33
|
+
if (!Array.isArray(processes) || !processes.every((pid) => Number.isInteger(pid) && pid > 0))
|
|
34
|
+
throw new Error("Invalid runtime owner record; refusing takeover.");
|
|
35
|
+
return { pid: value.pid, identity: value.identity, processes };
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
39
|
+
return undefined;
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async withOwnerLock(operation) {
|
|
44
|
+
const release = await lockfile.lock(this.directory, {
|
|
45
|
+
lockfilePath: join(this.directory, "workflow-acquire.lock"),
|
|
46
|
+
retries: 0,
|
|
47
|
+
stale: 10000,
|
|
48
|
+
});
|
|
49
|
+
try {
|
|
50
|
+
await operation();
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
await release();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async writeOwner(owner) {
|
|
57
|
+
const temporary = join(this.directory, `workflow-owner-${randomUUID()}.tmp`);
|
|
58
|
+
try {
|
|
59
|
+
await writeFile(temporary, JSON.stringify(owner), { mode: 0o600, flag: "wx" });
|
|
60
|
+
await rename(temporary, join(this.directory, "workflow-owner.json"));
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
await rm(temporary, { force: true });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async acquire() {
|
|
67
|
+
await assertOwnedPath(this.directory);
|
|
68
|
+
await mkdir(this.directory, { recursive: true, mode: 0o700 });
|
|
69
|
+
await this.withOwnerLock(async () => {
|
|
70
|
+
const owner = await this.owner();
|
|
71
|
+
if (owner) {
|
|
72
|
+
const alive = [owner.pid, ...owner.processes].some((pid) => {
|
|
73
|
+
try {
|
|
74
|
+
process.kill(pid, 0);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
return !(error instanceof Error && "code" in error && error.code === "ESRCH");
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
if (alive)
|
|
82
|
+
throw new Error("Desktop busy: another lunR workflow owns this user's desktop. Retry only after it ends.");
|
|
83
|
+
}
|
|
84
|
+
await this.writeOwner({ pid: process.pid, identity: this.identity });
|
|
85
|
+
this.owned = true;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async trackProcess(pid) {
|
|
89
|
+
await this.withOwnerLock(async () => {
|
|
90
|
+
const owner = await this.owner();
|
|
91
|
+
if (!owner || owner.identity !== this.identity || !Number.isInteger(pid) || pid < 1)
|
|
92
|
+
throw new Error("Cannot bind runtime to the desktop lease.");
|
|
93
|
+
if (!owner.processes.includes(pid))
|
|
94
|
+
owner.processes.push(pid);
|
|
95
|
+
await this.writeOwner(owner);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
run(operation, signal) {
|
|
99
|
+
const result = this.tail.then(async () => {
|
|
100
|
+
if (this.closed)
|
|
101
|
+
throw new Error("Desktop workflow ended. Start a new workflow and observe again.");
|
|
102
|
+
signal?.throwIfAborted();
|
|
103
|
+
if (!this.owned)
|
|
104
|
+
await this.acquire();
|
|
105
|
+
if ((await this.owner())?.identity !== this.identity) {
|
|
106
|
+
this.closed = true;
|
|
107
|
+
this.controller.abort(new Error("Desktop lease lost."));
|
|
108
|
+
throw new Error("Desktop lease lost. Input refused.");
|
|
109
|
+
}
|
|
110
|
+
signal?.throwIfAborted();
|
|
111
|
+
return operation();
|
|
112
|
+
});
|
|
113
|
+
this.tail = result.catch(() => undefined);
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
async close() {
|
|
117
|
+
this.closed = true;
|
|
118
|
+
this.controller.abort();
|
|
119
|
+
await this.tail;
|
|
120
|
+
if (this.owned) {
|
|
121
|
+
await this.withOwnerLock(async () => {
|
|
122
|
+
if ((await this.owner())?.identity === this.identity)
|
|
123
|
+
await rm(join(this.directory, "workflow-owner.json"));
|
|
124
|
+
});
|
|
125
|
+
this.owned = false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=lease.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease.js","sourceRoot":"","sources":["../../../src/core/computer-use/lease.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { userInfo } from \"node:os\";\nimport { join } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { assertOwnedPath } from \"./runtime.ts\";\n\nexport class DesktopLease {\n\tprivate readonly identity = randomUUID();\n\tprivate owned = false;\n\tprivate tail: Promise<unknown> = Promise.resolve();\n\tprivate closed = false;\n\tprivate readonly controller = new AbortController();\n\tget signal(): AbortSignal {\n\t\treturn this.controller.signal;\n\t}\n\tprivate readonly directory: string;\n\tconstructor(directory = join(userInfo().homedir, \".lunr\", \"desktop\")) {\n\t\tthis.directory = directory;\n\t}\n\n\tprivate async owner(): Promise<{ pid: number; identity: string; processes: number[] } | undefined> {\n\t\ttry {\n\t\t\tconst value: unknown = JSON.parse(await readFile(join(this.directory, \"workflow-owner.json\"), \"utf8\"));\n\t\t\tif (\n\t\t\t\t!value ||\n\t\t\t\ttypeof value !== \"object\" ||\n\t\t\t\t!(\"pid\" in value) ||\n\t\t\t\ttypeof value.pid !== \"number\" ||\n\t\t\t\t!Number.isInteger(value.pid) ||\n\t\t\t\tvalue.pid < 1 ||\n\t\t\t\t!(\"identity\" in value) ||\n\t\t\t\ttypeof value.identity !== \"string\"\n\t\t\t)\n\t\t\t\tthrow new Error(\"Invalid desktop owner record; refusing takeover.\");\n\t\t\tconst processes = \"processes\" in value ? value.processes : [];\n\t\t\tif (!Array.isArray(processes) || !processes.every((pid) => Number.isInteger(pid) && pid > 0))\n\t\t\t\tthrow new Error(\"Invalid runtime owner record; refusing takeover.\");\n\t\t\treturn { pid: value.pid, identity: value.identity, processes };\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async withOwnerLock(operation: () => Promise<void>): Promise<void> {\n\t\tconst release = await lockfile.lock(this.directory, {\n\t\t\tlockfilePath: join(this.directory, \"workflow-acquire.lock\"),\n\t\t\tretries: 0,\n\t\t\tstale: 10000,\n\t\t});\n\t\ttry {\n\t\t\tawait operation();\n\t\t} finally {\n\t\t\tawait release();\n\t\t}\n\t}\n\n\tprivate async writeOwner(owner: { pid: number; identity: string; processes?: number[] }): Promise<void> {\n\t\tconst temporary = join(this.directory, `workflow-owner-${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait writeFile(temporary, JSON.stringify(owner), { mode: 0o600, flag: \"wx\" });\n\t\t\tawait rename(temporary, join(this.directory, \"workflow-owner.json\"));\n\t\t} finally {\n\t\t\tawait rm(temporary, { force: true });\n\t\t}\n\t}\n\n\tprivate async acquire(): Promise<void> {\n\t\tawait assertOwnedPath(this.directory);\n\t\tawait mkdir(this.directory, { recursive: true, mode: 0o700 });\n\t\tawait this.withOwnerLock(async () => {\n\t\t\tconst owner = await this.owner();\n\t\t\tif (owner) {\n\t\t\t\tconst alive = [owner.pid, ...owner.processes].some((pid) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tprocess.kill(pid, 0);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn !(error instanceof Error && \"code\" in error && error.code === \"ESRCH\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (alive)\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"Desktop busy: another lunR workflow owns this user's desktop. Retry only after it ends.\",\n\t\t\t\t\t);\n\t\t\t}\n\t\t\tawait this.writeOwner({ pid: process.pid, identity: this.identity });\n\t\t\tthis.owned = true;\n\t\t});\n\t}\n\n\tasync trackProcess(pid: number): Promise<void> {\n\t\tawait this.withOwnerLock(async () => {\n\t\t\tconst owner = await this.owner();\n\t\t\tif (!owner || owner.identity !== this.identity || !Number.isInteger(pid) || pid < 1)\n\t\t\t\tthrow new Error(\"Cannot bind runtime to the desktop lease.\");\n\t\t\tif (!owner.processes.includes(pid)) owner.processes.push(pid);\n\t\t\tawait this.writeOwner(owner);\n\t\t});\n\t}\n\n\trun<T>(operation: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n\t\tconst result = this.tail.then(async () => {\n\t\t\tif (this.closed) throw new Error(\"Desktop workflow ended. Start a new workflow and observe again.\");\n\t\t\tsignal?.throwIfAborted();\n\t\t\tif (!this.owned) await this.acquire();\n\t\t\tif ((await this.owner())?.identity !== this.identity) {\n\t\t\t\tthis.closed = true;\n\t\t\t\tthis.controller.abort(new Error(\"Desktop lease lost.\"));\n\t\t\t\tthrow new Error(\"Desktop lease lost. Input refused.\");\n\t\t\t}\n\t\t\tsignal?.throwIfAborted();\n\t\t\treturn operation();\n\t\t});\n\t\tthis.tail = result.catch(() => undefined);\n\t\treturn result;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.closed = true;\n\t\tthis.controller.abort();\n\t\tawait this.tail;\n\t\tif (this.owned) {\n\t\t\tawait this.withOwnerLock(async () => {\n\t\t\t\tif ((await this.owner())?.identity === this.identity) await rm(join(this.directory, \"workflow-owner.json\"));\n\t\t\t});\n\t\t\tthis.owned = false;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function macLaunchArguments(app: string, socket: string, home: string, lifetime: string): string[];
|
|
2
|
+
export declare class MacRuntime {
|
|
3
|
+
private directory?;
|
|
4
|
+
private lifetime?;
|
|
5
|
+
private exited?;
|
|
6
|
+
private pid?;
|
|
7
|
+
get processId(): number | undefined;
|
|
8
|
+
private socket?;
|
|
9
|
+
private closing?;
|
|
10
|
+
start(app: string, signal: AbortSignal): Promise<string>;
|
|
11
|
+
close(): Promise<void>;
|
|
12
|
+
private stop;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=macos-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"macos-runtime.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/macos-runtime.ts"],"names":[],"mappings":"AAYA,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBxG;AAoCD,qBAAa,UAAU;IACtB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,MAAM,CAAC,CAAgB;IAC/B,OAAO,CAAC,GAAG,CAAC,CAAS;IACrB,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IACD,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAgB;IAE1B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA8C7D;IAED,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAGrB;YAEa,IAAI;CAoBlB","sourcesContent":["import { execFile, spawn } from \"node:child_process\";\nimport { constants } from \"node:fs\";\nimport { type FileHandle, mkdtemp, open, realpath, rm } from \"node:fs/promises\";\nimport { connect } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { promisify } from \"node:util\";\nimport { CUA_VERSION, runtimeEnvironment } from \"./runtime.ts\";\n\nconst exec = promisify(execFile);\n\nexport function macLaunchArguments(app: string, socket: string, home: string, lifetime: string): string[] {\n\tconst environment = {\n\t\tHOME: home,\n\t\t...Object.fromEntries(Object.entries(runtimeEnvironment()).filter(([name]) => name.startsWith(\"CUA_\"))),\n\t};\n\treturn [\n\t\t\"-n\",\n\t\t\"-g\",\n\t\t\"-W\",\n\t\t\"-a\",\n\t\tapp,\n\t\t\"--stdin\",\n\t\tlifetime,\n\t\t...Object.entries(environment).flatMap(([name, value]) => [\"--env\", `${name}=${value}`]),\n\t\t\"--args\",\n\t\t\"serve\",\n\t\t\"--embedded\",\n\t\t\"--parent-liveness-stdio\",\n\t\t\"--socket\",\n\t\tsocket,\n\t\t\"--permission-mode\",\n\t\t\"standard\",\n\t\t\"--no-overlay\",\n\t];\n}\n\nfunction request(socket: string, method: string, args?: Record<string, unknown>): Promise<Record<string, unknown>> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst stream = connect(socket);\n\t\tlet buffer = \"\";\n\t\tstream.setTimeout(1000, () => stream.destroy(new Error(\"Private computer endpoint timed out.\")));\n\t\tstream.on(\"error\", reject);\n\t\tstream.on(\"connect\", () => stream.write(`${JSON.stringify({ method, args })}\\n`));\n\t\tstream.on(\"data\", (chunk) => {\n\t\t\tbuffer += chunk.toString();\n\t\t\tif (buffer.length > 65536) {\n\t\t\t\tstream.destroy(new Error(\"Invalid private endpoint metadata.\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!buffer.includes(\"\\n\")) return;\n\t\t\ttry {\n\t\t\t\tconst reply: unknown = JSON.parse(buffer.slice(0, buffer.indexOf(\"\\n\")));\n\t\t\t\tif (\n\t\t\t\t\t!reply ||\n\t\t\t\t\ttypeof reply !== \"object\" ||\n\t\t\t\t\t!(\"result\" in reply) ||\n\t\t\t\t\t!reply.result ||\n\t\t\t\t\ttypeof reply.result !== \"object\"\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Private endpoint refused metadata.\");\n\t\t\t\tresolve(Object.fromEntries(Object.entries(reply.result)));\n\t\t\t} catch (error) {\n\t\t\t\treject(error);\n\t\t\t}\n\t\t\tstream.destroy();\n\t\t});\n\t\tstream.on(\"end\", () => reject(new Error(\"Private computer endpoint closed.\")));\n\t});\n}\n\nexport class MacRuntime {\n\tprivate directory?: string;\n\tprivate lifetime?: FileHandle;\n\tprivate exited?: Promise<void>;\n\tprivate pid?: number;\n\tget processId(): number | undefined {\n\t\treturn this.pid;\n\t}\n\tprivate socket?: string;\n\tprivate closing?: Promise<void>;\n\n\tasync start(app: string, signal: AbortSignal): Promise<string> {\n\t\tconst directory = await mkdtemp(join(await realpath(tmpdir()), \"lunr-cua-\"));\n\t\tthis.directory = directory;\n\t\tconst socket = join(directory, \"driver.sock\");\n\t\tthis.socket = socket;\n\t\tconst lifetime = join(directory, \"lifetime\");\n\t\tawait exec(\"/usr/bin/mkfifo\", [\"-m\", \"600\", lifetime], { timeout: 5000, signal });\n\t\tthis.lifetime = await open(lifetime, constants.O_RDWR);\n\t\tsignal.throwIfAborted();\n\t\tconst launcher = spawn(\"/usr/bin/open\", macLaunchArguments(app, socket, directory, lifetime), {\n\t\t\tenv: runtimeEnvironment(),\n\t\t\tstdio: \"ignore\",\n\t\t});\n\t\tthis.exited = new Promise<void>((resolve, reject) => {\n\t\t\tlauncher.once(\"error\", reject);\n\t\t\tlauncher.once(\"exit\", (code) =>\n\t\t\t\tcode === 0 ? resolve() : reject(new Error(`LaunchServices exited ${code}.`)),\n\t\t\t);\n\t\t});\n\t\tvoid this.exited.catch(() => undefined);\n\t\tconst deadline = Date.now() + 15000;\n\t\twhile (Date.now() < deadline) {\n\t\t\tsignal.throwIfAborted();\n\t\t\ttry {\n\t\t\t\tconst metadata = await request(socket, \"metadata\");\n\t\t\t\tif (\n\t\t\t\t\tmetadata.driver_version !== CUA_VERSION ||\n\t\t\t\t\tmetadata.embedded !== true ||\n\t\t\t\t\ttypeof metadata.pid !== \"number\" ||\n\t\t\t\t\tmetadata.pid < 1\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Private runtime has incompatible metadata.\");\n\t\t\t\tthis.pid = metadata.pid;\n\t\t\t\treturn socket;\n\t\t\t} catch {\n\t\t\t\tawait Promise.race([\n\t\t\t\t\tdelay(100, undefined, { signal }),\n\t\t\t\t\tthis.exited.then(() => {\n\t\t\t\t\t\tthrow new Error(\"Computer app exited during startup.\");\n\t\t\t\t\t}),\n\t\t\t\t]);\n\t\t\t}\n\t\t}\n\t\tthrow new Error(\n\t\t\t\"Private macOS runtime startup timed out. Check CuaDriver Accessibility and Screen Recording grants.\",\n\t\t);\n\t}\n\n\tclose(): Promise<void> {\n\t\tthis.closing ??= this.stop();\n\t\treturn this.closing;\n\t}\n\n\tprivate async stop(): Promise<void> {\n\t\tawait this.lifetime?.close();\n\t\tthis.lifetime = undefined;\n\t\tif (this.socket && this.pid)\n\t\t\tawait request(this.socket, \"shutdown_if_pid\", { expected_pid: this.pid }).catch(() => undefined);\n\t\tif (this.exited) {\n\t\t\tconst timeout = new AbortController();\n\t\t\ttry {\n\t\t\t\tawait Promise.race([\n\t\t\t\t\tthis.exited,\n\t\t\t\t\tdelay(10000, undefined, { signal: timeout.signal }).then(() => {\n\t\t\t\t\t\tthrow new Error(\"Owned macOS app shutdown is unconfirmed. Desktop lease retained.\");\n\t\t\t\t\t}),\n\t\t\t\t]);\n\t\t\t} finally {\n\t\t\t\ttimeout.abort();\n\t\t\t}\n\t\t}\n\t\tif (this.directory) await rm(this.directory, { recursive: true, force: true });\n\t}\n}\n"]}
|