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
|
@@ -3,93 +3,36 @@ import { Type } from "@sinclair/typebox";
|
|
|
3
3
|
import type { ToolDeps } from "../state.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* State persistence
|
|
6
|
+
* State persistence — save/restore cookies, localStorage, sessionStorage.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const STATE_DIR = ".gsd/browser-state";
|
|
10
10
|
|
|
11
11
|
export function registerStatePersistenceTools(pi: ExtensionAPI, deps: ToolDeps): void {
|
|
12
|
-
// -------------------------------------------------------------------------
|
|
13
|
-
// browser_save_state
|
|
14
|
-
// -------------------------------------------------------------------------
|
|
15
12
|
pi.registerTool({
|
|
16
|
-
name: "
|
|
17
|
-
label: "Browser
|
|
13
|
+
name: "browser_state",
|
|
14
|
+
label: "Browser State",
|
|
18
15
|
description:
|
|
19
|
-
"Save cookies, localStorage,
|
|
20
|
-
"State files
|
|
21
|
-
"Never displays secret values in output.",
|
|
16
|
+
"Save or restore browser state (cookies, localStorage, sessionStorage) to persist sessions across browser restarts. " +
|
|
17
|
+
"State files written to .gsd/browser-state/ (should be gitignored).",
|
|
22
18
|
parameters: Type.Object({
|
|
23
|
-
|
|
24
|
-
Type.
|
|
25
|
-
|
|
19
|
+
action: Type.Union([
|
|
20
|
+
Type.Literal("save"),
|
|
21
|
+
Type.Literal("restore"),
|
|
22
|
+
], { description: "'save' — persist current state, 'restore' — load previously saved state" }),
|
|
23
|
+
name: Type.Optional(Type.String({ description: "State file name (default: 'default'). Used as filename stem." })),
|
|
26
24
|
}),
|
|
27
25
|
|
|
28
26
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
29
27
|
try {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const path = await import("node:path");
|
|
35
|
-
const stateDir = path.resolve(process.cwd(), STATE_DIR);
|
|
36
|
-
await mkdir(stateDir, { recursive: true });
|
|
37
|
-
|
|
38
|
-
// 1. Playwright storageState: cookies + localStorage
|
|
39
|
-
const storageState = await ctx.storageState();
|
|
40
|
-
|
|
41
|
-
// 2. sessionStorage: must be extracted per-origin via page.evaluate
|
|
42
|
-
const sessionStorageData: Record<string, Record<string, string>> = {};
|
|
43
|
-
try {
|
|
44
|
-
const origin = new URL(p.url()).origin;
|
|
45
|
-
const ssData = await p.evaluate(() => {
|
|
46
|
-
const data: Record<string, string> = {};
|
|
47
|
-
for (let i = 0; i < sessionStorage.length; i++) {
|
|
48
|
-
const key = sessionStorage.key(i);
|
|
49
|
-
if (key) data[key] = sessionStorage.getItem(key) ?? "";
|
|
50
|
-
}
|
|
51
|
-
return data;
|
|
52
|
-
});
|
|
53
|
-
if (Object.keys(ssData).length > 0) {
|
|
54
|
-
sessionStorageData[origin] = ssData;
|
|
55
|
-
}
|
|
56
|
-
} catch {
|
|
57
|
-
// Page may not have a valid origin (about:blank, etc.)
|
|
28
|
+
if (params.action === "save") {
|
|
29
|
+
return await saveState(deps, params.name ?? "default");
|
|
30
|
+
} else {
|
|
31
|
+
return await restoreState(deps, params.name ?? "default");
|
|
58
32
|
}
|
|
59
|
-
|
|
60
|
-
const combined = {
|
|
61
|
-
storageState,
|
|
62
|
-
sessionStorage: sessionStorageData,
|
|
63
|
-
savedAt: new Date().toISOString(),
|
|
64
|
-
url: p.url(),
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const filePath = path.join(stateDir, `${name}.json`);
|
|
68
|
-
await writeFile(filePath, JSON.stringify(combined, null, 2));
|
|
69
|
-
|
|
70
|
-
// Ensure .gitignore covers the state dir
|
|
71
|
-
const gitignorePath = path.resolve(process.cwd(), STATE_DIR, ".gitignore");
|
|
72
|
-
await writeFile(gitignorePath, "*\n!.gitignore\n").catch(() => { /* best-effort — .gitignore may already exist or dir may be read-only */ });
|
|
73
|
-
|
|
74
|
-
const cookieCount = storageState.cookies?.length ?? 0;
|
|
75
|
-
const localStorageOrigins = storageState.origins?.length ?? 0;
|
|
76
|
-
const sessionStorageOrigins = Object.keys(sessionStorageData).length;
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
content: [{
|
|
80
|
-
type: "text",
|
|
81
|
-
text: `State saved: ${filePath}\nCookies: ${cookieCount}\nlocalStorage origins: ${localStorageOrigins}\nsessionStorage origins: ${sessionStorageOrigins}`,
|
|
82
|
-
}],
|
|
83
|
-
details: {
|
|
84
|
-
path: filePath,
|
|
85
|
-
cookieCount,
|
|
86
|
-
localStorageOrigins,
|
|
87
|
-
sessionStorageOrigins,
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
33
|
} catch (err: any) {
|
|
91
34
|
return {
|
|
92
|
-
content: [{ type: "text", text: `
|
|
35
|
+
content: [{ type: "text" as const, text: `State '${params.action}' failed: ${err.message}` }],
|
|
93
36
|
details: { error: err.message },
|
|
94
37
|
isError: true,
|
|
95
38
|
};
|
|
@@ -97,106 +40,85 @@ export function registerStatePersistenceTools(pi: ExtensionAPI, deps: ToolDeps):
|
|
|
97
40
|
},
|
|
98
41
|
});
|
|
99
42
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
try {
|
|
118
|
-
const { context: ctx, page: p } = await deps.ensureBrowser();
|
|
119
|
-
const name = deps.sanitizeArtifactName(params.name ?? "default", "default");
|
|
120
|
-
|
|
121
|
-
const { readFile } = await import("node:fs/promises");
|
|
122
|
-
const path = await import("node:path");
|
|
123
|
-
const filePath = path.join(process.cwd(), STATE_DIR, `${name}.json`);
|
|
124
|
-
|
|
125
|
-
let raw: string;
|
|
126
|
-
try {
|
|
127
|
-
raw = await readFile(filePath, "utf-8");
|
|
128
|
-
} catch {
|
|
129
|
-
return {
|
|
130
|
-
content: [{ type: "text", text: `State file not found: ${filePath}` }],
|
|
131
|
-
details: { error: "file_not_found", path: filePath },
|
|
132
|
-
isError: true,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const combined = JSON.parse(raw);
|
|
137
|
-
const storageState = combined.storageState;
|
|
138
|
-
const sessionStorageData: Record<string, Record<string, string>> = combined.sessionStorage ?? {};
|
|
139
|
-
|
|
140
|
-
// 1. Restore cookies
|
|
141
|
-
let cookieCount = 0;
|
|
142
|
-
if (storageState?.cookies?.length) {
|
|
143
|
-
await ctx.addCookies(storageState.cookies);
|
|
144
|
-
cookieCount = storageState.cookies.length;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// 2. Restore localStorage via page.evaluate
|
|
148
|
-
let localStorageOrigins = 0;
|
|
149
|
-
if (storageState?.origins?.length) {
|
|
150
|
-
for (const origin of storageState.origins) {
|
|
151
|
-
try {
|
|
152
|
-
await p.evaluate((items: Array<{ name: string; value: string }>) => {
|
|
153
|
-
for (const { name, value } of items) {
|
|
154
|
-
localStorage.setItem(name, value);
|
|
155
|
-
}
|
|
156
|
-
}, origin.localStorage ?? []);
|
|
157
|
-
localStorageOrigins++;
|
|
158
|
-
} catch {
|
|
159
|
-
// Origin mismatch — localStorage can only be set on matching origin
|
|
160
|
-
}
|
|
161
|
-
}
|
|
43
|
+
async function saveState(deps: ToolDeps, name: string) {
|
|
44
|
+
const { context: ctx, page: p } = await deps.ensureBrowser();
|
|
45
|
+
name = deps.sanitizeArtifactName(name, "default");
|
|
46
|
+
const { mkdir, writeFile } = await import("node:fs/promises");
|
|
47
|
+
const path = await import("node:path");
|
|
48
|
+
const stateDir = path.resolve(process.cwd(), STATE_DIR);
|
|
49
|
+
await mkdir(stateDir, { recursive: true });
|
|
50
|
+
|
|
51
|
+
const storageState = await ctx.storageState();
|
|
52
|
+
const sessionStorageData: Record<string, Record<string, string>> = {};
|
|
53
|
+
try {
|
|
54
|
+
const origin = new URL(p.url()).origin;
|
|
55
|
+
const ssData = await p.evaluate(() => {
|
|
56
|
+
const data: Record<string, string> = {};
|
|
57
|
+
for (let i = 0; i < sessionStorage.length; i++) {
|
|
58
|
+
const key = sessionStorage.key(i);
|
|
59
|
+
if (key) data[key] = sessionStorage.getItem(key) ?? "";
|
|
162
60
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
61
|
+
return data;
|
|
62
|
+
});
|
|
63
|
+
if (Object.keys(ssData).length > 0) sessionStorageData[origin] = ssData;
|
|
64
|
+
} catch { /* Page may not have a valid origin */ }
|
|
65
|
+
|
|
66
|
+
const combined = { storageState, sessionStorage: sessionStorageData, savedAt: new Date().toISOString(), url: p.url() };
|
|
67
|
+
const filePath = path.join(stateDir, `${name}.json`);
|
|
68
|
+
await writeFile(filePath, JSON.stringify(combined, null, 2));
|
|
69
|
+
|
|
70
|
+
const gitignorePath = path.resolve(process.cwd(), STATE_DIR, ".gitignore");
|
|
71
|
+
await writeFile(gitignorePath, "*\n!.gitignore\n").catch(() => { /* best-effort */ });
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
content: [{ type: "text" as const, text: `State saved: ${filePath}\nCookies: ${storageState.cookies?.length ?? 0}\nlocalStorage origins: ${storageState.origins?.length ?? 0}\nsessionStorage origins: ${Object.keys(sessionStorageData).length}` }],
|
|
75
|
+
details: { path: filePath, cookieCount: storageState.cookies?.length ?? 0, localStorageOrigins: storageState.origins?.length ?? 0, sessionStorageOrigins: Object.keys(sessionStorageData).length },
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function restoreState(deps: ToolDeps, name: string) {
|
|
80
|
+
const { context: ctx, page: p } = await deps.ensureBrowser();
|
|
81
|
+
name = deps.sanitizeArtifactName(name, "default");
|
|
82
|
+
const { readFile } = await import("node:fs/promises");
|
|
83
|
+
const path = await import("node:path");
|
|
84
|
+
const filePath = path.join(process.cwd(), STATE_DIR, `${name}.json`);
|
|
85
|
+
|
|
86
|
+
let raw: string;
|
|
87
|
+
try { raw = await readFile(filePath, "utf-8"); } catch {
|
|
88
|
+
return { content: [{ type: "text" as const, text: `State file not found: ${filePath}` }], details: { error: "file_not_found", path: filePath }, isError: true };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const combined = JSON.parse(raw);
|
|
92
|
+
const storageState = combined.storageState;
|
|
93
|
+
const sessionStorageData: Record<string, Record<string, string>> = combined.sessionStorage ?? {};
|
|
94
|
+
|
|
95
|
+
let cookieCount = 0;
|
|
96
|
+
if (storageState?.cookies?.length) {
|
|
97
|
+
await ctx.addCookies(storageState.cookies);
|
|
98
|
+
cookieCount = storageState.cookies.length;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let localStorageOrigins = 0;
|
|
102
|
+
if (storageState?.origins?.length) {
|
|
103
|
+
for (const origin of storageState.origins) {
|
|
104
|
+
try {
|
|
105
|
+
await p.evaluate((items: Array<{ name: string; value: string }>) => { for (const { name, value } of items) localStorage.setItem(name, value); }, origin.localStorage ?? []);
|
|
106
|
+
localStorageOrigins++;
|
|
107
|
+
} catch { /* Origin mismatch */ }
|
|
199
108
|
}
|
|
200
|
-
}
|
|
201
|
-
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let sessionStorageOrigins = 0;
|
|
112
|
+
for (const [_origin, data] of Object.entries(sessionStorageData)) {
|
|
113
|
+
try {
|
|
114
|
+
await p.evaluate((items: Record<string, string>) => { for (const [key, value] of Object.entries(items)) sessionStorage.setItem(key, value); }, data);
|
|
115
|
+
sessionStorageOrigins++;
|
|
116
|
+
} catch { /* Origin mismatch */ }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
content: [{ type: "text" as const, text: `State restored from: ${filePath}\nCookies: ${cookieCount}\nlocalStorage origins: ${localStorageOrigins}\nsessionStorage origins: ${sessionStorageOrigins}` }],
|
|
121
|
+
details: { path: filePath, cookieCount, localStorageOrigins, sessionStorageOrigins, savedAt: combined.savedAt, savedUrl: combined.url },
|
|
122
|
+
};
|
|
123
|
+
}
|
|
202
124
|
}
|
|
@@ -625,7 +625,7 @@ export function formatVersionedRef(version: number, key: string): string {
|
|
|
625
625
|
}
|
|
626
626
|
|
|
627
627
|
export function staleRefGuidance(refDisplay: string, reason: string): string {
|
|
628
|
-
return `Ref ${refDisplay} could not be resolved (${reason}). The ref is likely stale after DOM/navigation changes. Call
|
|
628
|
+
return `Ref ${refDisplay} could not be resolved (${reason}). The ref is likely stale after DOM/navigation changes. Call browser_ref with action='snapshot' to refresh refs.`;
|
|
629
629
|
}
|
|
630
630
|
|
|
631
631
|
// ---------------------------------------------------------------------------
|
|
@@ -204,9 +204,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
204
204
|
"List all running macOS applications. Returns an array of { name, bundleId, pid, isActive } " +
|
|
205
205
|
"for user-facing apps (regular activation policy). Set includeBackground to true to also " +
|
|
206
206
|
"include accessory/background apps.",
|
|
207
|
-
promptGuidelines: [
|
|
208
|
-
"Use to discover what apps are running before interacting with them.",
|
|
209
|
-
],
|
|
207
|
+
promptGuidelines: [] as string[],
|
|
210
208
|
parameters: Type.Object({
|
|
211
209
|
includeBackground: Type.Optional(Type.Boolean({ description: "Include background/accessory apps (default: false)" })),
|
|
212
210
|
}),
|
|
@@ -235,9 +233,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
235
233
|
"Launch a macOS application by name or bundle ID. " +
|
|
236
234
|
"Returns { launched, name, bundleId, pid } on success. " +
|
|
237
235
|
"Provide either 'name' (e.g. 'TextEdit') or 'bundleId' (e.g. 'com.apple.TextEdit').",
|
|
238
|
-
promptGuidelines: [
|
|
239
|
-
"Use app name for well-known apps; use bundleId when the name is ambiguous.",
|
|
240
|
-
],
|
|
241
236
|
parameters: Type.Object({
|
|
242
237
|
name: Type.Optional(Type.String({ description: "Application name (e.g. 'TextEdit', 'Safari')" })),
|
|
243
238
|
bundleId: Type.Optional(Type.String({ description: "Bundle identifier (e.g. 'com.apple.TextEdit')" })),
|
|
@@ -310,9 +305,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
310
305
|
"Quit a running macOS application. " +
|
|
311
306
|
"Returns { quit, name } on success. Errors if the app is not running. " +
|
|
312
307
|
"Provide either 'name' or 'bundleId'.",
|
|
313
|
-
promptGuidelines: [
|
|
314
|
-
"Use to clean up apps launched during automation — don't leave apps running unnecessarily.",
|
|
315
|
-
],
|
|
308
|
+
promptGuidelines: [] as string[],
|
|
316
309
|
parameters: Type.Object({
|
|
317
310
|
name: Type.Optional(Type.String({ description: "Application name" })),
|
|
318
311
|
bundleId: Type.Optional(Type.String({ description: "Bundle identifier" })),
|
|
@@ -349,9 +342,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
349
342
|
"The windowId can be used with getWindowInfo for detailed inspection or with screenshotWindow for capture. " +
|
|
350
343
|
"Returns an empty array (not error) if the app is running but has no visible windows. " +
|
|
351
344
|
"Errors if the app is not running.",
|
|
352
|
-
promptGuidelines: [
|
|
353
|
-
"Use to get windowId values needed by mac_screenshot.",
|
|
354
|
-
],
|
|
345
|
+
promptGuidelines: [] as string[],
|
|
355
346
|
parameters: Type.Object({
|
|
356
347
|
app: Type.String({ description: "Application name (e.g. 'TextEdit') or bundle identifier (e.g. 'com.apple.TextEdit')" }),
|
|
357
348
|
}),
|
|
@@ -393,8 +384,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
393
384
|
"The 'app' param accepts an app name (e.g. 'Finder') or bundle ID (e.g. 'com.apple.Finder').",
|
|
394
385
|
promptGuidelines: [
|
|
395
386
|
"Prefer for targeted element search — use role/title/value criteria to narrow results.",
|
|
396
|
-
"Use
|
|
397
|
-
"Use mac_get_tree instead of mode:tree when you just need to understand app structure.",
|
|
387
|
+
"Use mac_get_tree instead of mode:tree for quick structure inspection.",
|
|
398
388
|
],
|
|
399
389
|
parameters: Type.Object({
|
|
400
390
|
app: Type.String({ description: "Application name or bundle identifier" }),
|
|
@@ -524,9 +514,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
524
514
|
"Each line: `role \"title\" [value]` with 2-space indent per depth level. " +
|
|
525
515
|
"Omits title/value when nil or empty.",
|
|
526
516
|
promptGuidelines: [
|
|
527
|
-
"Use for understanding app UI structure — start with low limits and increase if needed.",
|
|
528
517
|
"Prefer mac_find search mode when you know what you're looking for.",
|
|
529
|
-
"Check the truncation note to know if the tree was cut short.",
|
|
530
518
|
],
|
|
531
519
|
parameters: Type.Object({
|
|
532
520
|
app: Type.String({ description: "Application name or bundle identifier" }),
|
|
@@ -581,8 +569,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
581
569
|
"Finds the first element matching the given criteria (role, title, value, identifier) and clicks it. " +
|
|
582
570
|
"At least one criterion is required. Returns the clicked element's attributes.",
|
|
583
571
|
promptGuidelines: [
|
|
584
|
-
"
|
|
585
|
-
"Use mac_find first to discover the right role/title/value criteria before clicking.",
|
|
572
|
+
"Use mac_find first to discover the right criteria before clicking.",
|
|
586
573
|
],
|
|
587
574
|
parameters: Type.Object({
|
|
588
575
|
app: Type.String({ description: "Application name or bundle identifier" }),
|
|
@@ -638,8 +625,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
638
625
|
"Returns the actual value after setting (read-back verification). " +
|
|
639
626
|
"At least one criterion is required.",
|
|
640
627
|
promptGuidelines: [
|
|
641
|
-
"
|
|
642
|
-
"Target text fields/areas by role (AXTextArea, AXTextField) for reliability.",
|
|
628
|
+
"Target text fields by role (AXTextArea, AXTextField) for reliability.",
|
|
643
629
|
],
|
|
644
630
|
parameters: Type.Object({
|
|
645
631
|
app: Type.String({ description: "Application name or bundle identifier" }),
|
|
@@ -697,9 +683,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
697
683
|
"Returns the screenshot as an image content block for visual analysis, alongside text metadata " +
|
|
698
684
|
"(dimensions and format). Requires Screen Recording permission — use mac_check_permissions to verify.",
|
|
699
685
|
promptGuidelines: [
|
|
700
|
-
"
|
|
701
|
-
"Prefer nominal resolution unless retina detail is needed — retina doubles payload size.",
|
|
702
|
-
"Requires Screen Recording permission — run mac_check_permissions first if screenshot fails.",
|
|
686
|
+
"Prefer nominal resolution; retina doubles payload. Run mac_check_permissions if it fails.",
|
|
703
687
|
],
|
|
704
688
|
parameters: Type.Object({
|
|
705
689
|
windowId: Type.Number({ description: "Window ID from mac_list_windows output" }),
|
|
@@ -747,9 +731,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
747
731
|
"Finds the first element matching the given criteria and reads the named attribute(s). " +
|
|
748
732
|
"AXValue subtypes (CGPoint, CGSize, CGRect, CFRange) are automatically unpacked to structured dicts. " +
|
|
749
733
|
"Use 'attribute' for a single attribute or 'attributes' for multiple. At least one search criterion is required.",
|
|
750
|
-
promptGuidelines: [
|
|
751
|
-
"Use to verify state after actions — read AXValue to confirm text was typed, AXEnabled to check if a button is active.",
|
|
752
|
-
],
|
|
734
|
+
promptGuidelines: [] as string[],
|
|
753
735
|
parameters: Type.Object({
|
|
754
736
|
app: Type.String({ description: "Application name or bundle identifier" }),
|
|
755
737
|
attribute: Type.Optional(Type.String({ description: "Single attribute name to read (e.g. 'AXValue', 'AXPosition', 'AXRole')" })),
|
|
@@ -824,8 +806,13 @@ export default function (pi: ExtensionAPI) {
|
|
|
824
806
|
|
|
825
807
|
// -----------------------------------------------------------------
|
|
826
808
|
// System prompt injection — mac-tools usage guidelines
|
|
809
|
+
// Only inject when mac tools are actually active.
|
|
827
810
|
// -----------------------------------------------------------------
|
|
828
811
|
pi.on("before_agent_start", async (event) => {
|
|
812
|
+
const activeTools = new Set(pi.getActiveTools());
|
|
813
|
+
const hasMacTools = [...activeTools].some((name) => name.startsWith("mac_"));
|
|
814
|
+
if (!hasMacTools) return;
|
|
815
|
+
|
|
829
816
|
const guidelines = `
|
|
830
817
|
|
|
831
818
|
[SYSTEM CONTEXT — Mac Tools]
|
|
@@ -834,18 +821,16 @@ export default function (pi: ExtensionAPI) {
|
|
|
834
821
|
|
|
835
822
|
You have mac-tools for controlling native macOS applications (Finder, TextEdit, Safari, Xcode, etc.) via Accessibility APIs.
|
|
836
823
|
|
|
837
|
-
**Mac-tools vs browser-tools:** Use mac-tools for native macOS apps. Use browser-tools for web pages inside a browser.
|
|
824
|
+
**Mac-tools vs browser-tools:** Use mac-tools for native macOS apps. Use browser-tools for web pages inside a browser.
|
|
838
825
|
|
|
839
|
-
**Permissions:** If any mac tool returns a permission error, run \`mac_check_permissions\` to diagnose.
|
|
826
|
+
**Permissions:** If any mac tool returns a permission error, run \`mac_check_permissions\` to diagnose.
|
|
840
827
|
|
|
841
828
|
**Interaction pattern — discover → act → verify:**
|
|
842
|
-
1. **Discover**
|
|
843
|
-
2. **Act** with \`mac_click\`
|
|
844
|
-
3. **Verify**
|
|
845
|
-
|
|
846
|
-
**Tree queries:** Start with default limits (mac_get_tree: maxDepth:3, maxCount:50). Increase only if the element you need isn't visible in the output. Large trees waste context.
|
|
829
|
+
1. **Discover** with \`mac_find\` or \`mac_get_tree\`
|
|
830
|
+
2. **Act** with \`mac_click\` or \`mac_type\`
|
|
831
|
+
3. **Verify** with \`mac_read\` or \`mac_screenshot\`
|
|
847
832
|
|
|
848
|
-
|
|
833
|
+
Start with default tree limits (maxDepth:3, maxCount:50). Use \`mac_screenshot\` sparingly — the payload is large.`;
|
|
849
834
|
|
|
850
835
|
return { systemPrompt: event.systemPrompt + guidelines };
|
|
851
836
|
});
|
|
@@ -93,9 +93,29 @@ function truncateEntrypointContent(raw: string): {
|
|
|
93
93
|
* @param memoryDir Absolute path to the project's memory directory.
|
|
94
94
|
* @param entrypointContent The (possibly truncated) contents of MEMORY.md.
|
|
95
95
|
*/
|
|
96
|
-
function buildMemoryPrompt(memoryDir: string, entrypointContent: string): string {
|
|
96
|
+
function buildMemoryPrompt(memoryDir: string, entrypointContent: string, hasMemories: boolean): string {
|
|
97
97
|
const sections: string[] = [];
|
|
98
98
|
|
|
99
|
+
if (!hasMemories) {
|
|
100
|
+
// Slim prompt when no memories exist — just enough to know the system is there
|
|
101
|
+
// and how to save the first memory. Full instructions are deferred until needed.
|
|
102
|
+
sections.push(`# Memory
|
|
103
|
+
|
|
104
|
+
You have a persistent, file-based memory system at \`${memoryDir}\`.
|
|
105
|
+
This directory already exists — write to it directly with the file write tool.
|
|
106
|
+
|
|
107
|
+
If the user explicitly asks you to remember something, save it immediately. If they ask you to forget, find and remove it.
|
|
108
|
+
|
|
109
|
+
To save a memory:
|
|
110
|
+
1. Write a markdown file to the memory directory with YAML frontmatter (name, description, type: user|feedback|project|reference)
|
|
111
|
+
2. Add a one-line pointer to MEMORY.md: \`- [Title](file.md) — one-line hook\`
|
|
112
|
+
|
|
113
|
+
Your MEMORY.md is currently empty.`);
|
|
114
|
+
return sections.join('\n\n');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ── Full prompt when memories exist ──
|
|
118
|
+
|
|
99
119
|
// ── Header ──
|
|
100
120
|
sections.push(`# Memory
|
|
101
121
|
|
|
@@ -196,7 +216,7 @@ export default function memoryExtension(pi: ExtensionAPI) {
|
|
|
196
216
|
entrypointContent = content;
|
|
197
217
|
}
|
|
198
218
|
|
|
199
|
-
const prompt = buildMemoryPrompt(memoryDir, entrypointContent);
|
|
219
|
+
const prompt = buildMemoryPrompt(memoryDir, entrypointContent, !!entrypointContent.trim());
|
|
200
220
|
|
|
201
221
|
return {
|
|
202
222
|
systemPrompt: event.systemPrompt + '\n\n' + prompt,
|