lsd-pi 1.2.4 → 1.3.6
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/README.md +22 -16
- package/dist/app-paths.d.ts +4 -0
- package/dist/app-paths.js +4 -0
- package/dist/bedrock-auth.d.ts +4 -0
- package/dist/bedrock-auth.js +4 -0
- package/dist/bundled-extension-paths.d.ts +4 -0
- package/dist/bundled-extension-paths.js +4 -0
- package/dist/cli-theme.d.ts +2 -2
- package/dist/cli-theme.js +13 -14
- package/dist/cli.js +43 -3
- package/dist/codex-rotate-settings.d.ts +4 -0
- package/dist/codex-rotate-settings.js +4 -0
- package/dist/help-text.d.ts +4 -0
- package/dist/help-text.js +4 -0
- package/dist/lsd-brand.d.ts +4 -0
- package/dist/lsd-brand.js +4 -0
- package/dist/onboarding-llm.d.ts +5 -0
- package/dist/onboarding-llm.js +5 -0
- package/dist/project-sessions.d.ts +4 -0
- package/dist/project-sessions.js +4 -0
- package/dist/resources/agents/generic.md +1 -0
- package/dist/resources/agents/scout.md +8 -1
- package/dist/resources/agents/worker.md +1 -0
- package/dist/resources/extensions/ask-user-questions.js +70 -0
- package/dist/resources/extensions/bg-shell/bg-shell-tool.js +6 -16
- package/dist/resources/extensions/browser-tools/tools/codegen.js +5 -5
- package/dist/resources/extensions/browser-tools/tools/navigation.js +107 -178
- package/dist/resources/extensions/browser-tools/tools/network-mock.js +112 -167
- package/dist/resources/extensions/browser-tools/tools/pages.js +182 -234
- package/dist/resources/extensions/browser-tools/tools/refs.js +202 -461
- package/dist/resources/extensions/browser-tools/tools/session.js +176 -323
- package/dist/resources/extensions/browser-tools/tools/state-persistence.js +91 -154
- package/dist/resources/extensions/browser-tools/utils.js +1 -1
- package/dist/resources/extensions/mac-tools/index.js +19 -34
- package/dist/resources/extensions/memory/index.js +20 -2
- package/dist/resources/extensions/shared/interview-ui.js +103 -20
- package/dist/resources/extensions/slash-commands/extension-manifest.json +2 -2
- package/dist/resources/extensions/slash-commands/fast.js +73 -0
- package/dist/resources/extensions/slash-commands/index.js +2 -0
- package/dist/resources/extensions/slash-commands/plan.js +54 -28
- package/dist/resources/extensions/slash-commands/tools.js +40 -4
- package/dist/resources/extensions/subagent/agent-switcher-component.js +208 -0
- package/dist/resources/extensions/subagent/agent-switcher-model.js +107 -0
- package/dist/resources/extensions/subagent/background-job-manager.js +24 -6
- package/dist/resources/extensions/subagent/background-runner.js +4 -0
- package/dist/resources/extensions/subagent/in-process-runner.js +387 -0
- package/dist/resources/extensions/subagent/index.js +715 -370
- package/dist/resources/extensions/subagent/launch-helpers.js +19 -5
- package/dist/resources/extensions/subagent/legacy-runner.js +503 -0
- package/dist/resources/extensions/voice/index.js +96 -36
- package/dist/resources/extensions/voice/push-to-talk.js +26 -0
- package/dist/shared-paths.d.ts +4 -0
- package/dist/shared-paths.js +4 -0
- package/dist/shared-preferences.d.ts +4 -0
- package/dist/shared-preferences.js +4 -0
- package/dist/startup-model-validation.d.ts +1 -1
- package/dist/startup-timings.d.ts +4 -0
- package/dist/startup-timings.js +4 -0
- package/dist/update-check.d.ts +4 -0
- package/dist/update-check.js +4 -0
- package/dist/update-cmd.d.ts +4 -0
- package/dist/update-cmd.js +4 -0
- package/dist/welcome-screen.js +4 -4
- package/dist/wizard.d.ts +4 -0
- package/dist/wizard.js +4 -0
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +28 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +105 -5
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +13 -2
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/src/agent.ts +142 -6
- package/packages/pi-agent-core/src/types.ts +12 -3
- package/packages/pi-ai/dist/adaptive/classifier.d.ts +29 -0
- package/packages/pi-ai/dist/adaptive/classifier.d.ts.map +1 -0
- package/packages/pi-ai/dist/adaptive/classifier.js +72 -0
- package/packages/pi-ai/dist/adaptive/classifier.js.map +1 -0
- package/packages/pi-ai/dist/adaptive/classifier.test.d.ts +2 -0
- package/packages/pi-ai/dist/adaptive/classifier.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/adaptive/classifier.test.js +32 -0
- package/packages/pi-ai/dist/adaptive/classifier.test.js.map +1 -0
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +0 -2
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +0 -2
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.js +0 -4
- package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-vertex.js +0 -5
- package/packages/pi-ai/dist/providers/google-vertex.js.map +1 -1
- package/packages/pi-ai/dist/providers/google.js +0 -5
- package/packages/pi-ai/dist/providers/google.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +35 -2
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +32 -6
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +127 -16
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +0 -1
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts +9 -2
- package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js +67 -0
- package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-responses.js +21 -3
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-shared.d.ts +0 -1
- package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-shared.js +0 -4
- package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +2 -1
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +6 -2
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/src/adaptive/classifier.test.ts +38 -0
- package/packages/pi-ai/src/adaptive/classifier.ts +107 -0
- package/packages/pi-ai/src/index.ts +1 -0
- package/packages/pi-ai/src/providers/amazon-bedrock.ts +0 -2
- package/packages/pi-ai/src/providers/anthropic-shared.ts +0 -2
- package/packages/pi-ai/src/providers/azure-openai-responses.ts +1 -1
- package/packages/pi-ai/src/providers/google-gemini-cli.ts +0 -4
- package/packages/pi-ai/src/providers/google-vertex.ts +0 -5
- package/packages/pi-ai/src/providers/google.ts +0 -5
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +143 -20
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +48 -7
- package/packages/pi-ai/src/providers/openai-completions.ts +1 -2
- package/packages/pi-ai/src/providers/openai-responses.fast-mode.test.ts +73 -0
- package/packages/pi-ai/src/providers/openai-responses.ts +27 -4
- package/packages/pi-ai/src/providers/openai-shared.ts +0 -3
- package/packages/pi-ai/src/providers/simple-options.ts +2 -1
- package/packages/pi-ai/src/types.ts +6 -2
- package/packages/pi-coding-agent/dist/cli/args.js +2 -2
- package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +7 -2
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +53 -20
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/keybindings.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/keybindings.js +2 -0
- package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp.md +3 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +36 -8
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js +37 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +4 -0
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +18 -7
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js +35 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js +32 -2
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +4 -1
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +2 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +12 -3
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tool-priority.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.js +18 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.test.js +27 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/grep.js +1 -1
- package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.js +2 -0
- package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/pty.d.ts +10 -1
- package/packages/pi-coding-agent/dist/core/tools/pty.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/pty.js +29 -3
- package/packages/pi-coding-agent/dist/core/tools/pty.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js +26 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts +45 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js +314 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js +122 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/embedded-terminal.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/embedded-terminal.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +19 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +11 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +49 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/thinking-selector.js +1 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +18 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js +49 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js +197 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +106 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +88 -2
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +41 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +10 -6
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/print-mode.js +6 -0
- package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +20 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/path-display.test.js +15 -0
- package/packages/pi-coding-agent/dist/tests/path-display.test.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/cli/args.ts +2 -2
- package/packages/pi-coding-agent/src/core/agent-session.ts +58 -21
- package/packages/pi-coding-agent/src/core/keybindings.ts +4 -1
- package/packages/pi-coding-agent/src/core/lsp/lsp.md +3 -1
- package/packages/pi-coding-agent/src/core/sdk.test.ts +45 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +39 -8
- package/packages/pi-coding-agent/src/core/session-manager.ts +12 -0
- package/packages/pi-coding-agent/src/core/settings-manager.fast-mode.test.ts +46 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +50 -9
- package/packages/pi-coding-agent/src/core/skills.ts +4 -1
- package/packages/pi-coding-agent/src/core/slash-commands.ts +2 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +14 -3
- package/packages/pi-coding-agent/src/core/tool-priority.test.ts +30 -0
- package/packages/pi-coding-agent/src/core/tool-priority.ts +17 -0
- package/packages/pi-coding-agent/src/core/tools/grep.ts +1 -1
- package/packages/pi-coding-agent/src/core/tools/index.ts +3 -0
- package/packages/pi-coding-agent/src/core/tools/pty.ts +45 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-summary-line.test.ts +31 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.test.ts +172 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.ts +402 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/embedded-terminal.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +18 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +63 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/thinking-selector.ts +1 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1154 -1136
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-summary-line.ts +64 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.ts +228 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +494 -389
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +7 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +3 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +103 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +60 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +11 -7
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
- package/packages/pi-coding-agent/src/modes/print-mode.ts +6 -0
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +29 -0
- package/packages/pi-coding-agent/src/tests/path-display.test.ts +17 -0
- package/packages/pi-tui/dist/components/loader.d.ts +5 -2
- package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/loader.js +33 -3
- package/packages/pi-tui/dist/components/loader.js.map +1 -1
- package/packages/pi-tui/src/components/loader.ts +31 -3
- package/packages/rpc-client/src/index.ts +1 -1
- package/packages/rpc-client/src/rpc-client.ts +29 -0
- package/packages/rpc-client/src/rpc-types.ts +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts +2 -2
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +10 -6
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/agents/generic.md +1 -0
- package/src/resources/agents/scout.md +8 -1
- package/src/resources/agents/worker.md +1 -0
- package/src/resources/extensions/ask-user-questions.ts +88 -0
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +6 -16
- package/src/resources/extensions/browser-tools/tools/codegen.ts +5 -5
- package/src/resources/extensions/browser-tools/tools/navigation.ts +118 -196
- package/src/resources/extensions/browser-tools/tools/network-mock.ts +114 -205
- package/src/resources/extensions/browser-tools/tools/pages.ts +183 -237
- package/src/resources/extensions/browser-tools/tools/refs.ts +193 -507
- package/src/resources/extensions/browser-tools/tools/session.ts +182 -321
- package/src/resources/extensions/browser-tools/tools/state-persistence.ts +94 -172
- package/src/resources/extensions/browser-tools/utils.ts +1 -1
- package/src/resources/extensions/mac-tools/index.ts +19 -34
- package/src/resources/extensions/memory/index.ts +22 -2
- package/src/resources/extensions/shared/interview-ui.ts +108 -15
- package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +61 -0
- package/src/resources/extensions/shared/tests/custom-ui-fallbacks.test.ts +46 -0
- package/src/resources/extensions/slash-commands/extension-manifest.json +2 -2
- package/src/resources/extensions/slash-commands/fast.ts +89 -0
- package/src/resources/extensions/slash-commands/index.ts +2 -0
- package/src/resources/extensions/slash-commands/plan.ts +59 -30
- package/src/resources/extensions/slash-commands/tools.ts +43 -4
- package/src/resources/extensions/subagent/agent-switcher-component.ts +228 -0
- package/src/resources/extensions/subagent/agent-switcher-model.ts +160 -0
- package/src/resources/extensions/subagent/background-job-manager.ts +57 -6
- package/src/resources/extensions/subagent/background-runner.ts +8 -0
- package/src/resources/extensions/subagent/background-types.ts +4 -0
- package/src/resources/extensions/subagent/in-process-runner.ts +534 -0
- package/src/resources/extensions/subagent/index.ts +998 -493
- package/src/resources/extensions/subagent/launch-helpers.ts +15 -4
- package/src/resources/extensions/subagent/legacy-runner.ts +607 -0
- package/src/resources/extensions/voice/index.ts +308 -238
- package/src/resources/extensions/voice/push-to-talk.ts +42 -0
- package/src/resources/extensions/voice/tests/push-to-talk.test.ts +109 -0
|
@@ -29,9 +29,23 @@ import { makeUI, INDENT } from "./ui.js";
|
|
|
29
29
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
30
30
|
const OTHER_OPTION_LABEL = "None of the above";
|
|
31
31
|
const OTHER_OPTION_DESCRIPTION = "Select to type your own answer.";
|
|
32
|
+
function matchesShowWhen(question, answers) {
|
|
33
|
+
if (!question.showWhen)
|
|
34
|
+
return true;
|
|
35
|
+
const controlling = answers[question.showWhen.questionId];
|
|
36
|
+
if (!controlling)
|
|
37
|
+
return false;
|
|
38
|
+
const selected = Array.isArray(controlling.selected)
|
|
39
|
+
? controlling.selected
|
|
40
|
+
: [controlling.selected];
|
|
41
|
+
return selected.some((value) => question.showWhen?.selectedAnyOf.includes(value));
|
|
42
|
+
}
|
|
32
43
|
async function runSequentialInterviewFallback(questions, ctx) {
|
|
33
44
|
const answers = {};
|
|
34
45
|
for (const q of questions) {
|
|
46
|
+
if (!matchesShowWhen(q, answers)) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
35
49
|
const options = q.options.map((o) => o.label);
|
|
36
50
|
if (!q.allowMultiple) {
|
|
37
51
|
options.push(OTHER_OPTION_LABEL);
|
|
@@ -147,7 +161,6 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
147
161
|
notes: "",
|
|
148
162
|
notesVisible: false,
|
|
149
163
|
}));
|
|
150
|
-
const isMultiQuestion = questions.length > 1;
|
|
151
164
|
let currentIdx = 0;
|
|
152
165
|
let focusNotes = false;
|
|
153
166
|
let showingReview = false;
|
|
@@ -181,13 +194,65 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
181
194
|
function loadStateToEditor() {
|
|
182
195
|
getEditor().setText(states[currentIdx].notes);
|
|
183
196
|
}
|
|
197
|
+
function selectedLabelsForIndex(idx) {
|
|
198
|
+
if (isMultiSelect(idx)) {
|
|
199
|
+
return Array.from(states[idx].checkedIndices).sort((a, b) => a - b).map((optionIdx) => questions[idx].options[optionIdx]?.label).filter((v) => !!v);
|
|
200
|
+
}
|
|
201
|
+
const committed = states[idx].committedIndex;
|
|
202
|
+
if (committed === null)
|
|
203
|
+
return [];
|
|
204
|
+
if (committed < questions[idx].options.length)
|
|
205
|
+
return [questions[idx].options[committed]?.label].filter((v) => !!v);
|
|
206
|
+
if (committed === noneOrDoneIdx(idx))
|
|
207
|
+
return [OTHER_OPTION_LABEL];
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
function visibleQuestionIndices() {
|
|
211
|
+
const visible = [];
|
|
212
|
+
for (let i = 0; i < questions.length; i++) {
|
|
213
|
+
const q = questions[i];
|
|
214
|
+
if (!q.showWhen) {
|
|
215
|
+
visible.push(i);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const controllingIdx = questions.findIndex((candidate) => candidate.id === q.showWhen?.questionId);
|
|
219
|
+
if (controllingIdx < 0 || !visible.includes(controllingIdx))
|
|
220
|
+
continue;
|
|
221
|
+
const selected = selectedLabelsForIndex(controllingIdx);
|
|
222
|
+
if (selected.some((label) => q.showWhen?.selectedAnyOf.includes(label))) {
|
|
223
|
+
visible.push(i);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return visible;
|
|
227
|
+
}
|
|
184
228
|
function isQuestionAnswered(idx) {
|
|
185
229
|
if (isMultiSelect(idx))
|
|
186
230
|
return states[idx].checkedIndices.size > 0;
|
|
187
231
|
return states[idx].committedIndex !== null;
|
|
188
232
|
}
|
|
189
233
|
function allAnswered() {
|
|
190
|
-
|
|
234
|
+
const visible = visibleQuestionIndices();
|
|
235
|
+
return visible.length > 0 && visible.every((i) => isQuestionAnswered(i));
|
|
236
|
+
}
|
|
237
|
+
function clearQuestionState(idx) {
|
|
238
|
+
states[idx].cursorIndex = 0;
|
|
239
|
+
states[idx].committedIndex = null;
|
|
240
|
+
states[idx].checkedIndices.clear();
|
|
241
|
+
states[idx].notes = "";
|
|
242
|
+
states[idx].notesVisible = false;
|
|
243
|
+
}
|
|
244
|
+
function reconcileVisibility() {
|
|
245
|
+
const visible = new Set(visibleQuestionIndices());
|
|
246
|
+
for (let i = 0; i < questions.length; i++) {
|
|
247
|
+
if (!visible.has(i))
|
|
248
|
+
clearQuestionState(i);
|
|
249
|
+
}
|
|
250
|
+
if (!visible.has(currentIdx)) {
|
|
251
|
+
const fallback = visibleQuestionIndices()[0] ?? 0;
|
|
252
|
+
currentIdx = fallback;
|
|
253
|
+
loadStateToEditor();
|
|
254
|
+
focusNotes = false;
|
|
255
|
+
}
|
|
191
256
|
}
|
|
192
257
|
function switchQuestion(newIdx) {
|
|
193
258
|
if (newIdx === currentIdx)
|
|
@@ -200,7 +265,10 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
200
265
|
}
|
|
201
266
|
function buildResult() {
|
|
202
267
|
const answers = {};
|
|
268
|
+
const visible = new Set(visibleQuestionIndices());
|
|
203
269
|
for (let i = 0; i < questions.length; i++) {
|
|
270
|
+
if (!visible.has(i))
|
|
271
|
+
continue;
|
|
204
272
|
const q = questions[i];
|
|
205
273
|
const st = states[i];
|
|
206
274
|
const notes = st.notes.trim();
|
|
@@ -234,6 +302,7 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
234
302
|
if (!isMultiSelect(currentIdx)) {
|
|
235
303
|
states[currentIdx].committedIndex = states[currentIdx].cursorIndex;
|
|
236
304
|
}
|
|
305
|
+
reconcileVisibility();
|
|
237
306
|
// Auto-open the notes field when "None of the above" is selected
|
|
238
307
|
// so the user can immediately provide a free-text explanation
|
|
239
308
|
// instead of being trapped in a re-asking loop (bug #2715).
|
|
@@ -245,10 +314,13 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
245
314
|
refresh();
|
|
246
315
|
return;
|
|
247
316
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
317
|
+
const visible = visibleQuestionIndices();
|
|
318
|
+
const currentVisiblePos = visible.indexOf(currentIdx);
|
|
319
|
+
const isMultiQuestion = visible.length > 1;
|
|
320
|
+
if (isMultiQuestion && currentVisiblePos >= 0 && currentVisiblePos < visible.length - 1) {
|
|
321
|
+
let next = visible[currentVisiblePos + 1] ?? visible[0] ?? currentIdx;
|
|
322
|
+
for (let i = 0; i < visible.length; i++) {
|
|
323
|
+
const candidate = visible[(currentVisiblePos + 1 + i) % visible.length] ?? currentIdx;
|
|
252
324
|
if (!isQuestionAnswered(candidate)) {
|
|
253
325
|
next = candidate;
|
|
254
326
|
break;
|
|
@@ -306,7 +378,8 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
306
378
|
if (showingReview) {
|
|
307
379
|
if (matchesKey(data, Key.escape) || matchesKey(data, Key.left)) {
|
|
308
380
|
showingReview = false;
|
|
309
|
-
|
|
381
|
+
const visible = visibleQuestionIndices();
|
|
382
|
+
switchQuestion(visible[visible.length - 1] ?? 0);
|
|
310
383
|
return;
|
|
311
384
|
}
|
|
312
385
|
if (matchesKey(data, Key.enter) || matchesKey(data, Key.right) || matchesKey(data, Key.space)) {
|
|
@@ -355,14 +428,19 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
355
428
|
return;
|
|
356
429
|
}
|
|
357
430
|
// ── Multi-question navigation ────────────────────────────────
|
|
431
|
+
const visible = visibleQuestionIndices();
|
|
432
|
+
const isMultiQuestion = visible.length > 1;
|
|
358
433
|
if (isMultiQuestion) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
434
|
+
const visiblePos = visible.indexOf(currentIdx);
|
|
435
|
+
if (visiblePos >= 0) {
|
|
436
|
+
if (matchesKey(data, Key.left)) {
|
|
437
|
+
switchQuestion(visible[(visiblePos - 1 + visible.length) % visible.length] ?? currentIdx);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (matchesKey(data, Key.right)) {
|
|
441
|
+
switchQuestion(visible[(visiblePos + 1) % visible.length] ?? currentIdx);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
366
444
|
}
|
|
367
445
|
}
|
|
368
446
|
// ── Cursor navigation ────────────────────────────────────────
|
|
@@ -435,7 +513,8 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
435
513
|
const push = (...rows) => { for (const r of rows)
|
|
436
514
|
lines.push(...r); };
|
|
437
515
|
push(ui.bar(), ui.blank(), ui.header(` ${opts.reviewHeadline ?? "Review your answers"}`), ui.blank());
|
|
438
|
-
|
|
516
|
+
const visible = visibleQuestionIndices();
|
|
517
|
+
for (const i of visible) {
|
|
439
518
|
const q = questions[i];
|
|
440
519
|
const st = states[i];
|
|
441
520
|
push(ui.subtitle(` ${q.question}`));
|
|
@@ -501,19 +580,23 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
501
580
|
const lines = [];
|
|
502
581
|
const push = (...rows) => { for (const r of rows)
|
|
503
582
|
lines.push(...r); };
|
|
583
|
+
reconcileVisibility();
|
|
584
|
+
const visible = visibleQuestionIndices();
|
|
585
|
+
const isMultiQuestion = visible.length > 1;
|
|
586
|
+
const visiblePos = Math.max(visible.indexOf(currentIdx), 0);
|
|
504
587
|
const q = questions[currentIdx];
|
|
505
588
|
const st = states[currentIdx];
|
|
506
589
|
const multiSel = isMultiSelect(currentIdx);
|
|
507
590
|
push(ui.bar());
|
|
508
591
|
// ── Progress header ────────────────────────────────────────────
|
|
509
592
|
if (isMultiQuestion) {
|
|
510
|
-
const unanswered =
|
|
511
|
-
const answeredSet = new Set(
|
|
512
|
-
push(ui.questionTabs(
|
|
593
|
+
const unanswered = visible.filter((i) => !isQuestionAnswered(i)).length;
|
|
594
|
+
const answeredSet = new Set(visible.map((i, visibleIndex) => (isQuestionAnswered(i) ? visibleIndex : -1)).filter((i) => i >= 0));
|
|
595
|
+
push(ui.questionTabs(visible.map((i) => questions[i]?.header ?? ""), visiblePos, answeredSet));
|
|
513
596
|
push(ui.blank());
|
|
514
597
|
const progressParts = [
|
|
515
598
|
opts.progress,
|
|
516
|
-
`Question ${
|
|
599
|
+
`Question ${visiblePos + 1}/${visible.length}`,
|
|
517
600
|
unanswered > 0 ? `${unanswered} unanswered` : null,
|
|
518
601
|
].filter(Boolean).join(" • ");
|
|
519
602
|
if (progressParts)
|
|
@@ -582,7 +665,7 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
582
665
|
}
|
|
583
666
|
// ── Footer hints ───────────────────────────────────────────────
|
|
584
667
|
push(ui.blank());
|
|
585
|
-
const isLast = !isMultiQuestion ||
|
|
668
|
+
const isLast = !isMultiQuestion || visiblePos === visible.length - 1;
|
|
586
669
|
const hints = [];
|
|
587
670
|
if (focusNotes) {
|
|
588
671
|
hints.push("enter to confirm");
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"id": "slash-commands",
|
|
3
3
|
"name": "Slash Commands",
|
|
4
4
|
"version": "1.0.0",
|
|
5
|
-
"description": "Bundled slash commands for context inspection, planning, and lazy tool search",
|
|
5
|
+
"description": "Bundled slash commands for context inspection, planning, fast mode, and lazy tool search",
|
|
6
6
|
"tier": "bundled",
|
|
7
7
|
"requires": { "platform": ">=2.29.0" },
|
|
8
8
|
"provides": {
|
|
9
|
-
"commands": ["audit", "clear", "context", "plan", "execute", "cancel-plan", "tools"],
|
|
9
|
+
"commands": ["audit", "clear", "context", "fast", "plan", "execute", "cancel-plan", "tools"],
|
|
10
10
|
"tools": ["tool_search", "tool_enable"],
|
|
11
11
|
"flags": ["plan"]
|
|
12
12
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { getAgentDir, SettingsManager } from "@gsd/pi-coding-agent";
|
|
2
|
+
function parseFastCommandAction(args) {
|
|
3
|
+
const normalized = args.trim().toLowerCase();
|
|
4
|
+
if (!normalized)
|
|
5
|
+
return "toggle";
|
|
6
|
+
if (normalized === "on")
|
|
7
|
+
return "on";
|
|
8
|
+
if (normalized === "off")
|
|
9
|
+
return "off";
|
|
10
|
+
if (normalized === "status")
|
|
11
|
+
return "status";
|
|
12
|
+
return "invalid";
|
|
13
|
+
}
|
|
14
|
+
function supportsFastMode(model) {
|
|
15
|
+
if (!model)
|
|
16
|
+
return false;
|
|
17
|
+
if (model.api === "openai-codex-responses")
|
|
18
|
+
return true;
|
|
19
|
+
if (model.api !== "openai-responses")
|
|
20
|
+
return false;
|
|
21
|
+
if (model.provider !== "openai")
|
|
22
|
+
return false;
|
|
23
|
+
return model.capabilities?.supportsServiceTier === true;
|
|
24
|
+
}
|
|
25
|
+
function getModelLabel(model) {
|
|
26
|
+
if (!model)
|
|
27
|
+
return "no active model";
|
|
28
|
+
return `${model.provider}/${model.id}`;
|
|
29
|
+
}
|
|
30
|
+
function getSettingsManager() {
|
|
31
|
+
return SettingsManager.create(process.cwd(), getAgentDir());
|
|
32
|
+
}
|
|
33
|
+
export const __testing = {
|
|
34
|
+
parseFastCommandAction,
|
|
35
|
+
supportsFastMode,
|
|
36
|
+
};
|
|
37
|
+
export default function fastCommand(pi) {
|
|
38
|
+
pi.registerCommand("fast", {
|
|
39
|
+
description: "Toggle fast mode for OpenAI/Codex models (service_tier=priority)",
|
|
40
|
+
getArgumentCompletions(prefix) {
|
|
41
|
+
const options = [
|
|
42
|
+
{ value: "on", label: "on", description: "Enable fast mode" },
|
|
43
|
+
{ value: "off", label: "off", description: "Disable fast mode" },
|
|
44
|
+
{ value: "status", label: "status", description: "Show current fast-mode status" },
|
|
45
|
+
];
|
|
46
|
+
const query = prefix.trim().toLowerCase();
|
|
47
|
+
return options.filter((item) => item.value.startsWith(query));
|
|
48
|
+
},
|
|
49
|
+
async handler(args, ctx) {
|
|
50
|
+
const settings = getSettingsManager();
|
|
51
|
+
const current = settings.getFastMode();
|
|
52
|
+
const action = parseFastCommandAction(args);
|
|
53
|
+
const model = ctx.model;
|
|
54
|
+
const supported = supportsFastMode(model);
|
|
55
|
+
const modelLabel = getModelLabel(model);
|
|
56
|
+
if (action === "invalid") {
|
|
57
|
+
ctx.ui.notify("Usage: /fast [on|off|status]", "warning");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (action === "status") {
|
|
61
|
+
ctx.ui.notify(`Fast mode: ${current ? "ON" : "OFF"} · model ${modelLabel} is ${supported ? "supported" : "unsupported"}`, "info");
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const next = action === "toggle" ? !current : action === "on";
|
|
65
|
+
settings.setFastMode(next);
|
|
66
|
+
if (!supported) {
|
|
67
|
+
ctx.ui.notify(`Fast mode: ${next ? "ON" : "OFF"} (saved). Current model ${modelLabel} does not support fast mode.`, "warning");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
ctx.ui.notify(`Fast mode: ${next ? "ON" : "OFF"} (saved). ${next ? "Requests will include service_tier=priority." : "Requests will omit service_tier."}`, "info");
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import auditCommand from "./audit.js";
|
|
2
2
|
import clearCommand from "./clear.js";
|
|
3
3
|
import contextCommand from "./context.js";
|
|
4
|
+
import fastCommand from "./fast.js";
|
|
4
5
|
import initCommand from "./init.js";
|
|
5
6
|
import planCommand from "./plan.js";
|
|
6
7
|
import toolSearchExtension from "./tools.js";
|
|
@@ -8,6 +9,7 @@ export default function slashCommands(pi) {
|
|
|
8
9
|
auditCommand(pi);
|
|
9
10
|
clearCommand(pi);
|
|
10
11
|
contextCommand(pi);
|
|
12
|
+
fastCommand(pi);
|
|
11
13
|
initCommand(pi);
|
|
12
14
|
planCommand(pi);
|
|
13
15
|
toolSearchExtension(pi);
|
|
@@ -28,9 +28,8 @@ const BLOCKED_TOOLS = new Set([
|
|
|
28
28
|
"async_bash",
|
|
29
29
|
"bg_shell",
|
|
30
30
|
"browser_navigate",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"browser_reload",
|
|
31
|
+
"browser_pages",
|
|
32
|
+
"browser_frames",
|
|
34
33
|
"browser_click",
|
|
35
34
|
"browser_drag",
|
|
36
35
|
"browser_type",
|
|
@@ -41,18 +40,13 @@ const BLOCKED_TOOLS = new Set([
|
|
|
41
40
|
"browser_select_option",
|
|
42
41
|
"browser_set_checked",
|
|
43
42
|
"browser_set_viewport",
|
|
44
|
-
"
|
|
45
|
-
"browser_hover_ref",
|
|
46
|
-
"browser_fill_ref",
|
|
43
|
+
"browser_ref",
|
|
47
44
|
"browser_act",
|
|
48
45
|
"browser_batch",
|
|
49
46
|
"browser_fill_form",
|
|
50
|
-
"
|
|
51
|
-
"browser_block_urls",
|
|
52
|
-
"browser_clear_routes",
|
|
47
|
+
"browser_network",
|
|
53
48
|
"browser_emulate_device",
|
|
54
|
-
"
|
|
55
|
-
"browser_restore_state",
|
|
49
|
+
"browser_state",
|
|
56
50
|
"browser_generate_test",
|
|
57
51
|
"browser_verify",
|
|
58
52
|
"write",
|
|
@@ -70,6 +64,7 @@ const REVISE_LABEL = "Revise plan";
|
|
|
70
64
|
const CANCEL_LABEL = "Cancel";
|
|
71
65
|
const DEFAULT_PLAN_REVIEW_AGENT = "generic";
|
|
72
66
|
const DEFAULT_PLAN_CODING_AGENT = "worker";
|
|
67
|
+
const MIN_PLAN_CONFIDENCE = 8;
|
|
73
68
|
const INITIAL_STATE = {
|
|
74
69
|
active: false,
|
|
75
70
|
task: "",
|
|
@@ -366,6 +361,9 @@ function buildPlanModeSystemPrompt() {
|
|
|
366
361
|
"You are currently in plan mode.",
|
|
367
362
|
"Investigate, clarify scope, and produce a persisted execution plan before making source changes.",
|
|
368
363
|
"If requirements are ambiguous or constraints are missing, ask concise clarifying questions before drafting or saving a plan.",
|
|
364
|
+
`Before writing or updating a plan artifact, make sure your confidence is at least ${MIN_PLAN_CONFIDENCE}/10. If confidence is lower, investigate more or ask clarifying questions first.`,
|
|
365
|
+
"Include an explicit confidence line in every saved plan, for example: \"Confidence: 8/10\" or higher.",
|
|
366
|
+
"When adjusting an existing saved plan, prefer the edit tool for targeted changes. Rewrite the whole file only when the structure changes substantially or an exact edit is impractical.",
|
|
369
367
|
"Do not modify source files or run side-effect commands while plan mode is active.",
|
|
370
368
|
"Persist plan artifacts under .lsd/plan/.",
|
|
371
369
|
];
|
|
@@ -395,25 +393,18 @@ function buildNewSessionOptionLabel() {
|
|
|
395
393
|
return `${APPROVE_LABEL} — ${APPROVE_NEW_SESSION_LABEL} (${suffix})`;
|
|
396
394
|
}
|
|
397
395
|
function buildApprovalActionInstructions() {
|
|
398
|
-
return [
|
|
399
|
-
"Ask for plan approval now using ask_user_questions.",
|
|
400
|
-
`One single-select question with id \"${PLAN_APPROVAL_ACTION_QUESTION_ID}\". Ask what to do next with the plan.`,
|
|
401
|
-
`Options: ${APPROVE_LABEL}, ${REVIEW_LABEL}, ${REVISE_LABEL}.`,
|
|
402
|
-
`Do not include \"${CANCEL_LABEL}\" as an explicit option — if the user wants to cancel they should choose \"None of the above\" and type \"${CANCEL_LABEL}\" in the note.`,
|
|
403
|
-
"Do not restate the plan. Just show the question.",
|
|
404
|
-
].join(" ");
|
|
405
|
-
}
|
|
406
|
-
function buildApprovalModeInstructions() {
|
|
407
396
|
const autoSwitchEnabled = readAutoSwitchPlanModelSetting();
|
|
408
397
|
const showNewSessionOption = autoSwitchEnabled;
|
|
409
398
|
const newSessionLabel = buildNewSessionOptionLabel();
|
|
410
|
-
const options = showNewSessionOption
|
|
411
|
-
? `${APPROVE_AUTO_LABEL}, ${APPROVE_BYPASS_LABEL}, ${APPROVE_AUTO_SUBAGENT_LABEL}, ${APPROVE_BYPASS_SUBAGENT_LABEL}, ${newSessionLabel}`
|
|
412
|
-
: `${APPROVE_AUTO_LABEL}, ${APPROVE_BYPASS_LABEL}, ${APPROVE_AUTO_SUBAGENT_LABEL}, ${APPROVE_BYPASS_SUBAGENT_LABEL}`;
|
|
413
399
|
return [
|
|
414
|
-
"
|
|
415
|
-
`
|
|
416
|
-
`
|
|
400
|
+
"Ask for plan approval now via exactly one ask_user_questions tool call.",
|
|
401
|
+
`Question 1 (single-select) id \"${PLAN_APPROVAL_ACTION_QUESTION_ID}\": ask what to do next with the plan. In the question text, tell the user that if they choose \"${REVISE_LABEL}\" they should type exact requested changes in the dialog notes field before submitting.`,
|
|
402
|
+
`Question 1 options: ${APPROVE_LABEL}, ${REVIEW_LABEL}, ${REVISE_LABEL}. Put "${APPROVE_LABEL}" first with a "(Recommended)" suffix in the description, not in the label.`,
|
|
403
|
+
`Do not include \"${CANCEL_LABEL}\" as an explicit option — if the user wants to cancel they should choose \"None of the above\" and type \"${CANCEL_LABEL}\" in the note.`,
|
|
404
|
+
`Question 2 (single-select) id \"${PLAN_APPROVAL_PERMISSION_QUESTION_ID}\": ask which execution mode to use.`,
|
|
405
|
+
`Question 2 options: ${APPROVE_AUTO_LABEL} (Recommended), ${APPROVE_BYPASS_LABEL}, ${APPROVE_AUTO_SUBAGENT_LABEL}, ${APPROVE_BYPASS_SUBAGENT_LABEL}${showNewSessionOption ? `, ${newSessionLabel}` : ""}.`,
|
|
406
|
+
`Set question 2 showWhen.questionId to \"${PLAN_APPROVAL_ACTION_QUESTION_ID}\" and showWhen.selectedAnyOf to [\"${APPROVE_LABEL}\"] so it appears only when the user selects Approve plan.`,
|
|
407
|
+
"Do not restate the plan in a normal assistant response. Just call ask_user_questions.",
|
|
417
408
|
].join(" ");
|
|
418
409
|
}
|
|
419
410
|
// Keep for external callers that reference the combined form (headless path)
|
|
@@ -461,6 +452,23 @@ function buildReviewSteeringMessage(planPath, planMarkdown) {
|
|
|
461
452
|
details.push("After the subagent responds, summarize its feedback for the user, present the current plan again, and then ask for approval again.", buildApprovalActionInstructions());
|
|
462
453
|
return details.join("\n\n");
|
|
463
454
|
}
|
|
455
|
+
function buildRevisionSteeringMessage(planPath, requestedChanges) {
|
|
456
|
+
const details = [
|
|
457
|
+
`The user selected \"${REVISE_LABEL}\" for ${planPath}.`,
|
|
458
|
+
"Revise the existing saved plan instead of drafting a fresh replacement unless a full rewrite is genuinely necessary.",
|
|
459
|
+
"Prefer the edit tool for targeted adjustments to the current plan artifact. Use write only if the structure changes substantially or an exact edit is impractical.",
|
|
460
|
+
`Before saving the revised plan, make sure confidence is at least ${MIN_PLAN_CONFIDENCE}/10. If lower, investigate more or ask clarifying questions first.`,
|
|
461
|
+
"Keep an explicit confidence line in the plan, for example: \"Confidence: 8/10\" or higher.",
|
|
462
|
+
];
|
|
463
|
+
if (requestedChanges) {
|
|
464
|
+
details.push(`User-requested changes: ${requestedChanges}`);
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
details.push("No concrete revision note was provided yet. Ask one concise clarifying question about what should change before editing the plan.");
|
|
468
|
+
}
|
|
469
|
+
details.push("After revising the saved plan artifact, ask for approval again.");
|
|
470
|
+
return details.join("\n\n");
|
|
471
|
+
}
|
|
464
472
|
function approvalSelectionToExecutionMode(selected) {
|
|
465
473
|
if (!selected)
|
|
466
474
|
return undefined;
|
|
@@ -489,6 +497,12 @@ function getAnswerValues(answer) {
|
|
|
489
497
|
}
|
|
490
498
|
return values;
|
|
491
499
|
}
|
|
500
|
+
function getAnswerNote(answer) {
|
|
501
|
+
if (typeof answer?.notes !== "string")
|
|
502
|
+
return undefined;
|
|
503
|
+
const note = answer.notes.trim();
|
|
504
|
+
return note.length > 0 ? note : undefined;
|
|
505
|
+
}
|
|
492
506
|
function selectionRequestsCancel(selected) {
|
|
493
507
|
return selected.some((value) => {
|
|
494
508
|
if (typeof value !== "string")
|
|
@@ -513,6 +527,8 @@ export const __testing = {
|
|
|
513
527
|
buildApprovalSteeringMessage,
|
|
514
528
|
buildPlanPreviewMessage,
|
|
515
529
|
buildReviewSteeringMessage,
|
|
530
|
+
buildRevisionSteeringMessage,
|
|
531
|
+
buildPlanModeSystemPrompt,
|
|
516
532
|
buildAutoSuggestPlanModeSystemPrompt,
|
|
517
533
|
readAutoSuggestPlanModeSetting,
|
|
518
534
|
PLAN_SUGGEST_QUESTION_ID,
|
|
@@ -679,8 +695,16 @@ export default function planCommand(pi) {
|
|
|
679
695
|
if (!actionSelection)
|
|
680
696
|
return;
|
|
681
697
|
if (actionSelection.includes(APPROVE_LABEL)) {
|
|
682
|
-
|
|
683
|
-
|
|
698
|
+
const executionMode = approvalSelectionToExecutionMode(permissionValues[0]) ?? {
|
|
699
|
+
permissionMode: DEFAULT_APPROVAL_PERMISSION_MODE,
|
|
700
|
+
executeWithSubagent: false,
|
|
701
|
+
};
|
|
702
|
+
state = { ...state, targetPermissionMode: executionMode.permissionMode };
|
|
703
|
+
if (executionMode.executeWithSubagent) {
|
|
704
|
+
const modeLabel = executionMode.permissionMode === "danger-full-access" ? "bypass" : "auto";
|
|
705
|
+
ctx.ui?.notify?.(`Plan approved: subagent(${modeLabel})`, "info");
|
|
706
|
+
}
|
|
707
|
+
await approvePlan(pi, ctx, executionMode.permissionMode, executionMode.executeWithSubagent);
|
|
684
708
|
return;
|
|
685
709
|
}
|
|
686
710
|
if (actionSelection.includes(REVIEW_LABEL)) {
|
|
@@ -695,9 +719,11 @@ export default function planCommand(pi) {
|
|
|
695
719
|
return;
|
|
696
720
|
}
|
|
697
721
|
if (actionSelection.includes(REVISE_LABEL)) {
|
|
722
|
+
const requestedChanges = getAnswerNote(actionAnswer);
|
|
698
723
|
enablePlanMode(pi, ctx.model ? { provider: ctx.model.provider, id: ctx.model.id } : undefined, {
|
|
699
724
|
approvalStatus: "revising",
|
|
700
725
|
});
|
|
726
|
+
pi.sendUserMessage(buildRevisionSteeringMessage(state.latestPlanPath ?? "the latest plan", requestedChanges), { deliverAs: "steer" });
|
|
701
727
|
}
|
|
702
728
|
});
|
|
703
729
|
pi.registerCommand("plan", {
|
|
@@ -37,6 +37,30 @@ function getBalancedToolNames(activeToolNames) {
|
|
|
37
37
|
"ask_user_questions",
|
|
38
38
|
];
|
|
39
39
|
}
|
|
40
|
+
const STANDARD_TOOLS = [
|
|
41
|
+
// Core
|
|
42
|
+
"read", "bash", "edit", "write", "lsp", "grep", "find", "ls",
|
|
43
|
+
// Background
|
|
44
|
+
"bg_shell",
|
|
45
|
+
// Search
|
|
46
|
+
"web_search", "fetch_page",
|
|
47
|
+
// Docs
|
|
48
|
+
"resolve_library", "get_library_docs",
|
|
49
|
+
// Agent
|
|
50
|
+
"subagent", "await_subagent", "Skill",
|
|
51
|
+
// User interaction
|
|
52
|
+
"ask_user_questions", "secure_env_collect",
|
|
53
|
+
// Browser (essential)
|
|
54
|
+
"browser_navigate", "browser_click", "browser_type", "browser_screenshot",
|
|
55
|
+
"browser_scroll", "browser_key_press", "browser_evaluate",
|
|
56
|
+
"browser_find", "browser_wait_for", "browser_close",
|
|
57
|
+
"browser_assert", "browser_batch",
|
|
58
|
+
// Tool management
|
|
59
|
+
"tool_search", "tool_enable",
|
|
60
|
+
];
|
|
61
|
+
function getStandardToolNames() {
|
|
62
|
+
return [...STANDARD_TOOLS];
|
|
63
|
+
}
|
|
40
64
|
function getFullToolNames(pi) {
|
|
41
65
|
return pi.getAllTools().map((tool) => tool.name).filter((name) => Boolean(name));
|
|
42
66
|
}
|
|
@@ -168,7 +192,8 @@ export default function toolSearchExtension(pi) {
|
|
|
168
192
|
currentActive.length > 0 ? currentActive.join(", ") : "(none)",
|
|
169
193
|
"",
|
|
170
194
|
"Usage:",
|
|
171
|
-
" /tools balanced Switch to the balanced tool profile",
|
|
195
|
+
" /tools balanced Switch to the balanced tool profile (12 tools)",
|
|
196
|
+
" /tools standard Switch to the standard tool profile (~32 tools)",
|
|
172
197
|
" /tools full Switch to the full tool profile (all available tools)",
|
|
173
198
|
" /tools on Alias for /tools full",
|
|
174
199
|
" /tools off Alias for /tools balanced",
|
|
@@ -183,7 +208,18 @@ export default function toolSearchExtension(pi) {
|
|
|
183
208
|
pi.setActiveTools(nextActive);
|
|
184
209
|
pi.sendMessage({
|
|
185
210
|
customType: "tools:mode",
|
|
186
|
-
content: `Balanced tool profile active: ${pi.getActiveTools().join(", ")}`,
|
|
211
|
+
content: `Balanced tool profile active (${pi.getActiveTools().length} tools): ${pi.getActiveTools().join(", ")}`,
|
|
212
|
+
display: true,
|
|
213
|
+
});
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (input === "standard") {
|
|
217
|
+
settings.setToolProfile("standard");
|
|
218
|
+
const nextActive = getStandardToolNames();
|
|
219
|
+
pi.setActiveTools(nextActive);
|
|
220
|
+
pi.sendMessage({
|
|
221
|
+
customType: "tools:mode",
|
|
222
|
+
content: `Standard tool profile active (${pi.getActiveTools().length} tools): ${pi.getActiveTools().join(", ")}`,
|
|
187
223
|
display: true,
|
|
188
224
|
});
|
|
189
225
|
return;
|
|
@@ -194,14 +230,14 @@ export default function toolSearchExtension(pi) {
|
|
|
194
230
|
pi.setActiveTools(nextActive);
|
|
195
231
|
pi.sendMessage({
|
|
196
232
|
customType: "tools:mode",
|
|
197
|
-
content: `Full tool profile active: ${pi.getActiveTools().join(", ")}`,
|
|
233
|
+
content: `Full tool profile active (${pi.getActiveTools().length} tools): ${pi.getActiveTools().join(", ")}`,
|
|
198
234
|
display: true,
|
|
199
235
|
});
|
|
200
236
|
return;
|
|
201
237
|
}
|
|
202
238
|
pi.sendMessage({
|
|
203
239
|
customType: "tools:help",
|
|
204
|
-
content: `Unknown /tools subcommand: ${input}\n\nTry /tools, /tools balanced, /tools full, /tools on, or /tools off.`,
|
|
240
|
+
content: `Unknown /tools subcommand: ${input}\n\nTry /tools, /tools balanced, /tools standard, /tools full, /tools on, or /tools off.`,
|
|
205
241
|
display: true,
|
|
206
242
|
});
|
|
207
243
|
},
|