@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gateway/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * lunR: gateway daemon entry (Phase 2a skeleton; Phase 2b registered the\n * Telegram adapter, Phase 3 the Discord adapter — both via ADAPTER_FACTORIES).\n *\n * `lunr gateway` runs the daemon: load gateway.json, instantiate every\n * enabled platform that has a registered adapter factory AND a resolvable\n * token, connect, route messages, and stay alive until SIGINT/SIGTERM.\n * With no runnable adapters it prints per-platform setup instructions and\n * exits 1.\n *\n * Sub-commands:\n * lunr gateway pair approve <platform> <code> approve a pairing code\n * lunr gateway pair list show pending + paired\n * lunr gateway status config/token/session summary\n */\n\nimport { isFeatureEnabled } from \"../core/install-features.ts\";\nimport { DiscordAdapter } from \"./adapters/discord.ts\";\nimport { TelegramAdapter } from \"./adapters/telegram.ts\";\nimport { AgentBridge } from \"./agent-bridge.ts\";\nimport { handleApprovalCallback } from \"./approval.ts\";\nimport { addAllowedUser } from \"./authz.ts\";\nimport { handleCallback, startButtonSweeper, stopButtonSweeper } from \"./buttons.ts\";\nimport { botCommandSpecs } from \"./commands.ts\";\nimport {\n\ttype DiscordConfig,\n\tloadGatewayConfig,\n\ttype PlatformConfig,\n\tplatformConfigFor,\n\tresolvePlatformToken,\n\tsaveGatewayConfig,\n} from \"./config.ts\";\nimport { startGatewayCron } from \"./cron.ts\";\nimport { createPairingStore } from \"./pairing.ts\";\nimport { startGatewayPresenter, stopGatewayPresenter } from \"./presenter.ts\";\nimport { createRouter } from \"./router.ts\";\nimport { claimGateway } from \"./service.ts\";\nimport { buildSessionKey } from \"./session-keys.ts\";\nimport { listSessions } from \"./store.ts\";\nimport type { PlatformAdapter } from \"./types.ts\";\n\n/**\n * Adapter registry — the seam adapters plug into:\n *\n * ADAPTER_FACTORIES.<platform> = (cfg) => new SomeAdapter(cfg);\n *\n * A factory receives the sanitized platform config with the token already\n * resolved into cfg.token (env beats file — see resolvePlatformToken and\n * runDaemon below). The registry type is the PlatformConfig base; adapters\n * with extra fields (Discord) narrow with a cast — the daemon always passes\n * the full sanitized per-platform object.\n */\nexport const ADAPTER_FACTORIES: Record<string, (cfg: PlatformConfig) => PlatformAdapter> = {\n\ttelegram: (cfg) => new TelegramAdapter(cfg),\n\tdiscord: (cfg) => new DiscordAdapter(cfg as DiscordConfig),\n};\n\nconst KNOWN_PLATFORMS = [\"telegram\", \"discord\"] as const;\n\nconst SETUP_INSTRUCTIONS: Record<string, string[]> = {\n\ttelegram: [\"Telegram: run lunr gateway setup locally to configure the bot token and owner ID.\"],\n\tdiscord: [\"Discord: run lunr gateway setup locally to configure the bot token and owner ID.\"],\n};\n\nfunction printSetupInstructions(enabledButUnrunnable: string[]): void {\n\tconsole.log(\"lunR gateway: no runnable platforms configured.\");\n\tfor (const platform of enabledButUnrunnable) {\n\t\tconsole.log(` (platform \"${platform}\" is enabled but has no registered adapter or resolvable token)`);\n\t}\n\tfor (const platform of KNOWN_PLATFORMS) {\n\t\tfor (const line of SETUP_INSTRUCTIONS[platform]) {\n\t\t\tconsole.log(line);\n\t\t}\n\t}\n}\n\nasync function runPairApprove(platform: string, code: string | undefined, owner = false): Promise<number> {\n\tif (!code) {\n\t\tconsole.error(\"Usage: lunr gateway pair approve <platform> <code> [--owner]\");\n\t\treturn 1;\n\t}\n\tconst pairing = createPairingStore();\n\tconst userId = pairing.approve(platform, code);\n\tif (userId === null) {\n\t\tconsole.error(`Pairing failed: no valid pending code \"${code}\" for ${platform} (wrong, expired, or locked out).`);\n\t\treturn 1;\n\t}\n\ttry {\n\t\tif (owner) {\n\t\t\tconst cfg = loadGatewayConfig();\n\t\t\tif (platform !== \"telegram\" && platform !== \"discord\") throw new Error(\"Unknown platform.\");\n\t\t\tcfg.owners ??= { telegram: [], discord: [] };\n\t\t\tcfg.owners[platform] = [...new Set([...cfg.owners[platform], userId])];\n\t\t\tcfg[platform].allowedUsers = [...new Set([...cfg[platform].allowedUsers, userId])];\n\t\t\tsaveGatewayConfig(cfg);\n\t\t} else addAllowedUser(platform, userId);\n\t} catch (err) {\n\t\tconsole.error(`Paired ${platform} user ${userId}, but could not persist allowedUsers: ${err}`);\n\t\treturn 1;\n\t}\n\tconsole.log(\n\t\t`Approved ${platform} user ${userId}${owner ? \" as owner with local project and TUI access\" : \" for chat only; owner access requires local --owner approval\"}.`,\n\t);\n\treturn 0;\n}\n\nfunction runPairList(): number {\n\tconst pairing = createPairingStore();\n\tconst pending = pairing.listPending();\n\tconst approved = pairing.listApproved();\n\tconsole.log(\"Pending pairing codes:\");\n\tif (pending.length === 0) {\n\t\tconsole.log(\" (none)\");\n\t} else {\n\t\tfor (const p of pending) {\n\t\t\tconsole.log(` ${p.platform} ${p.code} user=${p.userId} expires ${new Date(p.expiresAt).toISOString()}`);\n\t\t}\n\t}\n\tconsole.log(\"Paired users:\");\n\tif (approved.length === 0) {\n\t\tconsole.log(\" (none)\");\n\t} else {\n\t\tfor (const u of approved) {\n\t\t\tconsole.log(` ${u.platform} ${u.userId} approved ${new Date(u.approvedAt).toISOString()}`);\n\t\t}\n\t}\n\treturn 0;\n}\n\nfunction runStatus(): number {\n\tconst cfg = loadGatewayConfig();\n\tconsole.log(\n\t\t`chat-platforms: ${isFeatureEnabled(\"chat-platforms\") ? \"enabled\" : \"disabled\"} (install-features.json)`,\n\t);\n\tconsole.log(\"lunR gateway status:\");\n\tfor (const platform of KNOWN_PLATFORMS) {\n\t\tconst platformCfg = platformConfigFor(cfg, platform);\n\t\tif (!platformCfg) continue;\n\t\tconst token = resolvePlatformToken(platform, platformCfg);\n\t\tconst adapter = ADAPTER_FACTORIES[platform] === undefined ? \"no adapter\" : \"adapter registered\";\n\t\tconsole.log(\n\t\t\t` ${platform}: ${platformCfg.enabled ? \"enabled\" : \"disabled\"} · token ${token ? \"resolved\" : \"missing\"} · ${adapter}`,\n\t\t);\n\t}\n\tconst sessions = listSessions();\n\tconsole.log(` sessions: ${Object.keys(sessions).length} stored`);\n\treturn 0;\n}\n\nasync function runDaemon(): Promise<number> {\n\tif (!isFeatureEnabled(\"chat-platforms\")) {\n\t\tconsole.error(\"lunR gateway: chat platforms are not enabled.\");\n\t\tconsole.error(\"Enable with: lunr features enable chat-platforms\");\n\t\treturn 1;\n\t}\n\tconst cfg = loadGatewayConfig();\n\tconst adapters = new Map<string, PlatformAdapter>();\n\tconst skipped: string[] = [];\n\n\tfor (const platform of KNOWN_PLATFORMS) {\n\t\tconst platformCfg = platformConfigFor(cfg, platform);\n\t\tif (!platformCfg?.enabled) continue;\n\t\tconst factory: ((cfg: PlatformConfig) => PlatformAdapter) | undefined = ADAPTER_FACTORIES[platform];\n\t\tif (factory === undefined) {\n\t\t\tskipped.push(platform);\n\t\t\tcontinue;\n\t\t}\n\t\tconst token = resolvePlatformToken(platform, platformCfg);\n\t\tif (!token) {\n\t\t\tskipped.push(platform);\n\t\t\tcontinue;\n\t\t}\n\t\tadapters.set(platform, factory({ ...platformCfg, token }));\n\t}\n\n\tif (adapters.size === 0) {\n\t\tprintSetupInstructions(skipped);\n\t\treturn 1;\n\t}\n\n\tconst pairing = createPairingStore();\n\tconst bridge = new AgentBridge();\n\tfor (const adapter of adapters.values())\n\t\tadapter.setCommandSuggestions?.(async (source, command) => {\n\t\t\tconst session = bridge.peekSession(buildSessionKey(source, loadGatewayConfig()));\n\t\t\tif (!session) return [];\n\t\t\tif (command === \"thinking\") return session.getAvailableThinkingLevels();\n\t\t\tif (command === \"model\")\n\t\t\t\treturn (await session.modelRuntime.getAvailable()).map((model) => `${model.provider}/${model.id}`);\n\t\t\treturn [];\n\t\t});\n\tconst router = createRouter({ adapters, cfg, pairing, bridge, reloadConfig: true, remoteControls: true });\n\n\tlet finish!: () => void;\n\tconst stopped = new Promise<void>((resolve) => {\n\t\tfinish = resolve;\n\t});\n\tlet stopping = false;\n\tlet cron: ReturnType<typeof startGatewayCron> | undefined;\n\tconst platformStatus: Record<string, string> = {};\n\tconst retries = new Set<ReturnType<typeof setTimeout>>();\n\tconst shutdown = () => {\n\t\tif (stopping) return;\n\t\tstopping = true;\n\t\towner.update(platformStatus, \"stopping\");\n\t\tcron?.stop();\n\t\tfor (const timer of retries) clearTimeout(timer);\n\t\tstopButtonSweeper();\n\t\tvoid (async () => {\n\t\t\tawait bridge.shutdown();\n\t\t\tawait Promise.all([...adapters.values()].map((adapter) => adapter.disconnect().catch(() => {})));\n\t\t\tstopGatewayPresenter();\n\t\t\towner.release();\n\t\t\tprocess.removeListener(\"SIGINT\", shutdown);\n\t\t\tprocess.removeListener(\"SIGTERM\", shutdown);\n\t\t\tfinish();\n\t\t})().catch((error) => {\n\t\t\tconsole.error(\"Gateway shutdown failed:\", error instanceof Error ? error.message : String(error));\n\t\t\tstopping = false;\n\t\t\towner.update(platformStatus, Object.values(platformStatus).includes(\"connected\") ? \"ready\" : \"starting\");\n\t\t\tstartButtonSweeper();\n\t\t\tcron = startGatewayCron({ adapters, cfg });\n\t\t\tfor (const [platform, adapter] of adapters)\n\t\t\t\tif (platformStatus[platform] !== \"connected\") void connect(platform, adapter);\n\t\t});\n\t};\n\tconst owner = claimGateway(shutdown);\n\tprocess.on(\"SIGINT\", shutdown);\n\tprocess.on(\"SIGTERM\", shutdown);\n\tstartGatewayPresenter(adapters);\n\tstartButtonSweeper();\n\tconst connect = async (platform: string, adapter: PlatformAdapter): Promise<void> => {\n\t\tif (stopping) return;\n\t\ttry {\n\t\t\tplatformStatus[platform] = \"connecting\";\n\t\t\towner.update(platformStatus, Object.values(platformStatus).includes(\"connected\") ? \"ready\" : \"starting\");\n\t\t\tconst ok = await adapter.connect();\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error(\"Connection failed\");\n\t\t\t}\n\t\t\tadapter.onMessage((event) => {\n\t\t\t\tvoid router.handleEvent(event);\n\t\t\t});\n\t\t\tadapter.onCallback(async (event) => {\n\t\t\t\tconst consumed = await handleApprovalCallback(event, adapter);\n\t\t\t\tif (!consumed) {\n\t\t\t\t\tvoid handleCallback(event, { adapters, cfg: loadGatewayConfig(), pairing, bridge, adapter });\n\t\t\t\t}\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tawait adapter.registerCommands?.(botCommandSpecs());\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[gateway] ${platform}: command menu registration failed: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (stopping) {\n\t\t\t\tawait adapter.disconnect();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tplatformStatus[platform] = \"connected\";\n\t\t\tconsole.log(`lunR gateway: ${platform} connected`);\n\t\t} catch {\n\t\t\tplatformStatus[platform] = \"disconnected, retrying (check gateway logs)\";\n\t\t\tawait adapter.disconnect().catch(() => {});\n\t\t\tif (!stopping) {\n\t\t\t\tconst retry = setTimeout(() => {\n\t\t\t\t\tretries.delete(retry);\n\t\t\t\t\tvoid connect(platform, adapter);\n\t\t\t\t}, 5000);\n\t\t\t\tretries.add(retry);\n\t\t\t}\n\t\t}\n\t\tif (!stopping)\n\t\t\towner.update(platformStatus, Object.values(platformStatus).includes(\"connected\") ? \"ready\" : \"starting\");\n\t};\n\tfor (const [platform, adapter] of adapters) void connect(platform, adapter);\n\n\t// Phase 4: cron jobs fire inside the daemon and deliver back to chats.\n\t// Starts even with zero stored jobs — jobs can be created later from chats.\n\tcron = startGatewayCron({ adapters, cfg });\n\tconsole.log(`lunR gateway: cron scheduler started (${cron.intervalMs / 1000}s interval)`);\n\n\towner.update(platformStatus, \"starting\");\n\tawait stopped;\n\treturn 0;\n}\n\nexport async function runGateway(args: string[]): Promise<number> {\n\tconst [sub, ...rest] = args;\n\tif (sub === \"pair\") {\n\t\tconst [action, platform, code, flag] = rest;\n\t\tif (action === \"approve\" && platform && (flag === undefined || flag === \"--owner\"))\n\t\t\treturn runPairApprove(platform, code, flag === \"--owner\");\n\t\tif (action === \"list\") return runPairList();\n\t\tconsole.error(\"Usage: lunr gateway pair approve <platform> <code> [--owner] | lunr gateway pair list\");\n\t\treturn 1;\n\t}\n\tif (sub === \"status\") return runStatus();\n\tif (sub === undefined) return runDaemon();\n\tconsole.error(`Unknown gateway sub-command \"${sub}\". Expected: pair approve | pair list | status`);\n\treturn 1;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gateway/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * lunR: gateway daemon entry (Phase 2a skeleton; Phase 2b registered the\n * Telegram adapter, Phase 3 the Discord adapter — both via ADAPTER_FACTORIES).\n *\n * `lunr gateway` runs the daemon: load gateway.json, instantiate every\n * enabled platform that has a registered adapter factory AND a resolvable\n * token, connect, route messages, and stay alive until SIGINT/SIGTERM.\n * With no runnable adapters it prints per-platform setup instructions and\n * exits 1.\n *\n * Sub-commands:\n * lunr gateway pair approve <platform> <code> approve a pairing code\n * lunr gateway pair list show pending + paired\n * lunr gateway status config/token/session summary\n */\n\nimport { isFeatureEnabled } from \"../core/install-features.ts\";\nimport { DiscordAdapter } from \"./adapters/discord.ts\";\nimport { TelegramAdapter } from \"./adapters/telegram.ts\";\nimport { AgentBridge } from \"./agent-bridge.ts\";\nimport { handleApprovalCallback } from \"./approval.ts\";\nimport { addAllowedUser } from \"./authz.ts\";\nimport { handleCallback, startButtonSweeper, stopButtonSweeper } from \"./buttons.ts\";\nimport { botCommandSpecs } from \"./commands.ts\";\nimport {\n\ttype DiscordConfig,\n\tloadGatewayConfig,\n\ttype PlatformConfig,\n\tplatformConfigFor,\n\tresolvePlatformToken,\n\tsaveGatewayConfig,\n} from \"./config.ts\";\nimport { startGatewayCron } from \"./cron.ts\";\nimport { createPairingStore } from \"./pairing.ts\";\nimport { startGatewayPresenter, stopGatewayPresenter } from \"./presenter.ts\";\nimport { createRouter } from \"./router.ts\";\nimport { claimGateway } from \"./service.ts\";\nimport { buildSessionKey } from \"./session-keys.ts\";\nimport { listSessions } from \"./store.ts\";\nimport type { PlatformAdapter } from \"./types.ts\";\n\n/**\n * Adapter registry — the seam adapters plug into:\n *\n * ADAPTER_FACTORIES.<platform> = (cfg) => new SomeAdapter(cfg);\n *\n * A factory receives the sanitized platform config with the token already\n * resolved into cfg.token (env beats file — see resolvePlatformToken and\n * runDaemon below). The registry type is the PlatformConfig base; adapters\n * with extra fields (Discord) narrow with a cast — the daemon always passes\n * the full sanitized per-platform object.\n */\nexport const ADAPTER_FACTORIES: Record<string, (cfg: PlatformConfig) => PlatformAdapter> = {\n\ttelegram: (cfg) => new TelegramAdapter(cfg),\n\tdiscord: (cfg) => new DiscordAdapter(cfg as DiscordConfig),\n};\n\nconst KNOWN_PLATFORMS = [\"telegram\", \"discord\"] as const;\n\nconst SETUP_INSTRUCTIONS: Record<string, string[]> = {\n\ttelegram: [\"Telegram: run lunr gateway setup locally to configure the bot token and approved user ID.\"],\n\tdiscord: [\"Discord: run lunr gateway setup locally to configure the bot token and approved user ID.\"],\n};\n\nfunction printSetupInstructions(enabledButUnrunnable: string[]): void {\n\tconsole.log(\"lunR gateway: no runnable platforms configured.\");\n\tfor (const platform of enabledButUnrunnable) {\n\t\tconsole.log(` (platform \"${platform}\" is enabled but has no registered adapter or resolvable token)`);\n\t}\n\tfor (const platform of KNOWN_PLATFORMS) {\n\t\tfor (const line of SETUP_INSTRUCTIONS[platform]) {\n\t\t\tconsole.log(line);\n\t\t}\n\t}\n}\n\nasync function runPairApprove(platform: string, code: string | undefined, owner = false): Promise<number> {\n\tif (!code) {\n\t\tconsole.error(\"Usage: lunr gateway pair approve <platform> <code> [--owner]\");\n\t\treturn 1;\n\t}\n\tconst pairing = createPairingStore();\n\tconst userId = pairing.approve(platform, code);\n\tif (userId === null) {\n\t\tconsole.error(`Pairing failed: no valid pending code \"${code}\" for ${platform} (wrong, expired, or locked out).`);\n\t\treturn 1;\n\t}\n\ttry {\n\t\tif (owner) {\n\t\t\tconst cfg = loadGatewayConfig();\n\t\t\tif (platform !== \"telegram\" && platform !== \"discord\") throw new Error(\"Unknown platform.\");\n\t\t\tcfg.owners ??= { telegram: [], discord: [] };\n\t\t\tcfg.owners[platform] = [...new Set([...cfg.owners[platform], userId])];\n\t\t\tcfg[platform].allowedUsers = [...new Set([...cfg[platform].allowedUsers, userId])];\n\t\t\tsaveGatewayConfig(cfg);\n\t\t} else addAllowedUser(platform, userId);\n\t} catch (err) {\n\t\tconsole.error(`Paired ${platform} user ${userId}, but could not persist allowedUsers: ${err}`);\n\t\treturn 1;\n\t}\n\tconsole.log(`Approved ${platform} user ${userId}. Gateway access includes local projects and saved sessions.`);\n\treturn 0;\n}\n\nfunction runPairList(): number {\n\tconst pairing = createPairingStore();\n\tconst pending = pairing.listPending();\n\tconst approved = pairing.listApproved();\n\tconsole.log(\"Pending pairing codes:\");\n\tif (pending.length === 0) {\n\t\tconsole.log(\" (none)\");\n\t} else {\n\t\tfor (const p of pending) {\n\t\t\tconsole.log(` ${p.platform} ${p.code} user=${p.userId} expires ${new Date(p.expiresAt).toISOString()}`);\n\t\t}\n\t}\n\tconsole.log(\"Paired users:\");\n\tif (approved.length === 0) {\n\t\tconsole.log(\" (none)\");\n\t} else {\n\t\tfor (const u of approved) {\n\t\t\tconsole.log(` ${u.platform} ${u.userId} approved ${new Date(u.approvedAt).toISOString()}`);\n\t\t}\n\t}\n\treturn 0;\n}\n\nfunction runStatus(): number {\n\tconst cfg = loadGatewayConfig();\n\tconsole.log(\n\t\t`chat-platforms: ${isFeatureEnabled(\"chat-platforms\") ? \"enabled\" : \"disabled\"} (install-features.json)`,\n\t);\n\tconsole.log(\"lunR gateway status:\");\n\tfor (const platform of KNOWN_PLATFORMS) {\n\t\tconst platformCfg = platformConfigFor(cfg, platform);\n\t\tif (!platformCfg) continue;\n\t\tconst token = resolvePlatformToken(platform, platformCfg);\n\t\tconst adapter = ADAPTER_FACTORIES[platform] === undefined ? \"no adapter\" : \"adapter registered\";\n\t\tconsole.log(\n\t\t\t` ${platform}: ${platformCfg.enabled ? \"enabled\" : \"disabled\"} · token ${token ? \"resolved\" : \"missing\"} · ${adapter}`,\n\t\t);\n\t}\n\tconst sessions = listSessions();\n\tconsole.log(` sessions: ${Object.keys(sessions).length} stored`);\n\treturn 0;\n}\n\nasync function runDaemon(): Promise<number> {\n\tif (!isFeatureEnabled(\"chat-platforms\")) {\n\t\tconsole.error(\"lunR gateway: chat platforms are not enabled.\");\n\t\tconsole.error(\"Enable with: lunr features enable chat-platforms\");\n\t\treturn 1;\n\t}\n\tconst cfg = loadGatewayConfig();\n\tconst adapters = new Map<string, PlatformAdapter>();\n\tconst skipped: string[] = [];\n\n\tfor (const platform of KNOWN_PLATFORMS) {\n\t\tconst platformCfg = platformConfigFor(cfg, platform);\n\t\tif (!platformCfg?.enabled) continue;\n\t\tconst factory: ((cfg: PlatformConfig) => PlatformAdapter) | undefined = ADAPTER_FACTORIES[platform];\n\t\tif (factory === undefined) {\n\t\t\tskipped.push(platform);\n\t\t\tcontinue;\n\t\t}\n\t\tconst token = resolvePlatformToken(platform, platformCfg);\n\t\tif (!token) {\n\t\t\tskipped.push(platform);\n\t\t\tcontinue;\n\t\t}\n\t\tadapters.set(platform, factory({ ...platformCfg, token }));\n\t}\n\n\tif (adapters.size === 0) {\n\t\tprintSetupInstructions(skipped);\n\t\treturn 1;\n\t}\n\n\tconst pairing = createPairingStore();\n\tconst bridge = new AgentBridge();\n\tfor (const adapter of adapters.values())\n\t\tadapter.setCommandSuggestions?.(async (source, command) => {\n\t\t\tconst session = bridge.peekSession(buildSessionKey(source, loadGatewayConfig()));\n\t\t\tif (!session) return [];\n\t\t\tif (command === \"thinking\") return session.getAvailableThinkingLevels();\n\t\t\tif (command === \"model\")\n\t\t\t\treturn (await session.modelRuntime.getAvailable()).map((model) => `${model.provider}/${model.id}`);\n\t\t\treturn [];\n\t\t});\n\tconst router = createRouter({ adapters, cfg, pairing, bridge, reloadConfig: true, remoteControls: true });\n\n\tlet finish!: () => void;\n\tconst stopped = new Promise<void>((resolve) => {\n\t\tfinish = resolve;\n\t});\n\tlet stopping = false;\n\tlet cron: ReturnType<typeof startGatewayCron> | undefined;\n\tconst platformStatus: Record<string, string> = {};\n\tconst retries = new Set<ReturnType<typeof setTimeout>>();\n\tconst shutdown = () => {\n\t\tif (stopping) return;\n\t\tstopping = true;\n\t\towner.update(platformStatus, \"stopping\");\n\t\tconst cronStopped = cron?.stop();\n\t\tfor (const timer of retries) clearTimeout(timer);\n\t\tstopButtonSweeper();\n\t\tvoid (async () => {\n\t\t\tawait cronStopped;\n\t\t\tawait bridge.shutdown();\n\t\t\tawait Promise.all([...adapters.values()].map((adapter) => adapter.disconnect().catch(() => {})));\n\t\t\tstopGatewayPresenter();\n\t\t\towner.release();\n\t\t\tprocess.removeListener(\"SIGINT\", shutdown);\n\t\t\tprocess.removeListener(\"SIGTERM\", shutdown);\n\t\t\tfinish();\n\t\t})().catch((error) => {\n\t\t\tconsole.error(\"Gateway shutdown failed:\", error instanceof Error ? error.message : String(error));\n\t\t\tstopping = false;\n\t\t\towner.update(platformStatus, Object.values(platformStatus).includes(\"connected\") ? \"ready\" : \"starting\");\n\t\t\tstartButtonSweeper();\n\t\t\tcron = startGatewayCron({ adapters, cfg });\n\t\t\tfor (const [platform, adapter] of adapters)\n\t\t\t\tif (platformStatus[platform] !== \"connected\") void connect(platform, adapter);\n\t\t});\n\t};\n\tconst owner = claimGateway(shutdown);\n\tprocess.on(\"SIGINT\", shutdown);\n\tprocess.on(\"SIGTERM\", shutdown);\n\tstartGatewayPresenter(adapters);\n\tstartButtonSweeper();\n\tconst connect = async (platform: string, adapter: PlatformAdapter): Promise<void> => {\n\t\tif (stopping) return;\n\t\ttry {\n\t\t\tplatformStatus[platform] = \"connecting\";\n\t\t\towner.update(platformStatus, Object.values(platformStatus).includes(\"connected\") ? \"ready\" : \"starting\");\n\t\t\tconst ok = await adapter.connect();\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error(\"Connection failed\");\n\t\t\t}\n\t\t\tadapter.onMessage((event) => {\n\t\t\t\tvoid router.handleEvent(event);\n\t\t\t});\n\t\t\tadapter.onCallback(async (event) => {\n\t\t\t\tconst consumed = await handleApprovalCallback(event, adapter);\n\t\t\t\tif (!consumed) {\n\t\t\t\t\tvoid handleCallback(event, { adapters, cfg: loadGatewayConfig(), pairing, bridge, adapter });\n\t\t\t\t}\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tawait adapter.registerCommands?.(botCommandSpecs());\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[gateway] ${platform}: command menu registration failed: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (stopping) {\n\t\t\t\tawait adapter.disconnect();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tplatformStatus[platform] = \"connected\";\n\t\t\tconsole.log(`lunR gateway: ${platform} connected`);\n\t\t} catch {\n\t\t\tplatformStatus[platform] = \"disconnected, retrying (check gateway logs)\";\n\t\t\tawait adapter.disconnect().catch(() => {});\n\t\t\tif (!stopping) {\n\t\t\t\tconst retry = setTimeout(() => {\n\t\t\t\t\tretries.delete(retry);\n\t\t\t\t\tvoid connect(platform, adapter);\n\t\t\t\t}, 5000);\n\t\t\t\tretries.add(retry);\n\t\t\t}\n\t\t}\n\t\tif (!stopping)\n\t\t\towner.update(platformStatus, Object.values(platformStatus).includes(\"connected\") ? \"ready\" : \"starting\");\n\t};\n\tfor (const [platform, adapter] of adapters) void connect(platform, adapter);\n\n\t// Phase 4: cron jobs fire inside the daemon and deliver back to chats.\n\t// Starts even with zero stored jobs — jobs can be created later from chats.\n\tcron = startGatewayCron({ adapters, cfg });\n\tconsole.log(`lunR gateway: cron scheduler started (${cron.intervalMs / 1000}s interval)`);\n\n\towner.update(platformStatus, \"starting\");\n\tawait stopped;\n\treturn 0;\n}\n\nexport async function runGateway(args: string[]): Promise<number> {\n\tconst [sub, ...rest] = args;\n\tif (sub === \"pair\") {\n\t\tconst [action, platform, code, flag] = rest;\n\t\tif (action === \"approve\" && platform && (flag === undefined || flag === \"--owner\"))\n\t\t\treturn runPairApprove(platform, code, flag === \"--owner\");\n\t\tif (action === \"list\") return runPairList();\n\t\tconsole.error(\"Usage: lunr gateway pair approve <platform> <code> [--owner] | lunr gateway pair list\");\n\t\treturn 1;\n\t}\n\tif (sub === \"status\") return runStatus();\n\tif (sub === undefined) return runDaemon();\n\tconsole.error(`Unknown gateway sub-command \"${sub}\". Expected: pair approve | pair list | status`);\n\treturn 1;\n}\n"]}
|
|
@@ -12,6 +12,7 @@ export declare const FORWARDED_COMMANDS: {
|
|
|
12
12
|
export declare function resolveWithinRoots(path: string, roots: string[]): string;
|
|
13
13
|
export declare function createProjectFolder(parent: string, name: string, roots: string[]): string;
|
|
14
14
|
interface MobileContext {
|
|
15
|
+
pickerGeneration?: number;
|
|
15
16
|
key: string;
|
|
16
17
|
event: MessageEvent;
|
|
17
18
|
adapter: PlatformAdapter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobile-commands.d.ts","sourceRoot":"","sources":["../../src/gateway/mobile-commands.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,aAAa,CAAC;AAGpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEhE,eAAO,MAAM,eAAe;;;GAc3B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;GAQ9B,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAiBxE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAazF;AAED,UAAU,aAAa;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,aAAa,CAAC;CACnB;AA8ED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtD;AA6JD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAkJ7G","sourcesContent":["import { mkdirSync, readdirSync, realpathSync, statSync } from \"node:fs\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"node:path\";\nimport { getPermissionMode, PERMISSION_MODES, setPermissionMode } from \"../core/permissions.ts\";\nimport { SessionManager } from \"../core/session-manager.ts\";\nimport { getSubagentCancellation } from \"../core/subagent-cancellation.ts\";\nimport { isGatewayOwner, requireGatewayOwner } from \"./authz.ts\";\nimport { createPicker, type PickerItem, type PickerResolveResult } from \"./buttons.ts\";\nimport { type GatewayConfig, loadGatewayConfig } from \"./config.ts\";\nimport { bindConversation, conversationBinding } from \"./conversations.ts\";\nimport { gatewayInput, gatewaySelect } from \"./presenter.ts\";\nimport type { BridgeLike } from \"./router.ts\";\nimport type { MessageEvent, PlatformAdapter } from \"./types.ts\";\n\nexport const MOBILE_COMMANDS = [\n\t{ name: \"project\", description: \"Browse folders and choose a project\" },\n\t{ name: \"continue\", description: \"Continue a handoff or the latest TUI session\" },\n\t{ name: \"sessions\", description: \"Browse saved sessions across projects\" },\n\t{ name: \"mode\", description: \"Choose yolo, auto, or read-only permissions\" },\n\t{ name: \"plan\", description: \"Plan work and approve it from this chat\" },\n\t{ name: \"settings\", description: \"Change this session's model, thinking, or permissions\" },\n\t{ name: \"stopall\", description: \"Stop this session and its background subagents\" },\n\t{ name: \"download\", description: \"Send a file from the current project\" },\n\t{ name: \"usage\", description: \"Show session tokens and subscription usage\" },\n\t{ name: \"processes\", description: \"List or stop this session's shell processes\" },\n\t{ name: \"refresh\", description: \"Refresh available models\" },\n\t{ name: \"skill\", description: \"Choose a skill and send it a task\" },\n\t{ name: \"fast\", description: \"Toggle OpenAI Codex fast mode\" },\n];\n\nexport const FORWARDED_COMMANDS = [\n\t{ name: \"goal\", description: \"Set or manage the session goal\" },\n\t{ name: \"cron\", description: \"Schedule prompts and manage scheduled jobs\" },\n\t{ name: \"run\", description: \"Launch a subagent task\" },\n\t{ name: \"chain\", description: \"Run a sequence of subagent tasks\" },\n\t{ name: \"parallel\", description: \"Run independent subagent tasks\" },\n\t{ name: \"mcp\", description: \"Show configured MCP servers\" },\n\t{ name: \"lsp\", description: \"Show language server status\" },\n];\n\nexport function resolveWithinRoots(path: string, roots: string[]): string {\n\tconst actual = realpathSync(resolve(path));\n\tif (\n\t\t!roots.some((root) => {\n\t\t\ttry {\n\t\t\t\tconst rel = relative(realpathSync(root), actual);\n\t\t\t\treturn (\n\t\t\t\t\trel === \"\" ||\n\t\t\t\t\t(!rel.startsWith(`..${process.platform === \"win32\" ? \"\\\\\" : \"/\"}`) && rel !== \"..\" && !isAbsolute(rel))\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t})\n\t)\n\t\tthrow new Error(\"That path is outside the approved folders.\");\n\treturn actual;\n}\n\nexport function createProjectFolder(parent: string, name: string, roots: string[]): string {\n\tif (\n\t\t!name ||\n\t\tname === \".\" ||\n\t\tname === \"..\" ||\n\t\t/[\\\\/\\x00-\\x1f<>:\"|?*]/.test(name) ||\n\t\t/[. ]$/.test(name) ||\n\t\t/^(con|prn|aux|nul|com\\d|lpt\\d)(\\.|$)/i.test(name)\n\t)\n\t\tthrow new Error(\"Use a simple folder name without slashes or reserved characters.\");\n\tconst actual = resolveWithinRoots(parent, roots);\n\tmkdirSync(join(actual, name));\n\treturn resolveWithinRoots(join(actual, name), roots);\n}\n\ninterface MobileContext {\n\tkey: string;\n\tevent: MessageEvent;\n\tadapter: PlatformAdapter;\n\tbridge: BridgeLike;\n\tcfg: GatewayConfig;\n}\n\nasync function browseProject(ctx: MobileContext, initialPath?: string): Promise<void> {\n\tconst { key, event, adapter, bridge } = ctx;\n\tconst roots = ctx.cfg.projectRoots ?? [];\n\tif (!roots.length) throw new Error(\"Add approved project folders with lunr gateway setup first.\");\n\tlet current: string | undefined = initialPath\n\t\t? resolveWithinRoots(initialPath, ctx.cfg.projectRoots ?? [])\n\t\t: undefined;\n\tconst view = (): { title: string; items: PickerItem[] } => {\n\t\tif (!current)\n\t\t\treturn {\n\t\t\t\ttitle: \"Choose a project folder\",\n\t\t\t\titems: [...new Set([...(conversationBinding(key)?.recentProjects ?? []), ...roots])]\n\t\t\t\t\t.filter((p) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresolveWithinRoots(p, roots);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.map((p) => ({ label: p, value: p })),\n\t\t\t};\n\t\tcurrent = resolveWithinRoots(current, roots);\n\t\tconst items: PickerItem[] = [\n\t\t\t{ label: \"Use this folder\", value: \"use\" },\n\t\t\t{ label: \"New folder\", value: \"new\" },\n\t\t\t{ label: \"Recent and roots\", value: \"roots\" },\n\t\t];\n\t\ttry {\n\t\t\tconst up = resolveWithinRoots(dirname(current), roots);\n\t\t\tif (up !== current) items.push({ label: \"Up\", value: up });\n\t\t} catch {}\n\t\tfor (const item of readdirSync(current, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {\n\t\t\tif (!item.isDirectory() && !item.isSymbolicLink()) continue;\n\t\t\ttry {\n\t\t\t\tconst path = resolveWithinRoots(join(current, item.name), roots);\n\t\t\t\tif (statSync(path).isDirectory()) items.push({ label: item.name, value: path });\n\t\t\t} catch {}\n\t\t}\n\t\treturn { title: current, items };\n\t};\n\tconst initial = view();\n\tawait createPicker(\n\t\tadapter,\n\t\tevent.source,\n\t\t{\n\t\t\tkind: \"project\",\n\t\t\tsessionKey: key,\n\t\t\tinvokerId: event.source.userId,\n\t\t\t...initial,\n\t\t\tvalidate: () => isGatewayOwner(event.source, loadGatewayConfig()),\n\t\t\tresolve: async (item): Promise<PickerResolveResult> => {\n\t\t\t\trequireGatewayOwner(event.source);\n\t\t\t\tif (item.value === \"use\" && current) {\n\t\t\t\t\tconst cwd = resolveWithinRoots(current, loadGatewayConfig().projectRoots ?? []);\n\t\t\t\t\tif (bridge.getStatus(key).busy)\n\t\t\t\t\t\tthrow new Error(\"Stop the current turn or wait before switching projects.\");\n\t\t\t\t\tawait bridge.reset(key);\n\t\t\t\t\tbindConversation(key, event.source, { cwd, owner: event.source.userId });\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdone: true,\n\t\t\t\t\t\ttext: `Project selected: ${cwd}\\nSend a task to begin. Existing sessions are still available through /sessions.`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (item.value === \"new\" && current) {\n\t\t\t\t\tconst name = await gatewayInput(key, \"New folder name\");\n\t\t\t\t\tif (name) current = createProjectFolder(current, name, loadGatewayConfig().projectRoots ?? []);\n\t\t\t\t} else current = item.value === \"roots\" ? undefined : item.value;\n\t\t\t\treturn { done: false, ...view() };\n\t\t\t},\n\t\t},\n\t\t{ threadId: event.source.threadId },\n\t);\n}\n\nconst transfers = new Map<string, AbortController>();\nexport function cancelMobileTransfer(key: string): void {\n\ttransfers.get(key)?.abort();\n}\n\nasync function continueSession(ctx: MobileContext, file: string): Promise<void> {\n\tif (transfers.has(ctx.key)) throw new Error(\"A session transfer is already pending. Use /stop to cancel it.\");\n\tconst controller = new AbortController();\n\ttransfers.set(ctx.key, controller);\n\ttry {\n\t\tawait performContinue(ctx, file, controller.signal);\n\t} finally {\n\t\ttransfers.delete(ctx.key);\n\t}\n}\n\nasync function performContinue(ctx: MobileContext, file: string, signal: AbortSignal): Promise<void> {\n\trequireGatewayOwner(ctx.event.source);\n\tconst { requestSessionTransfer, SessionTransferError } = await import(\"../core/session-handoff.ts\");\n\tconst { key, bridge } = ctx;\n\tconst current = bridge.peekSession?.(key);\n\tif (current?.sessionManager?.getSessionFile() === file) {\n\t\tawait ctx.adapter.send(ctx.event.source.chatId, \"This session is already open here.\");\n\t\treturn;\n\t}\n\tif (bridge.getStatus(key).busy) throw new Error(\"Stop the current phone session before switching.\");\n\ttry {\n\t\tawait requestSessionTransfer(file, { timeoutMs: 3000, signal });\n\t} catch (error) {\n\t\tif (!(error instanceof SessionTransferError) || ![\"busy\", \"timeout\"].includes(error.code)) throw error;\n\t\tconst choice = await gatewaySelect(\n\t\t\tkey,\n\t\t\t`${error instanceof Error ? error.message : \"Session is in use\"}\\nHow should lunR continue?`,\n\t\t\t[\"Wait until idle\", \"Stop and continue\", \"Cancel\"],\n\t\t\t{ signal },\n\t\t);\n\t\tif (!choice || choice === \"Cancel\") return;\n\t\tif (choice === \"Stop and continue\") await requestSessionTransfer(file, { stop: true, timeoutMs: 30_000, signal });\n\t\telse {\n\t\t\tconst deadline = Date.now() + 120_000;\n\t\t\tfor (;;) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\trequireGatewayOwner(ctx.event.source);\n\t\t\t\ttry {\n\t\t\t\t\tawait requestSessionTransfer(file, { timeoutMs: 3000, signal });\n\t\t\t\t\tbreak;\n\t\t\t\t} catch (retryError) {\n\t\t\t\t\tif (\n\t\t\t\t\t\t!(retryError instanceof SessionTransferError) ||\n\t\t\t\t\t\t![\"busy\", \"timeout\"].includes(retryError.code) ||\n\t\t\t\t\t\tDate.now() >= deadline\n\t\t\t\t\t)\n\t\t\t\t\t\tthrow retryError;\n\t\t\t\t}\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 500));\n\t\t\t}\n\t\t}\n\t}\n\tsignal.throwIfAborted();\n\trequireGatewayOwner(ctx.event.source);\n\tawait bridge.switchSession(key, file);\n\tconst session = await bridge.getSession(key);\n\tconst cwd = session?.sessionManager?.getCwd();\n\tbindConversation(key, ctx.event.source, { cwd, owner: ctx.event.source.userId });\n\tconst id = session?.sessionManager?.getSessionId();\n\tif (id && [\"auto\", \"yolo\"].includes(getPermissionMode(id))) {\n\t\tconst requested = getPermissionMode(id);\n\t\tsetPermissionMode(\"read-only\", id);\n\t\tsession?.sessionManager?.setPermissionMode?.(\"read-only\");\n\t\tif (\n\t\t\t(await gatewaySelect(\n\t\t\t\tkey,\n\t\t\t\t`Continue with ${requested} permissions? Tools can change files and run commands without individual approval.`,\n\t\t\t\t[\"Keep read-only\", `Use ${requested}`],\n\t\t\t)) === `Use ${requested}`\n\t\t) {\n\t\t\tsetPermissionMode(requested, id);\n\t\t\tsession?.sessionManager?.setPermissionMode?.(requested);\n\t\t}\n\t}\n\tawait ctx.adapter.send(\n\t\tctx.event.source.chatId,\n\t\t`Continuing ${session?.sessionManager?.getSessionName() ?? basename(file)}\\nProject: ${cwd}\\nSend your next instruction.`,\n\t\t{ threadId: ctx.event.source.threadId },\n\t);\n}\n\nasync function browseSessions(ctx: MobileContext, args: string, quick: boolean): Promise<void> {\n\tconst handoff = await import(\"../core/session-handoff.ts\");\n\tif (quick) {\n\t\tconst candidates = handoff.listHandoffCandidates();\n\t\tif (!candidates.length) {\n\t\t\tconst latest = handoff.latestTuiSession();\n\t\t\tif (!latest)\n\t\t\t\tthrow new Error(\"No recent TUI session found. Use /sessions or mark one in the terminal with /handoff.\");\n\t\t\tawait continueSession(ctx, latest.sessionFile);\n\t\t\treturn;\n\t\t}\n\t\tif (candidates.length === 1) {\n\t\t\tawait continueSession(ctx, candidates[0].sessionFile);\n\t\t\treturn;\n\t\t}\n\t\tawait sessionPicker(\n\t\t\tctx,\n\t\t\tcandidates.map((s) => ({ label: `${s.cwd} · ${basename(s.sessionFile)}`, value: s.sessionFile })),\n\t\t);\n\t\treturn;\n\t}\n\tconst sessions = await SessionManager.listAll();\n\tconst known = new Set(sessions.map((s) => s.path));\n\tfor (const file of handoff.listRegisteredSessionPaths()) {\n\t\tif (known.has(file)) continue;\n\t\ttry {\n\t\t\tconst manager = SessionManager.openReadOnly(file);\n\t\t\tconst header = manager.getHeader();\n\t\t\tif (header)\n\t\t\t\tsessions.push({\n\t\t\t\t\tid: header.id,\n\t\t\t\t\tpath: file,\n\t\t\t\t\tcwd: manager.getCwd(),\n\t\t\t\t\tname: manager.getSessionName(),\n\t\t\t\t\tcreated: new Date(header.timestamp),\n\t\t\t\t\tmodified: statSync(file).mtime,\n\t\t\t\t\tmessageCount: manager.getEntries().length,\n\t\t\t\t\tfirstMessage: \"\",\n\t\t\t\t\tallMessagesText: \"\",\n\t\t\t\t});\n\t\t} catch {}\n\t}\n\tconst query = args.toLowerCase();\n\tconst items = sessions\n\t\t.sort((a, b) => b.modified.getTime() - a.modified.getTime())\n\t\t.filter((s) => !query || `${s.name ?? \"\"} ${s.cwd} ${s.id}`.toLowerCase().includes(query))\n\t\t.map((s) => ({\n\t\t\tlabel: `${s.name || s.firstMessage.slice(0, 35) || s.id.slice(0, 8)} · ${basename(s.cwd)} · ${s.modified.toLocaleDateString()}`,\n\t\t\tvalue: s.path,\n\t\t}));\n\tawait sessionPicker(ctx, items);\n}\n\nasync function sessionPicker(ctx: MobileContext, items: PickerItem[]): Promise<void> {\n\tawait createPicker(\n\t\tctx.adapter,\n\t\tctx.event.source,\n\t\t{\n\t\t\tkind: \"sessions\",\n\t\t\tsessionKey: ctx.key,\n\t\t\tinvokerId: ctx.event.source.userId,\n\t\t\ttitle: \"Choose a session. Use /sessions <search> to filter.\",\n\t\t\titems,\n\t\t\tvalidate: () => isGatewayOwner(ctx.event.source, loadGatewayConfig()),\n\t\t\tresolve: async (item) => {\n\t\t\t\tawait continueSession(ctx, item.value);\n\t\t\t\treturn { done: true, text: \"Session selection finished.\" };\n\t\t\t},\n\t\t},\n\t\t{ threadId: ctx.event.source.threadId },\n\t);\n}\n\nexport async function handleMobileCommand(ctx: MobileContext, command: string, args: string): Promise<boolean> {\n\tif (!MOBILE_COMMANDS.some((c) => c.name === command) && command !== \"resume\") return false;\n\trequireGatewayOwner(ctx.event.source, ctx.cfg);\n\tbindConversation(ctx.key, ctx.event.source, { owner: ctx.event.source.userId });\n\tif (command === \"project\") {\n\t\tawait browseProject(ctx, args.trim() || undefined);\n\t\treturn true;\n\t}\n\tif (command === \"sessions\" || command === \"resume\" || command === \"continue\") {\n\t\tawait browseSessions(ctx, args, command === \"continue\");\n\t\treturn true;\n\t}\n\tconst session = await ctx.bridge.getSession(ctx.key);\n\tif (!session) throw new Error(\"Select a project and send a task, or use /continue first.\");\n\tconst id = session.sessionManager?.getSessionId();\n\tif (command === \"usage\") {\n\t\tconst stats = session.getSessionStats();\n\t\tconst plans = await (await import(\"../core/usage-service.ts\")).getAllPlanUsageResults(\n\t\t\tsession.model?.provider,\n\t\t\tsession.modelRuntime,\n\t\t);\n\t\tawait ctx.adapter.send(\n\t\t\tctx.event.source.chatId,\n\t\t\t[\n\t\t\t\t`Tokens: ${stats.tokens.total} · cost: $${stats.cost.toFixed(4)}`,\n\t\t\t\t...plans.usages.flatMap((p) =>\n\t\t\t\t\tp.windows.map((w) => `${p.provider} ${w.label}: ${w.usedPercent.toFixed(1)}% used`),\n\t\t\t\t),\n\t\t\t\t...plans.errors,\n\t\t\t].join(\"\\n\"),\n\t\t);\n\t\treturn true;\n\t}\n\tif (command === \"processes\") {\n\t\tif (!id) throw new Error(\"No session identity.\");\n\t\tconst processes = await import(\"../core/process-registry.ts\");\n\t\tconst own = processes.list(id);\n\t\tif (args) {\n\t\t\tconst [action, raw] = args.split(/\\s+/);\n\t\t\tconst pid = Number(raw);\n\t\t\tif (action !== \"stop\" || !own.some((p) => p.pid === pid))\n\t\t\t\tthrow new Error(\"Usage: /processes stop <pid> from this session's process list.\");\n\t\t\tprocesses.kill(pid);\n\t\t\tawait ctx.adapter.send(ctx.event.source.chatId, `Stop requested for process ${pid}.`);\n\t\t} else\n\t\t\tawait ctx.adapter.send(\n\t\t\t\tctx.event.source.chatId,\n\t\t\t\town.length\n\t\t\t\t\t? own\n\t\t\t\t\t\t\t.map((p) => `${p.pid} · ${p.status} · ${p.command}`)\n\t\t\t\t\t\t\t.join(\"\\n\")\n\t\t\t\t\t\t\t.slice(0, ctx.adapter.maxMessageLength)\n\t\t\t\t\t: \"No tracked processes.\",\n\t\t\t);\n\t\treturn true;\n\t}\n\tif (command === \"stopall\") {\n\t\tawait ctx.bridge.abort(ctx.key);\n\t\tconst result = id ? await getSubagentCancellation(id)?.stop() : undefined;\n\t\tconst processes = await import(\"../core/process-registry.ts\");\n\t\tconst count = id ? processes.list(id).filter((p) => p.status !== \"exited\").length : 0;\n\t\tif (id) processes.killAll(id);\n\t\tawait ctx.adapter.send(\n\t\t\tctx.event.source.chatId,\n\t\t\t`Stopped the current turn. Requested stop for ${result?.requested ?? 0} background runs and ${count} tracked processes${result?.failed ? `; ${result.failed} requests failed` : \"\"}. Wait for them to exit before transferring.`,\n\t\t);\n\t\treturn true;\n\t}\n\tif (ctx.bridge.getStatus(ctx.key).busy) throw new Error(\"Wait for the current turn or use /stop first.\");\n\tif (command === \"refresh\") {\n\t\tawait session.modelRuntime.refresh();\n\t\tawait ctx.adapter.send(ctx.event.source.chatId, \"Model catalog refreshed. Use /model to choose.\");\n\t\treturn true;\n\t}\n\tif (command === \"fast\") {\n\t\tif (session.model?.provider !== \"openai-codex\" || !session.settingsManager)\n\t\t\tthrow new Error(\"Fast mode is available only for OpenAI Codex subscriptions.\");\n\t\tconst current = session.settingsManager.getOpenAIFastMode();\n\t\tif (args && ![\"on\", \"off\", \"status\"].includes(args)) throw new Error(\"Usage: /fast on|off|status\");\n\t\tif (args !== \"status\") session.settingsManager.setOpenAIFastMode(args ? args === \"on\" : !current);\n\t\tawait ctx.adapter.send(\n\t\t\tctx.event.source.chatId,\n\t\t\t`Fast mode: ${session.settingsManager.getOpenAIFastMode() ? \"on\" : \"off\"}`,\n\t\t);\n\t\treturn true;\n\t}\n\tif (command === \"skill\") {\n\t\tconst names = session.resourceLoader?.getSkills().skills.map((s) => s.name) ?? [];\n\t\tconst [name, ...task] = args.split(/\\s+/).filter(Boolean);\n\t\tconst chosen = name || (await gatewaySelect(ctx.key, \"Choose a skill\", names));\n\t\tif (!chosen) return true;\n\t\tif (!names.includes(chosen)) throw new Error(\"That skill is not loaded for this project.\");\n\t\tctx.event.text = `/skill:${chosen} ${task.join(\" \") || (await gatewayInput(ctx.key, \"What should this skill do?\")) || \"\"}`;\n\t\treturn false;\n\t}\n\tif (command === \"download\") {\n\t\tif (!ctx.adapter.sendFile) throw new Error(\"This platform cannot send files.\");\n\t\tif (!args) throw new Error(\"Usage: /download <project-relative path>\");\n\t\tconst cwd = session.sessionManager?.getCwd();\n\t\tif (!cwd) throw new Error(\"No project selected.\");\n\t\tconst file = resolveWithinRoots(resolve(cwd, args), [cwd]);\n\t\tconst stat = statSync(file);\n\t\tif (!stat.isFile() || stat.size > 8 * 1024 * 1024) throw new Error(\"Choose a file no larger than 8 MB.\");\n\t\tif (\n\t\t\t/(^|[\\\\/])(?:\\.env(?:\\.[^\\\\/]*)?|auth\\.json|gateway\\.json|credentials[^\\\\/]*|id_rsa|id_ed25519)([\\\\/]|$)/i.test(\n\t\t\t\tfile,\n\t\t\t)\n\t\t)\n\t\t\tthrow new Error(\"Credential files cannot be sent through chat.\");\n\t\tconst result = await ctx.adapter.sendFile(ctx.event.source.chatId, file, { threadId: ctx.event.source.threadId });\n\t\tif (!result.success) throw new Error(result.error ?? \"File delivery failed.\");\n\t\treturn true;\n\t}\n\tif (command === \"settings\") {\n\t\tconst choice = await gatewaySelect(ctx.key, \"Session settings\", [\"Model\", \"Thinking\", \"Permissions\"]);\n\t\tif (choice === \"Model\" || choice === \"Thinking\") {\n\t\t\tconst { CHAT_COMMANDS, runChatCommand } = await import(\"./commands.ts\");\n\t\t\tconst cmd = CHAT_COMMANDS.find((c) => c.name === choice.toLowerCase());\n\t\t\tif (cmd)\n\t\t\t\tawait runChatCommand(cmd, {\n\t\t\t\t\t...ctx,\n\t\t\t\t\targs: \"\",\n\t\t\t\t\treply: async (text) => {\n\t\t\t\t\t\tawait ctx.adapter.send(ctx.event.source.chatId, text);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\treturn true;\n\t\t}\n\t\tif (choice !== \"Permissions\") return true;\n\t}\n\tconst requested =\n\t\tcommand === \"plan\"\n\t\t\t? \"read-only\"\n\t\t\t: args || (await gatewaySelect(ctx.key, `Permission mode: ${getPermissionMode(id)}`, [...PERMISSION_MODES]));\n\tif (!requested) return true;\n\tconst mode = requested === \"read\" ? \"read-only\" : requested;\n\tif (!PERMISSION_MODES.includes(mode as (typeof PERMISSION_MODES)[number]))\n\t\tthrow new Error(\"Choose yolo, auto, or read-only.\");\n\tsetPermissionMode(mode as (typeof PERMISSION_MODES)[number], id);\n\tsession.sessionManager?.setPermissionMode?.(mode as (typeof PERMISSION_MODES)[number]);\n\tawait ctx.adapter.send(ctx.event.source.chatId, `Permission mode: ${mode}`);\n\tif (command === \"plan\" && args) {\n\t\tctx.event.text = `Create a plan for: ${args}`;\n\t\treturn false;\n\t}\n\treturn true;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mobile-commands.d.ts","sourceRoot":"","sources":["../../src/gateway/mobile-commands.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,aAAa,CAAC;AAGpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEhE,eAAO,MAAM,eAAe;;;GAc3B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;GAQ9B,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAiBxE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAazF;AAED,UAAU,aAAa;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,aAAa,CAAC;CACnB;AAkHD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtD;AAgKD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAsJ7G","sourcesContent":["import { mkdirSync, readdirSync, realpathSync, statSync } from \"node:fs\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"node:path\";\nimport type { ExtensionUIDialogOptions } from \"../core/extensions/types.ts\";\nimport { getPermissionMode, PERMISSION_MODES, setPermissionMode } from \"../core/permissions.ts\";\nimport { SessionManager } from \"../core/session-manager.ts\";\nimport { getSubagentCancellation } from \"../core/subagent-cancellation.ts\";\nimport { isAuthorized, requireAuthorized } from \"./authz.ts\";\nimport {\n\tcreatePicker,\n\tGatewayPickerCancelled,\n\tgatewayPickerGeneration,\n\ttype PickerItem,\n\ttype PickerResolveResult,\n} from \"./buttons.ts\";\nimport { type GatewayConfig, loadGatewayConfig } from \"./config.ts\";\nimport { bindConversation, conversationBinding } from \"./conversations.ts\";\nimport { gatewayInput, gatewaySelect, invalidateGatewayDialogs } from \"./presenter.ts\";\nimport type { BridgeLike } from \"./router.ts\";\nimport type { MessageEvent, PlatformAdapter } from \"./types.ts\";\n\nexport const MOBILE_COMMANDS = [\n\t{ name: \"project\", description: \"Browse folders and choose a project\" },\n\t{ name: \"continue\", description: \"Continue a handoff or the latest TUI session\" },\n\t{ name: \"sessions\", description: \"Browse saved sessions across projects\" },\n\t{ name: \"mode\", description: \"Choose yolo, auto, or read-only permissions\" },\n\t{ name: \"plan\", description: \"Plan work and approve it from this chat\" },\n\t{ name: \"settings\", description: \"Change this session's model, thinking, or permissions\" },\n\t{ name: \"stopall\", description: \"Stop this session and its background subagents\" },\n\t{ name: \"download\", description: \"Send a file from the current project\" },\n\t{ name: \"usage\", description: \"Show session tokens and subscription usage\" },\n\t{ name: \"processes\", description: \"List or stop this session's shell processes\" },\n\t{ name: \"refresh\", description: \"Refresh available models\" },\n\t{ name: \"skill\", description: \"Choose a skill and send it a task\" },\n\t{ name: \"fast\", description: \"Toggle OpenAI Codex fast mode\" },\n];\n\nexport const FORWARDED_COMMANDS = [\n\t{ name: \"goal\", description: \"Set or manage the session goal\" },\n\t{ name: \"cron\", description: \"Schedule prompts and manage scheduled jobs\" },\n\t{ name: \"run\", description: \"Launch a subagent task\" },\n\t{ name: \"chain\", description: \"Run a sequence of subagent tasks\" },\n\t{ name: \"parallel\", description: \"Run independent subagent tasks\" },\n\t{ name: \"mcp\", description: \"Show configured MCP servers\" },\n\t{ name: \"lsp\", description: \"Show language server status\" },\n];\n\nexport function resolveWithinRoots(path: string, roots: string[]): string {\n\tconst actual = realpathSync(resolve(path));\n\tif (\n\t\t!roots.some((root) => {\n\t\t\ttry {\n\t\t\t\tconst rel = relative(realpathSync(root), actual);\n\t\t\t\treturn (\n\t\t\t\t\trel === \"\" ||\n\t\t\t\t\t(!rel.startsWith(`..${process.platform === \"win32\" ? \"\\\\\" : \"/\"}`) && rel !== \"..\" && !isAbsolute(rel))\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t})\n\t)\n\t\tthrow new Error(\"That path is outside the approved folders.\");\n\treturn actual;\n}\n\nexport function createProjectFolder(parent: string, name: string, roots: string[]): string {\n\tif (\n\t\t!name ||\n\t\tname === \".\" ||\n\t\tname === \"..\" ||\n\t\t/[\\\\/\\x00-\\x1f<>:\"|?*]/.test(name) ||\n\t\t/[. ]$/.test(name) ||\n\t\t/^(con|prn|aux|nul|com\\d|lpt\\d)(\\.|$)/i.test(name)\n\t)\n\t\tthrow new Error(\"Use a simple folder name without slashes or reserved characters.\");\n\tconst actual = resolveWithinRoots(parent, roots);\n\tmkdirSync(join(actual, name));\n\treturn resolveWithinRoots(join(actual, name), roots);\n}\n\ninterface MobileContext {\n\tpickerGeneration?: number;\n\tkey: string;\n\tevent: MessageEvent;\n\tadapter: PlatformAdapter;\n\tbridge: BridgeLike;\n\tcfg: GatewayConfig;\n}\n\nfunction commandRequest(ctx: MobileContext) {\n\treturn { generation: ctx.pickerGeneration ?? gatewayPickerGeneration(ctx.key), source: ctx.event.source };\n}\n\nfunction selectForCommand(ctx: MobileContext, title: string, options: string[], opts?: ExtensionUIDialogOptions) {\n\treturn gatewaySelect(ctx.key, title, options, opts, commandRequest(ctx));\n}\n\nfunction inputForCommand(ctx: MobileContext, title: string) {\n\treturn gatewayInput(ctx.key, title, undefined, undefined, commandRequest(ctx));\n}\n\nasync function browseProject(ctx: MobileContext, initialPath?: string): Promise<void> {\n\tconst { key, event, adapter, bridge } = ctx;\n\tconst roots = ctx.cfg.projectRoots ?? [];\n\tif (!roots.length) throw new Error(\"Add approved project folders with lunr gateway setup first.\");\n\tlet current: string | undefined = initialPath\n\t\t? resolveWithinRoots(initialPath, ctx.cfg.projectRoots ?? [])\n\t\t: undefined;\n\tconst view = (): { title: string; items: PickerItem[] } => {\n\t\tif (!current)\n\t\t\treturn {\n\t\t\t\ttitle: \"Choose a project folder\",\n\t\t\t\titems: [...new Set([...(conversationBinding(key)?.recentProjects ?? []), ...roots])]\n\t\t\t\t\t.filter((p) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresolveWithinRoots(p, roots);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.map((p) => ({ label: p, value: p })),\n\t\t\t};\n\t\tcurrent = resolveWithinRoots(current, roots);\n\t\tconst items: PickerItem[] = [\n\t\t\t{ label: \"Use this folder\", value: \"use\" },\n\t\t\t{ label: \"New folder\", value: \"new\" },\n\t\t\t{ label: \"Recent and roots\", value: \"roots\" },\n\t\t];\n\t\ttry {\n\t\t\tconst up = resolveWithinRoots(dirname(current), roots);\n\t\t\tif (up !== current) items.push({ label: \"Up\", value: up });\n\t\t} catch {}\n\t\tfor (const item of readdirSync(current, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {\n\t\t\tif (!item.isDirectory() && !item.isSymbolicLink()) continue;\n\t\t\ttry {\n\t\t\t\tconst path = resolveWithinRoots(join(current, item.name), roots);\n\t\t\t\tif (statSync(path).isDirectory()) items.push({ label: item.name, value: path });\n\t\t\t} catch {}\n\t\t}\n\t\treturn { title: current, items };\n\t};\n\tconst initial = view();\n\tawait createPicker(\n\t\tadapter,\n\t\tevent.source,\n\t\t{\n\t\t\tkind: \"project\",\n\t\t\tsessionKey: key,\n\t\t\tgeneration: ctx.pickerGeneration,\n\t\t\tinvokerId: event.source.userId,\n\t\t\t...initial,\n\t\t\tvalidate: () => isAuthorized(event.source, loadGatewayConfig()),\n\t\t\tresolve: async (item): Promise<PickerResolveResult> => {\n\t\t\t\trequireAuthorized(event.source);\n\t\t\t\tif (item.value === \"use\" && current) {\n\t\t\t\t\tconst cwd = resolveWithinRoots(current, loadGatewayConfig().projectRoots ?? []);\n\t\t\t\t\tif (bridge.getStatus(key).busy)\n\t\t\t\t\t\tthrow new Error(\"Stop the current turn or wait before switching projects.\");\n\t\t\t\t\tlet committed = false;\n\t\t\t\t\tawait bridge.reset(key, {\n\t\t\t\t\t\tvalidate: () => {\n\t\t\t\t\t\t\trequireAuthorized(event.source);\n\t\t\t\t\t\t\tconst binding = conversationBinding(key);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!binding ||\n\t\t\t\t\t\t\t\tbinding.owner !== event.source.userId ||\n\t\t\t\t\t\t\t\tbinding.source.userId !== event.source.userId ||\n\t\t\t\t\t\t\t\tbinding.source.platform !== event.source.platform ||\n\t\t\t\t\t\t\t\tbinding.source.chatId !== event.source.chatId ||\n\t\t\t\t\t\t\t\tbinding.source.threadId !== event.source.threadId\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthrow new GatewayPickerCancelled(\"Project requester changed before selection completed.\");\n\t\t\t\t\t\t\tresolveWithinRoots(cwd, loadGatewayConfig().projectRoots ?? []);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcommit: () => {\n\t\t\t\t\t\t\tbindConversation(key, event.source, { cwd, owner: event.source.userId });\n\t\t\t\t\t\t\tcommitted = true;\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tif (!committed)\n\t\t\t\t\t\tthrow new Error(\"The gateway did not commit project replacement. Retry with an updated gateway.\");\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdone: true,\n\t\t\t\t\t\ttext: `Project selected: ${cwd}\\nSend a task to begin. Existing sessions are still available through /sessions.`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (item.value === \"new\" && current) {\n\t\t\t\t\tconst name = await inputForCommand(ctx, \"New folder name\");\n\t\t\t\t\tif (ctx.pickerGeneration !== gatewayPickerGeneration(key))\n\t\t\t\t\t\treturn { done: true, text: \"Selection cancelled.\" };\n\t\t\t\t\tif (name) current = createProjectFolder(current, name, loadGatewayConfig().projectRoots ?? []);\n\t\t\t\t} else current = item.value === \"roots\" ? undefined : item.value;\n\t\t\t\treturn { done: false, ...view() };\n\t\t\t},\n\t\t},\n\t\t{ threadId: event.source.threadId },\n\t);\n}\n\nconst transfers = new Map<string, AbortController>();\nexport function cancelMobileTransfer(key: string): void {\n\ttransfers.get(key)?.abort();\n}\n\nasync function continueSession(ctx: MobileContext, file: string): Promise<void> {\n\tif (transfers.has(ctx.key)) throw new Error(\"A session transfer is already pending. Use /stop to cancel it.\");\n\tconst controller = new AbortController();\n\ttransfers.set(ctx.key, controller);\n\ttry {\n\t\tawait performContinue(ctx, file, controller.signal);\n\t} finally {\n\t\ttransfers.delete(ctx.key);\n\t}\n}\n\nasync function performContinue(ctx: MobileContext, file: string, signal: AbortSignal): Promise<void> {\n\trequireAuthorized(ctx.event.source);\n\tconst { requestSessionTransfer, SessionTransferError } = await import(\"../core/session-handoff.ts\");\n\tconst { key, bridge } = ctx;\n\tconst current = bridge.peekSession?.(key);\n\tif (current?.sessionManager?.getSessionFile() === file) {\n\t\tawait ctx.adapter.send(ctx.event.source.chatId, \"This session is already open here.\");\n\t\treturn;\n\t}\n\tif (bridge.getStatus(key).busy) throw new Error(\"Stop the current phone session before switching.\");\n\ttry {\n\t\tawait requestSessionTransfer(file, { timeoutMs: 3000, signal });\n\t} catch (error) {\n\t\tif (!(error instanceof SessionTransferError) || ![\"busy\", \"timeout\"].includes(error.code)) throw error;\n\t\tconst choice = await selectForCommand(\n\t\t\tctx,\n\t\t\t`${error instanceof Error ? error.message : \"Session is in use\"}\\nHow should lunR continue?`,\n\t\t\t[\"Wait until idle\", \"Stop and continue\", \"Cancel\"],\n\t\t\t{ signal },\n\t\t);\n\t\tif (!choice || choice === \"Cancel\") return;\n\t\tif (choice === \"Stop and continue\") await requestSessionTransfer(file, { stop: true, timeoutMs: 30_000, signal });\n\t\telse {\n\t\t\tconst deadline = Date.now() + 120_000;\n\t\t\tfor (;;) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\trequireAuthorized(ctx.event.source);\n\t\t\t\ttry {\n\t\t\t\t\tawait requestSessionTransfer(file, { timeoutMs: 3000, signal });\n\t\t\t\t\tbreak;\n\t\t\t\t} catch (retryError) {\n\t\t\t\t\tif (\n\t\t\t\t\t\t!(retryError instanceof SessionTransferError) ||\n\t\t\t\t\t\t![\"busy\", \"timeout\"].includes(retryError.code) ||\n\t\t\t\t\t\tDate.now() >= deadline\n\t\t\t\t\t)\n\t\t\t\t\t\tthrow retryError;\n\t\t\t\t}\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 500));\n\t\t\t}\n\t\t}\n\t}\n\tsignal.throwIfAborted();\n\trequireAuthorized(ctx.event.source);\n\tif (ctx.pickerGeneration !== gatewayPickerGeneration(key)) return;\n\tawait bridge.switchSession(key, file);\n\tctx.pickerGeneration = gatewayPickerGeneration(key);\n\tconst session = await bridge.getSession(key);\n\tconst cwd = session?.sessionManager?.getCwd();\n\tbindConversation(key, ctx.event.source, { cwd, owner: ctx.event.source.userId });\n\tconst id = session?.sessionManager?.getSessionId();\n\tif (id && [\"auto\", \"yolo\"].includes(getPermissionMode(id))) {\n\t\tconst requested = getPermissionMode(id);\n\t\tsetPermissionMode(\"read-only\", id);\n\t\tsession?.sessionManager?.setPermissionMode?.(\"read-only\");\n\t\tif (\n\t\t\t(await selectForCommand(\n\t\t\t\tctx,\n\t\t\t\t`Continue with ${requested} permissions? Tools can change files and run commands without individual approval.`,\n\t\t\t\t[\"Keep read-only\", `Use ${requested}`],\n\t\t\t)) === `Use ${requested}`\n\t\t) {\n\t\t\tsetPermissionMode(requested, id);\n\t\t\tsession?.sessionManager?.setPermissionMode?.(requested);\n\t\t}\n\t}\n\tawait ctx.adapter.send(\n\t\tctx.event.source.chatId,\n\t\t`Continuing ${session?.sessionManager?.getSessionName() ?? basename(file)}\\nProject: ${cwd}\\nSend your next instruction.`,\n\t\t{ threadId: ctx.event.source.threadId },\n\t);\n}\n\nasync function browseSessions(ctx: MobileContext, args: string, quick: boolean): Promise<void> {\n\tconst handoff = await import(\"../core/session-handoff.ts\");\n\tif (quick) {\n\t\tconst candidates = handoff.listHandoffCandidates();\n\t\tif (!candidates.length) {\n\t\t\tconst latest = handoff.latestTuiSession();\n\t\t\tif (!latest)\n\t\t\t\tthrow new Error(\"No recent TUI session found. Use /sessions or mark one in the terminal with /handoff.\");\n\t\t\tawait continueSession(ctx, latest.sessionFile);\n\t\t\treturn;\n\t\t}\n\t\tif (candidates.length === 1) {\n\t\t\tawait continueSession(ctx, candidates[0].sessionFile);\n\t\t\treturn;\n\t\t}\n\t\tawait sessionPicker(\n\t\t\tctx,\n\t\t\tcandidates.map((s) => ({ label: `${s.cwd} · ${basename(s.sessionFile)}`, value: s.sessionFile })),\n\t\t);\n\t\treturn;\n\t}\n\tconst sessions = await SessionManager.listAll();\n\tconst known = new Set(sessions.map((s) => s.path));\n\tfor (const file of handoff.listRegisteredSessionPaths()) {\n\t\tif (known.has(file)) continue;\n\t\ttry {\n\t\t\tconst manager = SessionManager.openReadOnly(file);\n\t\t\tconst header = manager.getHeader();\n\t\t\tif (header)\n\t\t\t\tsessions.push({\n\t\t\t\t\tid: header.id,\n\t\t\t\t\tpath: file,\n\t\t\t\t\tcwd: manager.getCwd(),\n\t\t\t\t\tname: manager.getSessionName(),\n\t\t\t\t\tcreated: new Date(header.timestamp),\n\t\t\t\t\tmodified: statSync(file).mtime,\n\t\t\t\t\tmessageCount: manager.getEntries().length,\n\t\t\t\t\tfirstMessage: \"\",\n\t\t\t\t\tallMessagesText: \"\",\n\t\t\t\t});\n\t\t} catch {}\n\t}\n\tconst query = args.toLowerCase();\n\tconst items = sessions\n\t\t.sort((a, b) => b.modified.getTime() - a.modified.getTime())\n\t\t.filter((s) => !query || `${s.name ?? \"\"} ${s.cwd} ${s.id}`.toLowerCase().includes(query))\n\t\t.map((s) => ({\n\t\t\tlabel: `${s.name || s.firstMessage.slice(0, 35) || s.id.slice(0, 8)} · ${basename(s.cwd)} · ${s.modified.toLocaleDateString()}`,\n\t\t\tvalue: s.path,\n\t\t}));\n\tawait sessionPicker(ctx, items);\n}\n\nasync function sessionPicker(ctx: MobileContext, items: PickerItem[]): Promise<void> {\n\tawait createPicker(\n\t\tctx.adapter,\n\t\tctx.event.source,\n\t\t{\n\t\t\tkind: \"sessions\",\n\t\t\tsessionKey: ctx.key,\n\t\t\tgeneration: ctx.pickerGeneration,\n\t\t\tinvokerId: ctx.event.source.userId,\n\t\t\ttitle: \"Choose a session. Use /sessions <search> to filter.\",\n\t\t\titems,\n\t\t\tvalidate: () => isAuthorized(ctx.event.source, loadGatewayConfig()),\n\t\t\tresolve: async (item) => {\n\t\t\t\tawait continueSession(ctx, item.value);\n\t\t\t\treturn { done: true, text: \"Session selection finished.\" };\n\t\t\t},\n\t\t},\n\t\t{ threadId: ctx.event.source.threadId },\n\t);\n}\n\nexport async function handleMobileCommand(ctx: MobileContext, command: string, args: string): Promise<boolean> {\n\tif (!MOBILE_COMMANDS.some((c) => c.name === command) && command !== \"resume\") return false;\n\trequireAuthorized(ctx.event.source, ctx.cfg);\n\tif (command === \"project\") invalidateGatewayDialogs(ctx.key);\n\tctx.pickerGeneration = gatewayPickerGeneration(ctx.key);\n\tbindConversation(ctx.key, ctx.event.source, { owner: ctx.event.source.userId });\n\tif (command === \"project\") {\n\t\tawait browseProject(ctx, args.trim() || undefined);\n\t\treturn true;\n\t}\n\tif (command === \"sessions\" || command === \"resume\" || command === \"continue\") {\n\t\tawait browseSessions(ctx, args, command === \"continue\");\n\t\treturn true;\n\t}\n\tconst session = await ctx.bridge.getSession(ctx.key);\n\tif (!session) throw new Error(\"Select a project and send a task, or use /continue first.\");\n\tif (ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key)) return true;\n\tconst id = session.sessionManager?.getSessionId();\n\tif (command === \"usage\") {\n\t\tconst stats = session.getSessionStats();\n\t\tconst plans = await (await import(\"../core/usage-service.ts\")).getAllPlanUsageResults(\n\t\t\tsession.model?.provider,\n\t\t\tsession.modelRuntime,\n\t\t);\n\t\tawait ctx.adapter.send(\n\t\t\tctx.event.source.chatId,\n\t\t\t[\n\t\t\t\t`Tokens: ${stats.tokens.total} · cost: $${stats.cost.toFixed(4)}`,\n\t\t\t\t...plans.usages.flatMap((p) =>\n\t\t\t\t\tp.windows.map((w) => `${p.provider} ${w.label}: ${w.usedPercent.toFixed(1)}% used`),\n\t\t\t\t),\n\t\t\t\t...plans.errors,\n\t\t\t].join(\"\\n\"),\n\t\t);\n\t\treturn true;\n\t}\n\tif (command === \"processes\") {\n\t\tif (!id) throw new Error(\"No session identity.\");\n\t\tconst processes = await import(\"../core/process-registry.ts\");\n\t\tconst own = processes.list(id);\n\t\tif (args) {\n\t\t\tconst [action, raw] = args.split(/\\s+/);\n\t\t\tconst pid = Number(raw);\n\t\t\tif (action !== \"stop\" || !own.some((p) => p.pid === pid))\n\t\t\t\tthrow new Error(\"Usage: /processes stop <pid> from this session's process list.\");\n\t\t\tprocesses.kill(pid);\n\t\t\tawait ctx.adapter.send(ctx.event.source.chatId, `Stop requested for process ${pid}.`);\n\t\t} else\n\t\t\tawait ctx.adapter.send(\n\t\t\t\tctx.event.source.chatId,\n\t\t\t\town.length\n\t\t\t\t\t? own\n\t\t\t\t\t\t\t.map((p) => `${p.pid} · ${p.status} · ${p.command}`)\n\t\t\t\t\t\t\t.join(\"\\n\")\n\t\t\t\t\t\t\t.slice(0, ctx.adapter.maxMessageLength)\n\t\t\t\t\t: \"No tracked processes.\",\n\t\t\t);\n\t\treturn true;\n\t}\n\tif (command === \"stopall\") {\n\t\tawait ctx.bridge.abort(ctx.key);\n\t\tconst result = id ? await getSubagentCancellation(id)?.stop() : undefined;\n\t\tconst processes = await import(\"../core/process-registry.ts\");\n\t\tconst count = id ? processes.list(id).filter((p) => p.status !== \"exited\").length : 0;\n\t\tif (id) processes.killAll(id);\n\t\tawait ctx.adapter.send(\n\t\t\tctx.event.source.chatId,\n\t\t\t`Stopped the current turn. Requested stop for ${result?.requested ?? 0} background runs and ${count} tracked processes${result?.failed ? `; ${result.failed} requests failed` : \"\"}. Wait for them to exit before transferring.`,\n\t\t);\n\t\treturn true;\n\t}\n\tif (ctx.bridge.getStatus(ctx.key).busy) throw new Error(\"Wait for the current turn or use /stop first.\");\n\tif (command === \"refresh\") {\n\t\tawait session.modelRuntime.refresh();\n\t\tawait ctx.adapter.send(ctx.event.source.chatId, \"Model catalog refreshed. Use /model to choose.\");\n\t\treturn true;\n\t}\n\tif (command === \"fast\") {\n\t\tif (session.model?.provider !== \"openai-codex\" || !session.settingsManager)\n\t\t\tthrow new Error(\"Fast mode is available only for OpenAI Codex subscriptions.\");\n\t\tconst current = session.settingsManager.getOpenAIFastMode();\n\t\tif (args && ![\"on\", \"off\", \"status\"].includes(args)) throw new Error(\"Usage: /fast on|off|status\");\n\t\tif (args !== \"status\") session.settingsManager.setOpenAIFastMode(args ? args === \"on\" : !current);\n\t\tawait ctx.adapter.send(\n\t\t\tctx.event.source.chatId,\n\t\t\t`Fast mode: ${session.settingsManager.getOpenAIFastMode() ? \"on\" : \"off\"}`,\n\t\t);\n\t\treturn true;\n\t}\n\tif (command === \"skill\") {\n\t\tconst names = session.resourceLoader?.getSkills().skills.map((s) => s.name) ?? [];\n\t\tconst [name, ...task] = args.split(/\\s+/).filter(Boolean);\n\t\tconst chosen = name || (await selectForCommand(ctx, \"Choose a skill\", names));\n\t\tif (!chosen || ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key)) return true;\n\t\tif (!names.includes(chosen)) throw new Error(\"That skill is not loaded for this project.\");\n\t\tctx.event.text = `/skill:${chosen} ${task.join(\" \") || (await inputForCommand(ctx, \"What should this skill do?\")) || \"\"}`;\n\t\treturn ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key);\n\t}\n\tif (command === \"download\") {\n\t\tif (!ctx.adapter.sendFile) throw new Error(\"This platform cannot send files.\");\n\t\tif (!args) throw new Error(\"Usage: /download <project-relative path>\");\n\t\tconst cwd = session.sessionManager?.getCwd();\n\t\tif (!cwd) throw new Error(\"No project selected.\");\n\t\tconst file = resolveWithinRoots(resolve(cwd, args), [cwd]);\n\t\tconst stat = statSync(file);\n\t\tif (!stat.isFile() || stat.size > 8 * 1024 * 1024) throw new Error(\"Choose a file no larger than 8 MB.\");\n\t\tif (\n\t\t\t/(^|[\\\\/])(?:\\.env(?:\\.[^\\\\/]*)?|auth\\.json|gateway\\.json|credentials[^\\\\/]*|id_rsa|id_ed25519)([\\\\/]|$)/i.test(\n\t\t\t\tfile,\n\t\t\t)\n\t\t)\n\t\t\tthrow new Error(\"Credential files cannot be sent through chat.\");\n\t\tconst result = await ctx.adapter.sendFile(ctx.event.source.chatId, file, { threadId: ctx.event.source.threadId });\n\t\tif (!result.success) throw new Error(result.error ?? \"File delivery failed.\");\n\t\treturn true;\n\t}\n\tif (command === \"settings\") {\n\t\tconst choice = await selectForCommand(ctx, \"Session settings\", [\"Model\", \"Thinking\", \"Permissions\"]);\n\t\tif (choice === \"Model\" || choice === \"Thinking\") {\n\t\t\tconst { CHAT_COMMANDS, runChatCommand } = await import(\"./commands.ts\");\n\t\t\tif (ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key)) return true;\n\t\t\tconst cmd = CHAT_COMMANDS.find((c) => c.name === choice.toLowerCase());\n\t\t\tif (cmd)\n\t\t\t\tawait runChatCommand(cmd, {\n\t\t\t\t\t...ctx,\n\t\t\t\t\targs: \"\",\n\t\t\t\t\treply: async (text) => {\n\t\t\t\t\t\tawait ctx.adapter.send(ctx.event.source.chatId, text);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\treturn true;\n\t\t}\n\t\tif (choice !== \"Permissions\") return true;\n\t}\n\tconst requested =\n\t\tcommand === \"plan\"\n\t\t\t? \"read-only\"\n\t\t\t: args || (await selectForCommand(ctx, `Permission mode: ${getPermissionMode(id)}`, [...PERMISSION_MODES]));\n\tif (!requested || ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key)) return true;\n\tconst mode = requested === \"read\" ? \"read-only\" : requested;\n\tif (!PERMISSION_MODES.includes(mode as (typeof PERMISSION_MODES)[number]))\n\t\tthrow new Error(\"Choose yolo, auto, or read-only.\");\n\tsetPermissionMode(mode as (typeof PERMISSION_MODES)[number], id);\n\tsession.sessionManager?.setPermissionMode?.(mode as (typeof PERMISSION_MODES)[number]);\n\tawait ctx.adapter.send(ctx.event.source.chatId, `Permission mode: ${mode}`);\n\tif (command === \"plan\" && args) {\n\t\tctx.event.text = `Create a plan for: ${args}`;\n\t\treturn false;\n\t}\n\treturn true;\n}\n"]}
|
|
@@ -3,11 +3,11 @@ import { basename, dirname, isAbsolute, join, relative, resolve } from "node:pat
|
|
|
3
3
|
import { getPermissionMode, PERMISSION_MODES, setPermissionMode } from "../core/permissions.js";
|
|
4
4
|
import { SessionManager } from "../core/session-manager.js";
|
|
5
5
|
import { getSubagentCancellation } from "../core/subagent-cancellation.js";
|
|
6
|
-
import {
|
|
7
|
-
import { createPicker } from "./buttons.js";
|
|
6
|
+
import { isAuthorized, requireAuthorized } from "./authz.js";
|
|
7
|
+
import { createPicker, GatewayPickerCancelled, gatewayPickerGeneration, } from "./buttons.js";
|
|
8
8
|
import { loadGatewayConfig } from "./config.js";
|
|
9
9
|
import { bindConversation, conversationBinding } from "./conversations.js";
|
|
10
|
-
import { gatewayInput, gatewaySelect } from "./presenter.js";
|
|
10
|
+
import { gatewayInput, gatewaySelect, invalidateGatewayDialogs } from "./presenter.js";
|
|
11
11
|
export const MOBILE_COMMANDS = [
|
|
12
12
|
{ name: "project", description: "Browse folders and choose a project" },
|
|
13
13
|
{ name: "continue", description: "Continue a handoff or the latest TUI session" },
|
|
@@ -59,6 +59,15 @@ export function createProjectFolder(parent, name, roots) {
|
|
|
59
59
|
mkdirSync(join(actual, name));
|
|
60
60
|
return resolveWithinRoots(join(actual, name), roots);
|
|
61
61
|
}
|
|
62
|
+
function commandRequest(ctx) {
|
|
63
|
+
return { generation: ctx.pickerGeneration ?? gatewayPickerGeneration(ctx.key), source: ctx.event.source };
|
|
64
|
+
}
|
|
65
|
+
function selectForCommand(ctx, title, options, opts) {
|
|
66
|
+
return gatewaySelect(ctx.key, title, options, opts, commandRequest(ctx));
|
|
67
|
+
}
|
|
68
|
+
function inputForCommand(ctx, title) {
|
|
69
|
+
return gatewayInput(ctx.key, title, undefined, undefined, commandRequest(ctx));
|
|
70
|
+
}
|
|
62
71
|
async function browseProject(ctx, initialPath) {
|
|
63
72
|
const { key, event, adapter, bridge } = ctx;
|
|
64
73
|
const roots = ctx.cfg.projectRoots ?? [];
|
|
@@ -111,24 +120,46 @@ async function browseProject(ctx, initialPath) {
|
|
|
111
120
|
await createPicker(adapter, event.source, {
|
|
112
121
|
kind: "project",
|
|
113
122
|
sessionKey: key,
|
|
123
|
+
generation: ctx.pickerGeneration,
|
|
114
124
|
invokerId: event.source.userId,
|
|
115
125
|
...initial,
|
|
116
|
-
validate: () =>
|
|
126
|
+
validate: () => isAuthorized(event.source, loadGatewayConfig()),
|
|
117
127
|
resolve: async (item) => {
|
|
118
|
-
|
|
128
|
+
requireAuthorized(event.source);
|
|
119
129
|
if (item.value === "use" && current) {
|
|
120
130
|
const cwd = resolveWithinRoots(current, loadGatewayConfig().projectRoots ?? []);
|
|
121
131
|
if (bridge.getStatus(key).busy)
|
|
122
132
|
throw new Error("Stop the current turn or wait before switching projects.");
|
|
123
|
-
|
|
124
|
-
|
|
133
|
+
let committed = false;
|
|
134
|
+
await bridge.reset(key, {
|
|
135
|
+
validate: () => {
|
|
136
|
+
requireAuthorized(event.source);
|
|
137
|
+
const binding = conversationBinding(key);
|
|
138
|
+
if (!binding ||
|
|
139
|
+
binding.owner !== event.source.userId ||
|
|
140
|
+
binding.source.userId !== event.source.userId ||
|
|
141
|
+
binding.source.platform !== event.source.platform ||
|
|
142
|
+
binding.source.chatId !== event.source.chatId ||
|
|
143
|
+
binding.source.threadId !== event.source.threadId)
|
|
144
|
+
throw new GatewayPickerCancelled("Project requester changed before selection completed.");
|
|
145
|
+
resolveWithinRoots(cwd, loadGatewayConfig().projectRoots ?? []);
|
|
146
|
+
},
|
|
147
|
+
commit: () => {
|
|
148
|
+
bindConversation(key, event.source, { cwd, owner: event.source.userId });
|
|
149
|
+
committed = true;
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
if (!committed)
|
|
153
|
+
throw new Error("The gateway did not commit project replacement. Retry with an updated gateway.");
|
|
125
154
|
return {
|
|
126
155
|
done: true,
|
|
127
156
|
text: `Project selected: ${cwd}\nSend a task to begin. Existing sessions are still available through /sessions.`,
|
|
128
157
|
};
|
|
129
158
|
}
|
|
130
159
|
if (item.value === "new" && current) {
|
|
131
|
-
const name = await
|
|
160
|
+
const name = await inputForCommand(ctx, "New folder name");
|
|
161
|
+
if (ctx.pickerGeneration !== gatewayPickerGeneration(key))
|
|
162
|
+
return { done: true, text: "Selection cancelled." };
|
|
132
163
|
if (name)
|
|
133
164
|
current = createProjectFolder(current, name, loadGatewayConfig().projectRoots ?? []);
|
|
134
165
|
}
|
|
@@ -155,7 +186,7 @@ async function continueSession(ctx, file) {
|
|
|
155
186
|
}
|
|
156
187
|
}
|
|
157
188
|
async function performContinue(ctx, file, signal) {
|
|
158
|
-
|
|
189
|
+
requireAuthorized(ctx.event.source);
|
|
159
190
|
const { requestSessionTransfer, SessionTransferError } = await import("../core/session-handoff.js");
|
|
160
191
|
const { key, bridge } = ctx;
|
|
161
192
|
const current = bridge.peekSession?.(key);
|
|
@@ -171,7 +202,7 @@ async function performContinue(ctx, file, signal) {
|
|
|
171
202
|
catch (error) {
|
|
172
203
|
if (!(error instanceof SessionTransferError) || !["busy", "timeout"].includes(error.code))
|
|
173
204
|
throw error;
|
|
174
|
-
const choice = await
|
|
205
|
+
const choice = await selectForCommand(ctx, `${error instanceof Error ? error.message : "Session is in use"}\nHow should lunR continue?`, ["Wait until idle", "Stop and continue", "Cancel"], { signal });
|
|
175
206
|
if (!choice || choice === "Cancel")
|
|
176
207
|
return;
|
|
177
208
|
if (choice === "Stop and continue")
|
|
@@ -180,7 +211,7 @@ async function performContinue(ctx, file, signal) {
|
|
|
180
211
|
const deadline = Date.now() + 120_000;
|
|
181
212
|
for (;;) {
|
|
182
213
|
signal.throwIfAborted();
|
|
183
|
-
|
|
214
|
+
requireAuthorized(ctx.event.source);
|
|
184
215
|
try {
|
|
185
216
|
await requestSessionTransfer(file, { timeoutMs: 3000, signal });
|
|
186
217
|
break;
|
|
@@ -196,8 +227,11 @@ async function performContinue(ctx, file, signal) {
|
|
|
196
227
|
}
|
|
197
228
|
}
|
|
198
229
|
signal.throwIfAborted();
|
|
199
|
-
|
|
230
|
+
requireAuthorized(ctx.event.source);
|
|
231
|
+
if (ctx.pickerGeneration !== gatewayPickerGeneration(key))
|
|
232
|
+
return;
|
|
200
233
|
await bridge.switchSession(key, file);
|
|
234
|
+
ctx.pickerGeneration = gatewayPickerGeneration(key);
|
|
201
235
|
const session = await bridge.getSession(key);
|
|
202
236
|
const cwd = session?.sessionManager?.getCwd();
|
|
203
237
|
bindConversation(key, ctx.event.source, { cwd, owner: ctx.event.source.userId });
|
|
@@ -206,7 +240,7 @@ async function performContinue(ctx, file, signal) {
|
|
|
206
240
|
const requested = getPermissionMode(id);
|
|
207
241
|
setPermissionMode("read-only", id);
|
|
208
242
|
session?.sessionManager?.setPermissionMode?.("read-only");
|
|
209
|
-
if ((await
|
|
243
|
+
if ((await selectForCommand(ctx, `Continue with ${requested} permissions? Tools can change files and run commands without individual approval.`, ["Keep read-only", `Use ${requested}`])) === `Use ${requested}`) {
|
|
210
244
|
setPermissionMode(requested, id);
|
|
211
245
|
session?.sessionManager?.setPermissionMode?.(requested);
|
|
212
246
|
}
|
|
@@ -268,10 +302,11 @@ async function sessionPicker(ctx, items) {
|
|
|
268
302
|
await createPicker(ctx.adapter, ctx.event.source, {
|
|
269
303
|
kind: "sessions",
|
|
270
304
|
sessionKey: ctx.key,
|
|
305
|
+
generation: ctx.pickerGeneration,
|
|
271
306
|
invokerId: ctx.event.source.userId,
|
|
272
307
|
title: "Choose a session. Use /sessions <search> to filter.",
|
|
273
308
|
items,
|
|
274
|
-
validate: () =>
|
|
309
|
+
validate: () => isAuthorized(ctx.event.source, loadGatewayConfig()),
|
|
275
310
|
resolve: async (item) => {
|
|
276
311
|
await continueSession(ctx, item.value);
|
|
277
312
|
return { done: true, text: "Session selection finished." };
|
|
@@ -281,7 +316,10 @@ async function sessionPicker(ctx, items) {
|
|
|
281
316
|
export async function handleMobileCommand(ctx, command, args) {
|
|
282
317
|
if (!MOBILE_COMMANDS.some((c) => c.name === command) && command !== "resume")
|
|
283
318
|
return false;
|
|
284
|
-
|
|
319
|
+
requireAuthorized(ctx.event.source, ctx.cfg);
|
|
320
|
+
if (command === "project")
|
|
321
|
+
invalidateGatewayDialogs(ctx.key);
|
|
322
|
+
ctx.pickerGeneration = gatewayPickerGeneration(ctx.key);
|
|
285
323
|
bindConversation(ctx.key, ctx.event.source, { owner: ctx.event.source.userId });
|
|
286
324
|
if (command === "project") {
|
|
287
325
|
await browseProject(ctx, args.trim() || undefined);
|
|
@@ -294,6 +332,8 @@ export async function handleMobileCommand(ctx, command, args) {
|
|
|
294
332
|
const session = await ctx.bridge.getSession(ctx.key);
|
|
295
333
|
if (!session)
|
|
296
334
|
throw new Error("Select a project and send a task, or use /continue first.");
|
|
335
|
+
if (ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key))
|
|
336
|
+
return true;
|
|
297
337
|
const id = session.sessionManager?.getSessionId();
|
|
298
338
|
if (command === "usage") {
|
|
299
339
|
const stats = session.getSessionStats();
|
|
@@ -358,13 +398,13 @@ export async function handleMobileCommand(ctx, command, args) {
|
|
|
358
398
|
if (command === "skill") {
|
|
359
399
|
const names = session.resourceLoader?.getSkills().skills.map((s) => s.name) ?? [];
|
|
360
400
|
const [name, ...task] = args.split(/\s+/).filter(Boolean);
|
|
361
|
-
const chosen = name || (await
|
|
362
|
-
if (!chosen)
|
|
401
|
+
const chosen = name || (await selectForCommand(ctx, "Choose a skill", names));
|
|
402
|
+
if (!chosen || ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key))
|
|
363
403
|
return true;
|
|
364
404
|
if (!names.includes(chosen))
|
|
365
405
|
throw new Error("That skill is not loaded for this project.");
|
|
366
|
-
ctx.event.text = `/skill:${chosen} ${task.join(" ") || (await
|
|
367
|
-
return
|
|
406
|
+
ctx.event.text = `/skill:${chosen} ${task.join(" ") || (await inputForCommand(ctx, "What should this skill do?")) || ""}`;
|
|
407
|
+
return ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key);
|
|
368
408
|
}
|
|
369
409
|
if (command === "download") {
|
|
370
410
|
if (!ctx.adapter.sendFile)
|
|
@@ -386,9 +426,11 @@ export async function handleMobileCommand(ctx, command, args) {
|
|
|
386
426
|
return true;
|
|
387
427
|
}
|
|
388
428
|
if (command === "settings") {
|
|
389
|
-
const choice = await
|
|
429
|
+
const choice = await selectForCommand(ctx, "Session settings", ["Model", "Thinking", "Permissions"]);
|
|
390
430
|
if (choice === "Model" || choice === "Thinking") {
|
|
391
431
|
const { CHAT_COMMANDS, runChatCommand } = await import("./commands.js");
|
|
432
|
+
if (ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key))
|
|
433
|
+
return true;
|
|
392
434
|
const cmd = CHAT_COMMANDS.find((c) => c.name === choice.toLowerCase());
|
|
393
435
|
if (cmd)
|
|
394
436
|
await runChatCommand(cmd, {
|
|
@@ -405,8 +447,8 @@ export async function handleMobileCommand(ctx, command, args) {
|
|
|
405
447
|
}
|
|
406
448
|
const requested = command === "plan"
|
|
407
449
|
? "read-only"
|
|
408
|
-
: args || (await
|
|
409
|
-
if (!requested)
|
|
450
|
+
: args || (await selectForCommand(ctx, `Permission mode: ${getPermissionMode(id)}`, [...PERMISSION_MODES]));
|
|
451
|
+
if (!requested || ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key))
|
|
410
452
|
return true;
|
|
411
453
|
const mode = requested === "read" ? "read-only" : requested;
|
|
412
454
|
if (!PERMISSION_MODES.includes(mode))
|