@ashx-j/lunr 0.2.26 → 0.2.28
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 +25 -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/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/accounting.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/accounting.js +5 -2
- package/dist/builtin-extensions/narumiruna-pi-goal/src/accounting.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/runs/background/chain-root-attachment.d.ts +4 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +6 -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 +17 -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 +5 -1
- 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 +78 -42
- 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 +8 -1
- 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 +0 -3
- 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 +134 -28
- 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 +26 -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/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/session-tokens.d.ts +7 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.js +70 -38
- package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +9 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.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/slash/slash-commands.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +13 -62
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +1 -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 +18 -9
- 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 +28 -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/catalog/models.json +1 -1
- package/dist/catalog/providers/google-vertex.json +1 -1
- package/dist/catalog/providers/google.json +1 -1
- package/dist/catalog/publication.json +3 -3
- 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 +46 -21
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +344 -126
- 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/cache-stats.d.ts +1 -1
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js +1 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +2 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +5 -11
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +38 -92
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/computer-use/adapter.d.ts.map +1 -1
- package/dist/core/computer-use/adapter.js +7 -2
- package/dist/core/computer-use/adapter.js.map +1 -1
- package/dist/core/computer-use/image.d.ts.map +1 -1
- package/dist/core/computer-use/image.js +17 -5
- package/dist/core/computer-use/image.js.map +1 -1
- package/dist/core/computer-use/schemas.d.ts.map +1 -1
- package/dist/core/computer-use/schemas.js +23 -6
- package/dist/core/computer-use/schemas.js.map +1 -1
- package/dist/core/computer-use/workflow.d.ts.map +1 -1
- package/dist/core/computer-use/workflow.js +459 -119
- package/dist/core/computer-use/workflow.js.map +1 -1
- package/dist/core/context-breakdown.d.ts +2 -2
- package/dist/core/context-breakdown.d.ts.map +1 -1
- package/dist/core/context-breakdown.js +22 -20
- package/dist/core/context-breakdown.js.map +1 -1
- 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/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 +11 -1
- 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 +3 -3
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +11 -35
- 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 +126 -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 +11 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +111 -33
- 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/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-accounting.d.ts +47 -0
- package/dist/core/usage-accounting.d.ts.map +1 -0
- package/dist/core/usage-accounting.js +205 -0
- package/dist/core/usage-accounting.js.map +1 -0
- 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-history.d.ts +1 -18
- package/dist/core/usage-history.d.ts.map +1 -1
- package/dist/core/usage-history.js +46 -114
- package/dist/core/usage-history.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/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/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 +10 -4
- 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 +65 -56
- package/dist/gateway/cron.js.map +1 -1
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js +2 -1
- 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 +69 -15
- 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 +73 -38
- 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 +17 -2
- 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/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/context-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/context-view.js +2 -2
- package/dist/modes/interactive/components/context-view.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/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -12
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/usage-view.d.ts +5 -0
- package/dist/modes/interactive/components/usage-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/usage-view.js +21 -6
- package/dist/modes/interactive/components/usage-view.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +3 -7
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +151 -131
- 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/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-VFG7WNPX.js → adapter-247RTYLS.js} +4 -5
- package/dist/node-runtime/agent-session-services-RTUGP3XR.js +54 -0
- package/dist/node-runtime/{brave-UWDA3I22.js → brave-2AFFAXNN.js} +1 -1
- package/dist/node-runtime/{builtin-extensions-I2HIFEMY.js → builtin-extensions-N4EUD6SB.js} +8 -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-4QRUZ64T.js +1203 -0
- package/dist/node-runtime/{chunk-FQMM2EZ2.js → chunk-64XTQNLA.js} +29 -7
- package/dist/node-runtime/{chunk-SPVDBUOS.js → chunk-6O3IW3IA.js} +2 -2
- package/dist/node-runtime/{chunk-5ZQXRPMC.js → chunk-6ZZHGUSA.js} +2 -2
- package/dist/node-runtime/{chunk-WIF24I7G.js → chunk-APVM5NEU.js} +149 -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-LJTIVM7I.js → chunk-BMRXLQWQ.js} +464 -160
- package/dist/node-runtime/{chunk-GJ2RDBRL.js → chunk-BYC6RKCN.js} +4 -2
- package/dist/node-runtime/{chunk-T4DA4XE7.js → chunk-DFMPRAQQ.js} +162 -82
- package/dist/node-runtime/{chunk-SN2KSMPQ.js → chunk-DQSCFU7R.js} +13 -7
- package/dist/node-runtime/{chunk-UVWCDQYF.js → chunk-E5DQGNJI.js} +455 -278
- package/dist/node-runtime/{chunk-4SBQAI4T.js → chunk-EBLAZVSA.js} +2058 -73
- 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-IKU6Y7DL.js → chunk-FE3WZI7F.js} +9 -6
- 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-RGQAEOM5.js → chunk-FYIFPFXE.js} +23 -6
- 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-I74LN5JG.js → chunk-HUD2RFJW.js} +2 -2
- package/dist/node-runtime/{chunk-XHIRAZ26.js → chunk-IAZSK7KK.js} +1 -1
- package/dist/node-runtime/{chunk-GYIXXQAO.js → chunk-ICKGAKWX.js} +23 -59
- package/dist/node-runtime/{chunk-X3PGBLQ7.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-L24TPBS4.js → chunk-JEK35V2M.js} +45 -31
- package/dist/node-runtime/{chunk-RDDAZOMU.js → chunk-JL4HYQXK.js} +1 -1
- 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-MPKSOJBT.js → chunk-NHATCSOI.js} +4 -7
- package/dist/node-runtime/{chunk-RMQZU2YU.js → chunk-NNNR3QIY.js} +1 -1
- package/dist/node-runtime/{chunk-2KIPT4HJ.js → chunk-PWHTSQC4.js} +83 -21
- package/dist/node-runtime/{chunk-RWTKOC3B.js → chunk-QBTJG3UM.js} +1 -1
- package/dist/node-runtime/{chunk-RCR3XAQY.js → chunk-QT3F6UEV.js} +233 -169
- package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
- package/dist/node-runtime/{chunk-DVQSHCVP.js → chunk-R4WSB2MQ.js} +5 -5
- package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
- package/dist/node-runtime/{chunk-2CFDTH5B.js → chunk-RLGY2QIL.js} +45 -59
- package/dist/node-runtime/{chunk-CDVHZOOK.js → chunk-RY3FJ6WI.js} +29 -27
- package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
- package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-STMX7W5I.js} +3 -3
- package/dist/node-runtime/chunk-SWWHZ2RI.js +158 -0
- package/dist/node-runtime/{chunk-5Q4A37RB.js → chunk-TCT6PCUR.js} +32 -11
- package/dist/node-runtime/{chunk-P7XBVXGT.js → chunk-U3YVZ6UC.js} +18 -14
- package/dist/node-runtime/{chunk-D5UCKPBQ.js → chunk-UBWW2PID.js} +1 -1
- package/dist/node-runtime/{chunk-E75WFZ33.js → chunk-UNUZICC4.js} +3 -3
- package/dist/node-runtime/{chunk-RAK2QA2B.js → chunk-UYRKUKFE.js} +4 -4
- package/dist/node-runtime/{chunk-LWJXTA6Z.js → chunk-VSUEAI7O.js} +1377 -45
- 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-YWOJIGFY.js → chunk-ZEVFBFNF.js} +95 -142
- package/dist/node-runtime/{chunk-5B6VKFEV.js → chunk-ZIQUS5QO.js} +1 -1
- package/dist/node-runtime/cli-runtime.js +4 -4
- package/dist/node-runtime/{command-FSBU2EVZ.js → command-YRT7I2BW.js} +5 -5
- package/dist/node-runtime/{commands-NAAL7KNT.js → commands-2ETOWWRA.js} +16 -16
- package/dist/node-runtime/{commands-EMBQQVVT.js → commands-D6A6H4TS.js} +11 -18
- 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-4D7UXYU4.js → direct-tool-executor-2QJXVQD2.js} +6 -11
- package/dist/node-runtime/{exa-LL64QZR2.js → exa-6VBZNPGE.js} +1 -1
- package/dist/node-runtime/{export-html-VM4J2MNR.js → export-html-DBQRRMAY.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-DQM333YV.js → gateway-V6K2CDWN.js} +51 -42
- 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-J7TYMOBK.js} +14 -8
- package/dist/node-runtime/index.js +51 -48
- package/dist/node-runtime/{init-P5AUV77I.js → init-JBQJIPYI.js} +3 -6
- package/dist/node-runtime/{install-cli-NN4YAU44.js → install-cli-INGHIVBY.js} +30 -25
- package/dist/node-runtime/interactive-mode-ASZ7APYP.js +75 -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-Y23CCDIJ.js → lunr-computer-use-VDP2QNRQ.js} +9 -9
- package/dist/node-runtime/{lunr-cron-USHC4LXH.js → lunr-cron-WD3YH4CR.js} +93 -80
- package/dist/node-runtime/main.js +43 -41
- package/dist/node-runtime/{mobile-commands-O5LCHL32.js → mobile-commands-ICUXFW5V.js} +12 -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-Q7BL6KZO.js → package-manager-cli-CYM262SI.js} +20 -20
- 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-3PHF4KZ4.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-7IBSSGEW.js → pi-subagents-QPU3OXE4.js} +114 -167
- package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
- package/dist/node-runtime/{print-mode-XQ76CYMT.js → print-mode-2XHN5SUA.js} +3 -3
- package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
- package/dist/node-runtime/{proxy-modes-5FAPSZEZ.js → proxy-modes-VEGC6QG5.js} +8 -15
- package/dist/node-runtime/rpc-entry.js +43 -41
- 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-EFPPD2UW.js → runtime-UGXM4NPQ.js} +2 -2
- package/dist/node-runtime/{runtime-bridges-7WVCLI76.js → runtime-bridges-DNKMNJCF.js} +7 -7
- package/dist/node-runtime/{service-MDQIPQ26.js → service-IHLGFLBT.js} +6 -4
- package/dist/node-runtime/{session-handoff-GWARVEWT.js → session-handoff-LYH53ESV.js} +4 -4
- package/dist/node-runtime/{session-manager-JB5J6XBN.js → session-manager-ZJ3N5Q74.js} +3 -3
- package/dist/node-runtime/{session-selector-GIM4DHQ2.js → session-selector-I73U3EIO.js} +7 -7
- package/dist/node-runtime/{settings-manager-DJDM5AHM.js → settings-manager-P2TKGYTR.js} +5 -5
- package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
- package/dist/node-runtime/{setup-PFBWRNUI.js → setup-OLQ4GXWS.js} +17 -17
- package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
- package/dist/node-runtime/{subagent-executor-LPZ4BHWE.js → subagent-executor-UI6SHG3X.js} +412 -288
- 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-HNMOTNGX.js → update-cli-F3XXJANQ.js} +6 -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-OHPBEFO4.js → workflow-ICDI4N3J.js} +208 -78
- 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.map +1 -1
- package/dist/utils/image-resize-core.js +2 -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/custom-provider.md +3 -3
- package/docs/extensions.md +8 -4
- package/docs/features.md +25 -7
- 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 +24 -24
- package/install-lock/package.json +2 -2
- package/npm-shrinkwrap.json +60 -24
- package/package.json +9 -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-5YXS2PLF.js +0 -51
- package/dist/node-runtime/chunk-2IDTZAG5.js +0 -1415
- package/dist/node-runtime/chunk-3MISGG4S.js +0 -769
- package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
- package/dist/node-runtime/chunk-5B5QN3ZQ.js +0 -356
- package/dist/node-runtime/chunk-7IQGBKBJ.js +0 -2033
- package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
- package/dist/node-runtime/chunk-PTFBPO3C.js +0 -50
- package/dist/node-runtime/interactive-mode-YOHZVMKX.js +0 -74
- package/dist/node-runtime/mcp-auth-flow-QVLFVLEO.js +0 -33
|
@@ -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 { isAuthorized, requireAuthorized } 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: () => 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\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\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 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\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\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: () => 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\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,CAkK7G","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`Parent tokens including auxiliary requests: ${stats.tokens.total} · cost: $${stats.cost.toFixed(4)}`,\n\t\t\t\t...(stats.childUsage?.requests || stats.childUsage?.total\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t`Children: ${stats.childUsage.total} tokens · cost: $${stats.childUsage.cost.toFixed(4)}`,\n\t\t\t\t\t\t\t`Combined: ${stats.combinedUsage?.total ?? stats.tokens.total + stats.childUsage.total} tokens · cost: $${(stats.combinedUsage?.cost ?? stats.cost + stats.childUsage.cost).toFixed(4)}`,\n\t\t\t\t\t\t]\n\t\t\t\t\t: []),\n\t\t\t\t...(stats.combinedUsage?.unknownRequests\n\t\t\t\t\t? [`Usage unavailable for ${stats.combinedUsage.unknownRequests} request(s).`]\n\t\t\t\t\t: []),\n\t\t\t\t...(stats.combinedUsage?.partialRequests\n\t\t\t\t\t? [`Usage incomplete for ${stats.combinedUsage.partialRequests} request(s).`]\n\t\t\t\t\t: []),\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"]}
|
|
@@ -4,10 +4,10 @@ import { getPermissionMode, PERMISSION_MODES, setPermissionMode } from "../core/
|
|
|
4
4
|
import { SessionManager } from "../core/session-manager.js";
|
|
5
5
|
import { getSubagentCancellation } from "../core/subagent-cancellation.js";
|
|
6
6
|
import { isAuthorized, requireAuthorized } from "./authz.js";
|
|
7
|
-
import { createPicker } from "./buttons.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,6 +120,7 @@ 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
126
|
validate: () => isAuthorized(event.source, loadGatewayConfig()),
|
|
@@ -120,15 +130,36 @@ async function browseProject(ctx, initialPath) {
|
|
|
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
|
}
|
|
@@ -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")
|
|
@@ -197,7 +228,10 @@ async function performContinue(ctx, file, signal) {
|
|
|
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,6 +302,7 @@ 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,
|
|
@@ -282,6 +317,9 @@ 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,12 +332,26 @@ 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();
|
|
300
340
|
const plans = await (await import("../core/usage-service.js")).getAllPlanUsageResults(session.model?.provider, session.modelRuntime);
|
|
301
341
|
await ctx.adapter.send(ctx.event.source.chatId, [
|
|
302
|
-
`
|
|
342
|
+
`Parent tokens including auxiliary requests: ${stats.tokens.total} · cost: $${stats.cost.toFixed(4)}`,
|
|
343
|
+
...(stats.childUsage?.requests || stats.childUsage?.total
|
|
344
|
+
? [
|
|
345
|
+
`Children: ${stats.childUsage.total} tokens · cost: $${stats.childUsage.cost.toFixed(4)}`,
|
|
346
|
+
`Combined: ${stats.combinedUsage?.total ?? stats.tokens.total + stats.childUsage.total} tokens · cost: $${(stats.combinedUsage?.cost ?? stats.cost + stats.childUsage.cost).toFixed(4)}`,
|
|
347
|
+
]
|
|
348
|
+
: []),
|
|
349
|
+
...(stats.combinedUsage?.unknownRequests
|
|
350
|
+
? [`Usage unavailable for ${stats.combinedUsage.unknownRequests} request(s).`]
|
|
351
|
+
: []),
|
|
352
|
+
...(stats.combinedUsage?.partialRequests
|
|
353
|
+
? [`Usage incomplete for ${stats.combinedUsage.partialRequests} request(s).`]
|
|
354
|
+
: []),
|
|
303
355
|
...plans.usages.flatMap((p) => p.windows.map((w) => `${p.provider} ${w.label}: ${w.usedPercent.toFixed(1)}% used`)),
|
|
304
356
|
...plans.errors,
|
|
305
357
|
].join("\n"));
|
|
@@ -358,13 +410,13 @@ export async function handleMobileCommand(ctx, command, args) {
|
|
|
358
410
|
if (command === "skill") {
|
|
359
411
|
const names = session.resourceLoader?.getSkills().skills.map((s) => s.name) ?? [];
|
|
360
412
|
const [name, ...task] = args.split(/\s+/).filter(Boolean);
|
|
361
|
-
const chosen = name || (await
|
|
362
|
-
if (!chosen)
|
|
413
|
+
const chosen = name || (await selectForCommand(ctx, "Choose a skill", names));
|
|
414
|
+
if (!chosen || ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key))
|
|
363
415
|
return true;
|
|
364
416
|
if (!names.includes(chosen))
|
|
365
417
|
throw new Error("That skill is not loaded for this project.");
|
|
366
|
-
ctx.event.text = `/skill:${chosen} ${task.join(" ") || (await
|
|
367
|
-
return
|
|
418
|
+
ctx.event.text = `/skill:${chosen} ${task.join(" ") || (await inputForCommand(ctx, "What should this skill do?")) || ""}`;
|
|
419
|
+
return ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key);
|
|
368
420
|
}
|
|
369
421
|
if (command === "download") {
|
|
370
422
|
if (!ctx.adapter.sendFile)
|
|
@@ -386,9 +438,11 @@ export async function handleMobileCommand(ctx, command, args) {
|
|
|
386
438
|
return true;
|
|
387
439
|
}
|
|
388
440
|
if (command === "settings") {
|
|
389
|
-
const choice = await
|
|
441
|
+
const choice = await selectForCommand(ctx, "Session settings", ["Model", "Thinking", "Permissions"]);
|
|
390
442
|
if (choice === "Model" || choice === "Thinking") {
|
|
391
443
|
const { CHAT_COMMANDS, runChatCommand } = await import("./commands.js");
|
|
444
|
+
if (ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key))
|
|
445
|
+
return true;
|
|
392
446
|
const cmd = CHAT_COMMANDS.find((c) => c.name === choice.toLowerCase());
|
|
393
447
|
if (cmd)
|
|
394
448
|
await runChatCommand(cmd, {
|
|
@@ -405,8 +459,8 @@ export async function handleMobileCommand(ctx, command, args) {
|
|
|
405
459
|
}
|
|
406
460
|
const requested = command === "plan"
|
|
407
461
|
? "read-only"
|
|
408
|
-
: args || (await
|
|
409
|
-
if (!requested)
|
|
462
|
+
: args || (await selectForCommand(ctx, `Permission mode: ${getPermissionMode(id)}`, [...PERMISSION_MODES]));
|
|
463
|
+
if (!requested || ctx.pickerGeneration !== gatewayPickerGeneration(ctx.key))
|
|
410
464
|
return true;
|
|
411
465
|
const mode = requested === "read" ? "read-only" : requested;
|
|
412
466
|
if (!PERMISSION_MODES.includes(mode))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobile-commands.js","sourceRoot":"","sources":["../../src/gateway/mobile-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,YAAY,EAA6C,MAAM,cAAc,CAAC;AACvF,OAAO,EAAsB,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI7D,MAAM,CAAC,MAAM,eAAe,GAAG;IAC9B,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,qCAAqC,EAAE;IACvE,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,8CAA8C,EAAE;IACjF,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,uCAAuC,EAAE;IAC1E,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,6CAA6C,EAAE;IAC5E,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,yCAAyC,EAAE;IACxE,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,uDAAuD,EAAE;IAC1F,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,gDAAgD,EAAE;IAClF,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,sCAAsC,EAAE;IACzE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,4CAA4C,EAAE;IAC5E,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,6CAA6C,EAAE;IACjF,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,0BAA0B,EAAE;IAC5D,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,mCAAmC,EAAE;IACnE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,+BAA+B,EAAE;CAC9D,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG;IACjC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,gCAAgC,EAAE;IAC/D,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,4CAA4C,EAAE;IAC3E,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE;IACtD,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,kCAAkC,EAAE;IAClE,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,gCAAgC,EAAE;IACnE,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,6BAA6B,EAAE;IAC3D,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,6BAA6B,EAAE;CAC3D,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,KAAe,EAAU;IACzE,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,IACC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;YACjD,OAAO,CACN,GAAG,KAAK,EAAE;gBACV,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CACvG,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;IAAA,CACD,CAAC;QAEF,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC/D,OAAO,MAAM,CAAC;AAAA,CACd;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,IAAY,EAAE,KAAe,EAAU;IAC1F,IACC,CAAC,IAAI;QACL,IAAI,KAAK,GAAG;QACZ,IAAI,KAAK,IAAI;QACb,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QAClB,uCAAuC,CAAC,IAAI,CAAC,IAAI,CAAC;QAElD,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACjD,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9B,OAAO,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;AAAA,CACrD;AAUD,KAAK,UAAU,aAAa,CAAC,GAAkB,EAAE,WAAoB,EAAiB;IACrF,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAC5C,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;IACzC,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAClG,IAAI,OAAO,GAAuB,WAAW;QAC5C,CAAC,CAAC,kBAAkB,CAAC,WAAW,EAAE,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;QAC7D,CAAC,CAAC,SAAS,CAAC;IACb,MAAM,IAAI,GAAG,GAA2C,EAAE,CAAC;QAC1D,IAAI,CAAC,OAAO;YACX,OAAO;gBACN,KAAK,EAAE,yBAAyB;gBAChC,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,cAAc,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;qBAClF,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;oBACd,IAAI,CAAC;wBACJ,kBAAkB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;wBAC7B,OAAO,IAAI,CAAC;oBACb,CAAC;oBAAC,MAAM,CAAC;wBACR,OAAO,KAAK,CAAC;oBACd,CAAC;gBAAA,CACD,CAAC;qBACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;aACtC,CAAC;QACH,OAAO,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAiB;YAC3B,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE;YAC1C,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE;YACrC,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE;SAC7C,CAAC;QACF,IAAI,CAAC;YACJ,MAAM,EAAE,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;YACvD,IAAI,EAAE,KAAK,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC/G,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBAAE,SAAS;YAC5D,IAAI,CAAC;gBACJ,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;gBACjE,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;oBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACjF,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACX,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAAA,CACjC,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,EAAE,CAAC;IACvB,MAAM,YAAY,CACjB,OAAO,EACP,KAAK,CAAC,MAAM,EACZ;QACC,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,GAAG;QACf,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;QAC9B,GAAG,OAAO;QACV,QAAQ,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC;QAC/D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAgC,EAAE,CAAC;YACtD,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,IAAI,OAAO,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;gBAChF,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI;oBAC7B,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;gBAC7E,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACxB,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;gBACzE,OAAO;oBACN,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,qBAAqB,GAAG,kFAAkF;iBAChH,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,IAAI,OAAO,EAAE,CAAC;gBACrC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;gBACxD,IAAI,IAAI;oBAAE,OAAO,GAAG,mBAAmB,CAAC,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;YAChG,CAAC;;gBAAM,OAAO,GAAG,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACjE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC;QAAA,CAClC;KACD,EACD,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CACnC,CAAC;AAAA,CACF;AAED,MAAM,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;AACrD,MAAM,UAAU,oBAAoB,CAAC,GAAW,EAAQ;IACvD,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;AAAA,CAC5B;AAED,KAAK,UAAU,eAAe,CAAC,GAAkB,EAAE,IAAY,EAAiB;IAC/E,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IAC9G,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACnC,IAAI,CAAC;QACJ,MAAM,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;YAAS,CAAC;QACV,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;AAAA,CACD;AAED,KAAK,UAAU,eAAe,CAAC,GAAkB,EAAE,IAAY,EAAE,MAAmB,EAAiB;IACpG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC;IACpG,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC;QACxD,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,oCAAoC,CAAC,CAAC;QACtF,OAAO;IACR,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACpG,IAAI,CAAC;QACJ,MAAM,sBAAsB,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,CAAC,CAAC,KAAK,YAAY,oBAAoB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,MAAM,KAAK,CAAC;QACvG,MAAM,MAAM,GAAG,MAAM,aAAa,CACjC,GAAG,EACH,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,6BAA6B,EAC5F,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAClD,EAAE,MAAM,EAAE,CACV,CAAC;QACF,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,QAAQ;YAAE,OAAO;QAC3C,IAAI,MAAM,KAAK,mBAAmB;YAAE,MAAM,sBAAsB,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;aAC7G,CAAC;YACL,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;YACtC,SAAS,CAAC;gBACT,MAAM,CAAC,cAAc,EAAE,CAAC;gBACxB,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACpC,IAAI,CAAC;oBACJ,MAAM,sBAAsB,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;oBAChE,MAAM;gBACP,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACrB,IACC,CAAC,CAAC,UAAU,YAAY,oBAAoB,CAAC;wBAC7C,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC;wBAC9C,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ;wBAEtB,MAAM,UAAU,CAAC;gBACnB,CAAC;gBACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YAC1D,CAAC;QACF,CAAC;IACF,CAAC;IACD,MAAM,CAAC,cAAc,EAAE,CAAC;IACxB,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC;IAC9C,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACjF,MAAM,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;IACnD,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACxC,iBAAiB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACnC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC,WAAW,CAAC,CAAC;QAC1D,IACC,CAAC,MAAM,aAAa,CACnB,GAAG,EACH,iBAAiB,SAAS,oFAAoF,EAC9G,CAAC,gBAAgB,EAAE,OAAO,SAAS,EAAE,CAAC,CACtC,CAAC,KAAK,OAAO,SAAS,EAAE,EACxB,CAAC;YACF,iBAAiB,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YACjC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC,SAAS,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;IACD,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CACrB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EACvB,cAAc,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,cAAc,GAAG,+BAA+B,EACzH,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CACvC,CAAC;AAAA,CACF;AAED,KAAK,UAAU,cAAc,CAAC,GAAkB,EAAE,IAAY,EAAE,KAAc,EAAiB;IAC9F,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC;IAC3D,IAAI,KAAK,EAAE,CAAC;QACX,MAAM,UAAU,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;QACnD,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAC1C,IAAI,CAAC,MAAM;gBACV,MAAM,IAAI,KAAK,CAAC,uFAAuF,CAAC,CAAC;YAC1G,MAAM,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;YAC/C,OAAO;QACR,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YACtD,OAAO;QACR,CAAC;QACD,MAAM,aAAa,CAClB,GAAG,EACH,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,GAAG,OAAM,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CACjG,CAAC;QACF,OAAO;IACR,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,0BAA0B,EAAE,EAAE,CAAC;QACzD,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAC9B,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YACnC,IAAI,MAAM;gBACT,QAAQ,CAAC,IAAI,CAAC;oBACb,EAAE,EAAE,MAAM,CAAC,EAAE;oBACb,IAAI,EAAE,IAAI;oBACV,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;oBACrB,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE;oBAC9B,OAAO,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;oBACnC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK;oBAC9B,YAAY,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,MAAM;oBACzC,YAAY,EAAE,EAAE;oBAChB,eAAe,EAAE,EAAE;iBACnB,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,QAAQ;SACpB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;SAC3D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SACzF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACZ,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,OAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAM,CAAC,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAAE;QAC/H,KAAK,EAAE,CAAC,CAAC,IAAI;KACb,CAAC,CAAC,CAAC;IACL,MAAM,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AAAA,CAChC;AAED,KAAK,UAAU,aAAa,CAAC,GAAkB,EAAE,KAAmB,EAAiB;IACpF,MAAM,YAAY,CACjB,GAAG,CAAC,OAAO,EACX,GAAG,CAAC,KAAK,CAAC,MAAM,EAChB;QACC,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,GAAG,CAAC,GAAG;QACnB,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;QAClC,KAAK,EAAE,qDAAqD;QAC5D,KAAK;QACL,QAAQ,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC;QACnE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;YACxB,MAAM,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACvC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC;QAAA,CAC3D;KACD,EACD,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CACvC,CAAC;AAAA,CACF;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAkB,EAAE,OAAe,EAAE,IAAY,EAAoB;IAC9G,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3F,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7C,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAChF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC9E,MAAM,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,KAAK,UAAU,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrD,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC3F,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,YAAY,EAAE,CAAC;IAClD,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC,sBAAsB,CACpF,OAAO,CAAC,KAAK,EAAE,QAAQ,EACvB,OAAO,CAAC,YAAY,CACpB,CAAC;QACF,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CACrB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EACvB;YACC,WAAW,KAAK,CAAC,MAAM,CAAC,KAAK,cAAa,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YACjE,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAC7B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CACnF;YACD,GAAG,KAAK,CAAC,MAAM;SACf,CAAC,IAAI,CAAC,IAAI,CAAC,CACZ,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;QAC7B,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,IAAI,EAAE,CAAC;YACV,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACxC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,MAAM,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;gBACvD,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;YACnF,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpB,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,8BAA8B,GAAG,GAAG,CAAC,CAAC;QACvF,CAAC;;YACA,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CACrB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EACvB,GAAG,CAAC,MAAM;gBACT,CAAC,CAAC,GAAG;qBACF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAM,CAAC,CAAC,MAAM,OAAM,CAAC,CAAC,OAAO,EAAE,CAAC;qBACnD,IAAI,CAAC,IAAI,CAAC;qBACV,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC;gBACzC,CAAC,CAAC,uBAAuB,CAC1B,CAAC;QACH,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,uBAAuB,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1E,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC;QAC9D,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,IAAI,EAAE;YAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC9B,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CACrB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EACvB,gDAAgD,MAAM,EAAE,SAAS,IAAI,CAAC,wBAAwB,KAAK,qBAAqB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,kBAAkB,CAAC,CAAC,CAAC,EAAE,8CAA8C,CAChO,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACzG,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,gDAAgD,CAAC,CAAC;QAClG,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACxB,IAAI,OAAO,CAAC,KAAK,EAAE,QAAQ,KAAK,cAAc,IAAI,CAAC,OAAO,CAAC,eAAe;YACzE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC;QAC5D,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACnG,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,CAAC,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAClG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CACrB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EACvB,cAAc,OAAO,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAC1E,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,OAAO,CAAC,cAAc,EAAE,SAAS,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAClF,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC3F,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,UAAU,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,4BAA4B,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC3H,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAC/E,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QACvE,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;QAC7C,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACzG,IACC,0GAA0G,CAAC,IAAI,CAC9G,IAAI,CACJ;YAED,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClH,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,uBAAuB,CAAC,CAAC;QAC9E,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;QACtG,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YACjD,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;YACxE,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YACvE,IAAI,GAAG;gBACN,MAAM,cAAc,CAAC,GAAG,EAAE;oBACzB,GAAG,GAAG;oBACN,IAAI,EAAE,EAAE;oBACR,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;wBACtB,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;oBAAA,CACtD;iBACD,CAAC,CAAC;YACJ,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,MAAM,KAAK,aAAa;YAAE,OAAO,IAAI,CAAC;IAC3C,CAAC;IACD,MAAM,SAAS,GACd,OAAO,KAAK,MAAM;QACjB,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAoB,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAC/G,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,IAAI,GAAG,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5D,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAyC,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACrD,iBAAiB,CAAC,IAAyC,EAAE,EAAE,CAAC,CAAC;IACjE,OAAO,CAAC,cAAc,EAAE,iBAAiB,EAAE,CAAC,IAAyC,CAAC,CAAC;IACvF,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC;IAC5E,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC;QAChC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,sBAAsB,IAAI,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACZ","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 { isAuthorized, requireAuthorized } 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: () => 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\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\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 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\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\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: () => 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\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.js","sourceRoot":"","sources":["../../src/gateway/mobile-commands.ts"],"names":[],"mappings":"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","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`Parent tokens including auxiliary requests: ${stats.tokens.total} · cost: $${stats.cost.toFixed(4)}`,\n\t\t\t\t...(stats.childUsage?.requests || stats.childUsage?.total\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t`Children: ${stats.childUsage.total} tokens · cost: $${stats.childUsage.cost.toFixed(4)}`,\n\t\t\t\t\t\t\t`Combined: ${stats.combinedUsage?.total ?? stats.tokens.total + stats.childUsage.total} tokens · cost: $${(stats.combinedUsage?.cost ?? stats.cost + stats.childUsage.cost).toFixed(4)}`,\n\t\t\t\t\t\t]\n\t\t\t\t\t: []),\n\t\t\t\t...(stats.combinedUsage?.unknownRequests\n\t\t\t\t\t? [`Usage unavailable for ${stats.combinedUsage.unknownRequests} request(s).`]\n\t\t\t\t\t: []),\n\t\t\t\t...(stats.combinedUsage?.partialRequests\n\t\t\t\t\t? [`Usage incomplete for ${stats.combinedUsage.partialRequests} request(s).`]\n\t\t\t\t\t: []),\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"]}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import type { ExtensionUIContext, ExtensionUIDialogOptions } from "../core/extensions/types.ts";
|
|
2
2
|
import { type GatewayConfig } from "./config.ts";
|
|
3
|
+
import { type PairingStore } from "./pairing.ts";
|
|
3
4
|
import type { MessageEvent, PlatformAdapter } from "./types.ts";
|
|
5
|
+
/** Retire session UI independently of cancelling its current dialogs. Roll back a failed replacement. */
|
|
6
|
+
export declare function invalidateGatewaySession(key: string): () => void;
|
|
4
7
|
export declare function rememberGatewayRole(key: string, source: MessageEvent["source"]): void;
|
|
8
|
+
/** Fresh delivery authorization shared by previews, final edits and durable retries. */
|
|
9
|
+
export declare function canDeliverGatewayText(key: string, source: MessageEvent["source"], fallbackConfig?: GatewayConfig, pairing?: PairingStore): boolean;
|
|
5
10
|
export declare function gatewayDestination(key: string): {
|
|
6
11
|
adapter: PlatformAdapter;
|
|
7
12
|
source: MessageEvent["source"];
|
|
@@ -21,7 +26,12 @@ export declare function queueGatewayText(key: string, source: MessageEvent["sour
|
|
|
21
26
|
export declare function flushGatewayOutbox(): Promise<void>;
|
|
22
27
|
export declare function invalidateGatewayDialogs(key: string): void;
|
|
23
28
|
export declare function acceptGatewayInput(key: string, event: MessageEvent): boolean;
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
interface GatewayDialogRequest {
|
|
30
|
+
generation: number;
|
|
31
|
+
source: MessageEvent["source"];
|
|
32
|
+
}
|
|
33
|
+
export declare function gatewaySelect(key: string, title: string, options: string[], opts?: ExtensionUIDialogOptions, request?: GatewayDialogRequest): Promise<string | undefined>;
|
|
34
|
+
export declare function gatewayInput(key: string, title: string, placeholder?: string, opts?: ExtensionUIDialogOptions, request?: GatewayDialogRequest): Promise<string | undefined>;
|
|
26
35
|
export declare function createGatewayUI(key: string): ExtensionUIContext;
|
|
36
|
+
export {};
|
|
27
37
|
//# sourceMappingURL=presenter.d.ts.map
|