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
|
@@ -1,180 +1,117 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
2
|
/**
|
|
3
|
-
* State persistence
|
|
3
|
+
* State persistence — save/restore cookies, localStorage, sessionStorage.
|
|
4
4
|
*/
|
|
5
5
|
const STATE_DIR = ".gsd/browser-state";
|
|
6
6
|
export function registerStatePersistenceTools(pi, deps) {
|
|
7
|
-
// -------------------------------------------------------------------------
|
|
8
|
-
// browser_save_state
|
|
9
|
-
// -------------------------------------------------------------------------
|
|
10
7
|
pi.registerTool({
|
|
11
|
-
name: "
|
|
12
|
-
label: "Browser
|
|
13
|
-
description: "Save cookies, localStorage,
|
|
14
|
-
"State files
|
|
15
|
-
"Never displays secret values in output.",
|
|
8
|
+
name: "browser_state",
|
|
9
|
+
label: "Browser State",
|
|
10
|
+
description: "Save or restore browser state (cookies, localStorage, sessionStorage) to persist sessions across browser restarts. " +
|
|
11
|
+
"State files written to .gsd/browser-state/ (should be gitignored).",
|
|
16
12
|
parameters: Type.Object({
|
|
17
|
-
|
|
13
|
+
action: Type.Union([
|
|
14
|
+
Type.Literal("save"),
|
|
15
|
+
Type.Literal("restore"),
|
|
16
|
+
], { description: "'save' — persist current state, 'restore' — load previously saved state" }),
|
|
17
|
+
name: Type.Optional(Type.String({ description: "State file name (default: 'default'). Used as filename stem." })),
|
|
18
18
|
}),
|
|
19
19
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
20
20
|
try {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const { mkdir, writeFile } = await import("node:fs/promises");
|
|
24
|
-
const path = await import("node:path");
|
|
25
|
-
const stateDir = path.resolve(process.cwd(), STATE_DIR);
|
|
26
|
-
await mkdir(stateDir, { recursive: true });
|
|
27
|
-
// 1. Playwright storageState: cookies + localStorage
|
|
28
|
-
const storageState = await ctx.storageState();
|
|
29
|
-
// 2. sessionStorage: must be extracted per-origin via page.evaluate
|
|
30
|
-
const sessionStorageData = {};
|
|
31
|
-
try {
|
|
32
|
-
const origin = new URL(p.url()).origin;
|
|
33
|
-
const ssData = await p.evaluate(() => {
|
|
34
|
-
const data = {};
|
|
35
|
-
for (let i = 0; i < sessionStorage.length; i++) {
|
|
36
|
-
const key = sessionStorage.key(i);
|
|
37
|
-
if (key)
|
|
38
|
-
data[key] = sessionStorage.getItem(key) ?? "";
|
|
39
|
-
}
|
|
40
|
-
return data;
|
|
41
|
-
});
|
|
42
|
-
if (Object.keys(ssData).length > 0) {
|
|
43
|
-
sessionStorageData[origin] = ssData;
|
|
44
|
-
}
|
|
21
|
+
if (params.action === "save") {
|
|
22
|
+
return await saveState(deps, params.name ?? "default");
|
|
45
23
|
}
|
|
46
|
-
|
|
47
|
-
|
|
24
|
+
else {
|
|
25
|
+
return await restoreState(deps, params.name ?? "default");
|
|
48
26
|
}
|
|
49
|
-
const combined = {
|
|
50
|
-
storageState,
|
|
51
|
-
sessionStorage: sessionStorageData,
|
|
52
|
-
savedAt: new Date().toISOString(),
|
|
53
|
-
url: p.url(),
|
|
54
|
-
};
|
|
55
|
-
const filePath = path.join(stateDir, `${name}.json`);
|
|
56
|
-
await writeFile(filePath, JSON.stringify(combined, null, 2));
|
|
57
|
-
// Ensure .gitignore covers the state dir
|
|
58
|
-
const gitignorePath = path.resolve(process.cwd(), STATE_DIR, ".gitignore");
|
|
59
|
-
await writeFile(gitignorePath, "*\n!.gitignore\n").catch(() => { });
|
|
60
|
-
const cookieCount = storageState.cookies?.length ?? 0;
|
|
61
|
-
const localStorageOrigins = storageState.origins?.length ?? 0;
|
|
62
|
-
const sessionStorageOrigins = Object.keys(sessionStorageData).length;
|
|
63
|
-
return {
|
|
64
|
-
content: [{
|
|
65
|
-
type: "text",
|
|
66
|
-
text: `State saved: ${filePath}\nCookies: ${cookieCount}\nlocalStorage origins: ${localStorageOrigins}\nsessionStorage origins: ${sessionStorageOrigins}`,
|
|
67
|
-
}],
|
|
68
|
-
details: {
|
|
69
|
-
path: filePath,
|
|
70
|
-
cookieCount,
|
|
71
|
-
localStorageOrigins,
|
|
72
|
-
sessionStorageOrigins,
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
27
|
}
|
|
76
28
|
catch (err) {
|
|
77
29
|
return {
|
|
78
|
-
content: [{ type: "text", text: `
|
|
30
|
+
content: [{ type: "text", text: `State '${params.action}' failed: ${err.message}` }],
|
|
79
31
|
details: { error: err.message },
|
|
80
32
|
isError: true,
|
|
81
33
|
};
|
|
82
34
|
}
|
|
83
35
|
},
|
|
84
36
|
});
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const path = await import("node:path");
|
|
103
|
-
const filePath = path.join(process.cwd(), STATE_DIR, `${name}.json`);
|
|
104
|
-
let raw;
|
|
105
|
-
try {
|
|
106
|
-
raw = await readFile(filePath, "utf-8");
|
|
107
|
-
}
|
|
108
|
-
catch {
|
|
109
|
-
return {
|
|
110
|
-
content: [{ type: "text", text: `State file not found: ${filePath}` }],
|
|
111
|
-
details: { error: "file_not_found", path: filePath },
|
|
112
|
-
isError: true,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
const combined = JSON.parse(raw);
|
|
116
|
-
const storageState = combined.storageState;
|
|
117
|
-
const sessionStorageData = combined.sessionStorage ?? {};
|
|
118
|
-
// 1. Restore cookies
|
|
119
|
-
let cookieCount = 0;
|
|
120
|
-
if (storageState?.cookies?.length) {
|
|
121
|
-
await ctx.addCookies(storageState.cookies);
|
|
122
|
-
cookieCount = storageState.cookies.length;
|
|
37
|
+
async function saveState(deps, name) {
|
|
38
|
+
const { context: ctx, page: p } = await deps.ensureBrowser();
|
|
39
|
+
name = deps.sanitizeArtifactName(name, "default");
|
|
40
|
+
const { mkdir, writeFile } = await import("node:fs/promises");
|
|
41
|
+
const path = await import("node:path");
|
|
42
|
+
const stateDir = path.resolve(process.cwd(), STATE_DIR);
|
|
43
|
+
await mkdir(stateDir, { recursive: true });
|
|
44
|
+
const storageState = await ctx.storageState();
|
|
45
|
+
const sessionStorageData = {};
|
|
46
|
+
try {
|
|
47
|
+
const origin = new URL(p.url()).origin;
|
|
48
|
+
const ssData = await p.evaluate(() => {
|
|
49
|
+
const data = {};
|
|
50
|
+
for (let i = 0; i < sessionStorage.length; i++) {
|
|
51
|
+
const key = sessionStorage.key(i);
|
|
52
|
+
if (key)
|
|
53
|
+
data[key] = sessionStorage.getItem(key) ?? "";
|
|
123
54
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
55
|
+
return data;
|
|
56
|
+
});
|
|
57
|
+
if (Object.keys(ssData).length > 0)
|
|
58
|
+
sessionStorageData[origin] = ssData;
|
|
59
|
+
}
|
|
60
|
+
catch { /* Page may not have a valid origin */ }
|
|
61
|
+
const combined = { storageState, sessionStorage: sessionStorageData, savedAt: new Date().toISOString(), url: p.url() };
|
|
62
|
+
const filePath = path.join(stateDir, `${name}.json`);
|
|
63
|
+
await writeFile(filePath, JSON.stringify(combined, null, 2));
|
|
64
|
+
const gitignorePath = path.resolve(process.cwd(), STATE_DIR, ".gitignore");
|
|
65
|
+
await writeFile(gitignorePath, "*\n!.gitignore\n").catch(() => { });
|
|
66
|
+
return {
|
|
67
|
+
content: [{ type: "text", text: `State saved: ${filePath}\nCookies: ${storageState.cookies?.length ?? 0}\nlocalStorage origins: ${storageState.origins?.length ?? 0}\nsessionStorage origins: ${Object.keys(sessionStorageData).length}` }],
|
|
68
|
+
details: { path: filePath, cookieCount: storageState.cookies?.length ?? 0, localStorageOrigins: storageState.origins?.length ?? 0, sessionStorageOrigins: Object.keys(sessionStorageData).length },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async function restoreState(deps, name) {
|
|
72
|
+
const { context: ctx, page: p } = await deps.ensureBrowser();
|
|
73
|
+
name = deps.sanitizeArtifactName(name, "default");
|
|
74
|
+
const { readFile } = await import("node:fs/promises");
|
|
75
|
+
const path = await import("node:path");
|
|
76
|
+
const filePath = path.join(process.cwd(), STATE_DIR, `${name}.json`);
|
|
77
|
+
let raw;
|
|
78
|
+
try {
|
|
79
|
+
raw = await readFile(filePath, "utf-8");
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return { content: [{ type: "text", text: `State file not found: ${filePath}` }], details: { error: "file_not_found", path: filePath }, isError: true };
|
|
83
|
+
}
|
|
84
|
+
const combined = JSON.parse(raw);
|
|
85
|
+
const storageState = combined.storageState;
|
|
86
|
+
const sessionStorageData = combined.sessionStorage ?? {};
|
|
87
|
+
let cookieCount = 0;
|
|
88
|
+
if (storageState?.cookies?.length) {
|
|
89
|
+
await ctx.addCookies(storageState.cookies);
|
|
90
|
+
cookieCount = storageState.cookies.length;
|
|
91
|
+
}
|
|
92
|
+
let localStorageOrigins = 0;
|
|
93
|
+
if (storageState?.origins?.length) {
|
|
94
|
+
for (const origin of storageState.origins) {
|
|
95
|
+
try {
|
|
96
|
+
await p.evaluate((items) => { for (const { name, value } of items)
|
|
97
|
+
localStorage.setItem(name, value); }, origin.localStorage ?? []);
|
|
98
|
+
localStorageOrigins++;
|
|
155
99
|
}
|
|
156
|
-
|
|
157
|
-
content: [{
|
|
158
|
-
type: "text",
|
|
159
|
-
text: `State restored from: ${filePath}\nCookies: ${cookieCount}\nlocalStorage origins: ${localStorageOrigins}\nsessionStorage origins: ${sessionStorageOrigins}\nSaved at: ${combined.savedAt ?? "unknown"}`,
|
|
160
|
-
}],
|
|
161
|
-
details: {
|
|
162
|
-
path: filePath,
|
|
163
|
-
cookieCount,
|
|
164
|
-
localStorageOrigins,
|
|
165
|
-
sessionStorageOrigins,
|
|
166
|
-
savedAt: combined.savedAt,
|
|
167
|
-
savedUrl: combined.url,
|
|
168
|
-
},
|
|
169
|
-
};
|
|
100
|
+
catch { /* Origin mismatch */ }
|
|
170
101
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
102
|
+
}
|
|
103
|
+
let sessionStorageOrigins = 0;
|
|
104
|
+
for (const [_origin, data] of Object.entries(sessionStorageData)) {
|
|
105
|
+
try {
|
|
106
|
+
await p.evaluate((items) => { for (const [key, value] of Object.entries(items))
|
|
107
|
+
sessionStorage.setItem(key, value); }, data);
|
|
108
|
+
sessionStorageOrigins++;
|
|
177
109
|
}
|
|
178
|
-
|
|
179
|
-
|
|
110
|
+
catch { /* Origin mismatch */ }
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
content: [{ type: "text", text: `State restored from: ${filePath}\nCookies: ${cookieCount}\nlocalStorage origins: ${localStorageOrigins}\nsessionStorage origins: ${sessionStorageOrigins}` }],
|
|
114
|
+
details: { path: filePath, cookieCount, localStorageOrigins, sessionStorageOrigins, savedAt: combined.savedAt, savedUrl: combined.url },
|
|
115
|
+
};
|
|
116
|
+
}
|
|
180
117
|
}
|
|
@@ -463,7 +463,7 @@ export function formatVersionedRef(version, key) {
|
|
|
463
463
|
return `@v${version}:${key}`;
|
|
464
464
|
}
|
|
465
465
|
export function staleRefGuidance(refDisplay, reason) {
|
|
466
|
-
return `Ref ${refDisplay} could not be resolved (${reason}). The ref is likely stale after DOM/navigation changes. Call
|
|
466
|
+
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.`;
|
|
467
467
|
}
|
|
468
468
|
// ---------------------------------------------------------------------------
|
|
469
469
|
// Compact state summary formatting
|
|
@@ -173,9 +173,7 @@ export default function (pi) {
|
|
|
173
173
|
description: "List all running macOS applications. Returns an array of { name, bundleId, pid, isActive } " +
|
|
174
174
|
"for user-facing apps (regular activation policy). Set includeBackground to true to also " +
|
|
175
175
|
"include accessory/background apps.",
|
|
176
|
-
promptGuidelines: [
|
|
177
|
-
"Use to discover what apps are running before interacting with them.",
|
|
178
|
-
],
|
|
176
|
+
promptGuidelines: [],
|
|
179
177
|
parameters: Type.Object({
|
|
180
178
|
includeBackground: Type.Optional(Type.Boolean({ description: "Include background/accessory apps (default: false)" })),
|
|
181
179
|
}),
|
|
@@ -201,9 +199,6 @@ export default function (pi) {
|
|
|
201
199
|
description: "Launch a macOS application by name or bundle ID. " +
|
|
202
200
|
"Returns { launched, name, bundleId, pid } on success. " +
|
|
203
201
|
"Provide either 'name' (e.g. 'TextEdit') or 'bundleId' (e.g. 'com.apple.TextEdit').",
|
|
204
|
-
promptGuidelines: [
|
|
205
|
-
"Use app name for well-known apps; use bundleId when the name is ambiguous.",
|
|
206
|
-
],
|
|
207
202
|
parameters: Type.Object({
|
|
208
203
|
name: Type.Optional(Type.String({ description: "Application name (e.g. 'TextEdit', 'Safari')" })),
|
|
209
204
|
bundleId: Type.Optional(Type.String({ description: "Bundle identifier (e.g. 'com.apple.TextEdit')" })),
|
|
@@ -272,9 +267,7 @@ export default function (pi) {
|
|
|
272
267
|
description: "Quit a running macOS application. " +
|
|
273
268
|
"Returns { quit, name } on success. Errors if the app is not running. " +
|
|
274
269
|
"Provide either 'name' or 'bundleId'.",
|
|
275
|
-
promptGuidelines: [
|
|
276
|
-
"Use to clean up apps launched during automation — don't leave apps running unnecessarily.",
|
|
277
|
-
],
|
|
270
|
+
promptGuidelines: [],
|
|
278
271
|
parameters: Type.Object({
|
|
279
272
|
name: Type.Optional(Type.String({ description: "Application name" })),
|
|
280
273
|
bundleId: Type.Optional(Type.String({ description: "Bundle identifier" })),
|
|
@@ -309,9 +302,7 @@ export default function (pi) {
|
|
|
309
302
|
"The windowId can be used with getWindowInfo for detailed inspection or with screenshotWindow for capture. " +
|
|
310
303
|
"Returns an empty array (not error) if the app is running but has no visible windows. " +
|
|
311
304
|
"Errors if the app is not running.",
|
|
312
|
-
promptGuidelines: [
|
|
313
|
-
"Use to get windowId values needed by mac_screenshot.",
|
|
314
|
-
],
|
|
305
|
+
promptGuidelines: [],
|
|
315
306
|
parameters: Type.Object({
|
|
316
307
|
app: Type.String({ description: "Application name (e.g. 'TextEdit') or bundle identifier (e.g. 'com.apple.TextEdit')" }),
|
|
317
308
|
}),
|
|
@@ -348,8 +339,7 @@ export default function (pi) {
|
|
|
348
339
|
"The 'app' param accepts an app name (e.g. 'Finder') or bundle ID (e.g. 'com.apple.Finder').",
|
|
349
340
|
promptGuidelines: [
|
|
350
341
|
"Prefer for targeted element search — use role/title/value criteria to narrow results.",
|
|
351
|
-
"Use
|
|
352
|
-
"Use mac_get_tree instead of mode:tree when you just need to understand app structure.",
|
|
342
|
+
"Use mac_get_tree instead of mode:tree for quick structure inspection.",
|
|
353
343
|
],
|
|
354
344
|
parameters: Type.Object({
|
|
355
345
|
app: Type.String({ description: "Application name or bundle identifier" }),
|
|
@@ -470,9 +460,7 @@ export default function (pi) {
|
|
|
470
460
|
"Each line: `role \"title\" [value]` with 2-space indent per depth level. " +
|
|
471
461
|
"Omits title/value when nil or empty.",
|
|
472
462
|
promptGuidelines: [
|
|
473
|
-
"Use for understanding app UI structure — start with low limits and increase if needed.",
|
|
474
463
|
"Prefer mac_find search mode when you know what you're looking for.",
|
|
475
|
-
"Check the truncation note to know if the tree was cut short.",
|
|
476
464
|
],
|
|
477
465
|
parameters: Type.Object({
|
|
478
466
|
app: Type.String({ description: "Application name or bundle identifier" }),
|
|
@@ -522,8 +510,7 @@ export default function (pi) {
|
|
|
522
510
|
"Finds the first element matching the given criteria (role, title, value, identifier) and clicks it. " +
|
|
523
511
|
"At least one criterion is required. Returns the clicked element's attributes.",
|
|
524
512
|
promptGuidelines: [
|
|
525
|
-
"
|
|
526
|
-
"Use mac_find first to discover the right role/title/value criteria before clicking.",
|
|
513
|
+
"Use mac_find first to discover the right criteria before clicking.",
|
|
527
514
|
],
|
|
528
515
|
parameters: Type.Object({
|
|
529
516
|
app: Type.String({ description: "Application name or bundle identifier" }),
|
|
@@ -573,8 +560,7 @@ export default function (pi) {
|
|
|
573
560
|
"Returns the actual value after setting (read-back verification). " +
|
|
574
561
|
"At least one criterion is required.",
|
|
575
562
|
promptGuidelines: [
|
|
576
|
-
"
|
|
577
|
-
"Target text fields/areas by role (AXTextArea, AXTextField) for reliability.",
|
|
563
|
+
"Target text fields by role (AXTextArea, AXTextField) for reliability.",
|
|
578
564
|
],
|
|
579
565
|
parameters: Type.Object({
|
|
580
566
|
app: Type.String({ description: "Application name or bundle identifier" }),
|
|
@@ -625,9 +611,7 @@ export default function (pi) {
|
|
|
625
611
|
"Returns the screenshot as an image content block for visual analysis, alongside text metadata " +
|
|
626
612
|
"(dimensions and format). Requires Screen Recording permission — use mac_check_permissions to verify.",
|
|
627
613
|
promptGuidelines: [
|
|
628
|
-
"
|
|
629
|
-
"Prefer nominal resolution unless retina detail is needed — retina doubles payload size.",
|
|
630
|
-
"Requires Screen Recording permission — run mac_check_permissions first if screenshot fails.",
|
|
614
|
+
"Prefer nominal resolution; retina doubles payload. Run mac_check_permissions if it fails.",
|
|
631
615
|
],
|
|
632
616
|
parameters: Type.Object({
|
|
633
617
|
windowId: Type.Number({ description: "Window ID from mac_list_windows output" }),
|
|
@@ -672,9 +656,7 @@ export default function (pi) {
|
|
|
672
656
|
"Finds the first element matching the given criteria and reads the named attribute(s). " +
|
|
673
657
|
"AXValue subtypes (CGPoint, CGSize, CGRect, CFRange) are automatically unpacked to structured dicts. " +
|
|
674
658
|
"Use 'attribute' for a single attribute or 'attributes' for multiple. At least one search criterion is required.",
|
|
675
|
-
promptGuidelines: [
|
|
676
|
-
"Use to verify state after actions — read AXValue to confirm text was typed, AXEnabled to check if a button is active.",
|
|
677
|
-
],
|
|
659
|
+
promptGuidelines: [],
|
|
678
660
|
parameters: Type.Object({
|
|
679
661
|
app: Type.String({ description: "Application name or bundle identifier" }),
|
|
680
662
|
attribute: Type.Optional(Type.String({ description: "Single attribute name to read (e.g. 'AXValue', 'AXPosition', 'AXRole')" })),
|
|
@@ -741,8 +723,13 @@ export default function (pi) {
|
|
|
741
723
|
});
|
|
742
724
|
// -----------------------------------------------------------------
|
|
743
725
|
// System prompt injection — mac-tools usage guidelines
|
|
726
|
+
// Only inject when mac tools are actually active.
|
|
744
727
|
// -----------------------------------------------------------------
|
|
745
728
|
pi.on("before_agent_start", async (event) => {
|
|
729
|
+
const activeTools = new Set(pi.getActiveTools());
|
|
730
|
+
const hasMacTools = [...activeTools].some((name) => name.startsWith("mac_"));
|
|
731
|
+
if (!hasMacTools)
|
|
732
|
+
return;
|
|
746
733
|
const guidelines = `
|
|
747
734
|
|
|
748
735
|
[SYSTEM CONTEXT — Mac Tools]
|
|
@@ -751,18 +738,16 @@ export default function (pi) {
|
|
|
751
738
|
|
|
752
739
|
You have mac-tools for controlling native macOS applications (Finder, TextEdit, Safari, Xcode, etc.) via Accessibility APIs.
|
|
753
740
|
|
|
754
|
-
**Mac-tools vs browser-tools:** Use mac-tools for native macOS apps. Use browser-tools for web pages inside a browser.
|
|
741
|
+
**Mac-tools vs browser-tools:** Use mac-tools for native macOS apps. Use browser-tools for web pages inside a browser.
|
|
755
742
|
|
|
756
|
-
**Permissions:** If any mac tool returns a permission error, run \`mac_check_permissions\` to diagnose.
|
|
743
|
+
**Permissions:** If any mac tool returns a permission error, run \`mac_check_permissions\` to diagnose.
|
|
757
744
|
|
|
758
745
|
**Interaction pattern — discover → act → verify:**
|
|
759
|
-
1. **Discover**
|
|
760
|
-
2. **Act** with \`mac_click\`
|
|
761
|
-
3. **Verify**
|
|
762
|
-
|
|
763
|
-
**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.
|
|
746
|
+
1. **Discover** with \`mac_find\` or \`mac_get_tree\`
|
|
747
|
+
2. **Act** with \`mac_click\` or \`mac_type\`
|
|
748
|
+
3. **Verify** with \`mac_read\` or \`mac_screenshot\`
|
|
764
749
|
|
|
765
|
-
|
|
750
|
+
Start with default tree limits (maxDepth:3, maxCount:50). Use \`mac_screenshot\` sparingly — the payload is large.`;
|
|
766
751
|
return { systemPrompt: event.systemPrompt + guidelines };
|
|
767
752
|
});
|
|
768
753
|
}
|
|
@@ -63,8 +63,26 @@ function truncateEntrypointContent(raw) {
|
|
|
63
63
|
* @param memoryDir Absolute path to the project's memory directory.
|
|
64
64
|
* @param entrypointContent The (possibly truncated) contents of MEMORY.md.
|
|
65
65
|
*/
|
|
66
|
-
function buildMemoryPrompt(memoryDir, entrypointContent) {
|
|
66
|
+
function buildMemoryPrompt(memoryDir, entrypointContent, hasMemories) {
|
|
67
67
|
const sections = [];
|
|
68
|
+
if (!hasMemories) {
|
|
69
|
+
// Slim prompt when no memories exist — just enough to know the system is there
|
|
70
|
+
// and how to save the first memory. Full instructions are deferred until needed.
|
|
71
|
+
sections.push(`# Memory
|
|
72
|
+
|
|
73
|
+
You have a persistent, file-based memory system at \`${memoryDir}\`.
|
|
74
|
+
This directory already exists — write to it directly with the file write tool.
|
|
75
|
+
|
|
76
|
+
If the user explicitly asks you to remember something, save it immediately. If they ask you to forget, find and remove it.
|
|
77
|
+
|
|
78
|
+
To save a memory:
|
|
79
|
+
1. Write a markdown file to the memory directory with YAML frontmatter (name, description, type: user|feedback|project|reference)
|
|
80
|
+
2. Add a one-line pointer to MEMORY.md: \`- [Title](file.md) — one-line hook\`
|
|
81
|
+
|
|
82
|
+
Your MEMORY.md is currently empty.`);
|
|
83
|
+
return sections.join('\n\n');
|
|
84
|
+
}
|
|
85
|
+
// ── Full prompt when memories exist ──
|
|
68
86
|
// ── Header ──
|
|
69
87
|
sections.push(`# Memory
|
|
70
88
|
|
|
@@ -151,7 +169,7 @@ export default function memoryExtension(pi) {
|
|
|
151
169
|
const { content } = truncateEntrypointContent(entrypointContent);
|
|
152
170
|
entrypointContent = content;
|
|
153
171
|
}
|
|
154
|
-
const prompt = buildMemoryPrompt(memoryDir, entrypointContent);
|
|
172
|
+
const prompt = buildMemoryPrompt(memoryDir, entrypointContent, !!entrypointContent.trim());
|
|
155
173
|
return {
|
|
156
174
|
systemPrompt: event.systemPrompt + '\n\n' + prompt,
|
|
157
175
|
};
|