lsd-pi 1.2.4 → 1.3.2
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/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/plan.js +18 -17
- 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 +11 -6
- package/dist/resources/extensions/subagent/background-runner.js +4 -0
- package/dist/resources/extensions/subagent/index.js +714 -21
- package/dist/resources/extensions/subagent/launch-helpers.js +19 -5
- 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 +9 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +89 -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 +110 -4
- 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 +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +0 -2
- package/packages/pi-ai/dist/providers/openai-codex-responses.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 +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- 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 +0 -1
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +1 -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.ts +1 -3
- package/packages/pi-ai/src/providers/openai-completions.ts +1 -2
- package/packages/pi-ai/src/providers/openai-responses.ts +1 -1
- package/packages/pi-ai/src/providers/openai-shared.ts +0 -3
- package/packages/pi-ai/src/providers/simple-options.ts +0 -1
- package/packages/pi-ai/src/types.ts +1 -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/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 +32 -6
- 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 +12 -7
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +20 -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.js +1 -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 +6 -2
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- 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/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.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +12 -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 +7 -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 +23 -4
- 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/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +9 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- 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 +53 -2
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.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/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 +35 -6
- package/packages/pi-coding-agent/src/core/session-manager.ts +12 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +32 -9
- package/packages/pi-coding-agent/src/core/skills.ts +4 -1
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -2
- 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/embedded-terminal.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +10 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +31 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/thinking-selector.ts +1 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +9 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +65 -3
- 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/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/plan.ts +18 -19
- 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 +29 -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/index.ts +834 -19
- package/src/resources/extensions/subagent/launch-helpers.ts +15 -4
|
@@ -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
|
};
|
|
@@ -29,9 +29,23 @@ import { makeUI, INDENT } from "./ui.js";
|
|
|
29
29
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
30
30
|
const OTHER_OPTION_LABEL = "None of the above";
|
|
31
31
|
const OTHER_OPTION_DESCRIPTION = "Select to type your own answer.";
|
|
32
|
+
function matchesShowWhen(question, answers) {
|
|
33
|
+
if (!question.showWhen)
|
|
34
|
+
return true;
|
|
35
|
+
const controlling = answers[question.showWhen.questionId];
|
|
36
|
+
if (!controlling)
|
|
37
|
+
return false;
|
|
38
|
+
const selected = Array.isArray(controlling.selected)
|
|
39
|
+
? controlling.selected
|
|
40
|
+
: [controlling.selected];
|
|
41
|
+
return selected.some((value) => question.showWhen?.selectedAnyOf.includes(value));
|
|
42
|
+
}
|
|
32
43
|
async function runSequentialInterviewFallback(questions, ctx) {
|
|
33
44
|
const answers = {};
|
|
34
45
|
for (const q of questions) {
|
|
46
|
+
if (!matchesShowWhen(q, answers)) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
35
49
|
const options = q.options.map((o) => o.label);
|
|
36
50
|
if (!q.allowMultiple) {
|
|
37
51
|
options.push(OTHER_OPTION_LABEL);
|
|
@@ -147,7 +161,6 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
147
161
|
notes: "",
|
|
148
162
|
notesVisible: false,
|
|
149
163
|
}));
|
|
150
|
-
const isMultiQuestion = questions.length > 1;
|
|
151
164
|
let currentIdx = 0;
|
|
152
165
|
let focusNotes = false;
|
|
153
166
|
let showingReview = false;
|
|
@@ -181,13 +194,65 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
181
194
|
function loadStateToEditor() {
|
|
182
195
|
getEditor().setText(states[currentIdx].notes);
|
|
183
196
|
}
|
|
197
|
+
function selectedLabelsForIndex(idx) {
|
|
198
|
+
if (isMultiSelect(idx)) {
|
|
199
|
+
return Array.from(states[idx].checkedIndices).sort((a, b) => a - b).map((optionIdx) => questions[idx].options[optionIdx]?.label).filter((v) => !!v);
|
|
200
|
+
}
|
|
201
|
+
const committed = states[idx].committedIndex;
|
|
202
|
+
if (committed === null)
|
|
203
|
+
return [];
|
|
204
|
+
if (committed < questions[idx].options.length)
|
|
205
|
+
return [questions[idx].options[committed]?.label].filter((v) => !!v);
|
|
206
|
+
if (committed === noneOrDoneIdx(idx))
|
|
207
|
+
return [OTHER_OPTION_LABEL];
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
function visibleQuestionIndices() {
|
|
211
|
+
const visible = [];
|
|
212
|
+
for (let i = 0; i < questions.length; i++) {
|
|
213
|
+
const q = questions[i];
|
|
214
|
+
if (!q.showWhen) {
|
|
215
|
+
visible.push(i);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const controllingIdx = questions.findIndex((candidate) => candidate.id === q.showWhen?.questionId);
|
|
219
|
+
if (controllingIdx < 0 || !visible.includes(controllingIdx))
|
|
220
|
+
continue;
|
|
221
|
+
const selected = selectedLabelsForIndex(controllingIdx);
|
|
222
|
+
if (selected.some((label) => q.showWhen?.selectedAnyOf.includes(label))) {
|
|
223
|
+
visible.push(i);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return visible;
|
|
227
|
+
}
|
|
184
228
|
function isQuestionAnswered(idx) {
|
|
185
229
|
if (isMultiSelect(idx))
|
|
186
230
|
return states[idx].checkedIndices.size > 0;
|
|
187
231
|
return states[idx].committedIndex !== null;
|
|
188
232
|
}
|
|
189
233
|
function allAnswered() {
|
|
190
|
-
|
|
234
|
+
const visible = visibleQuestionIndices();
|
|
235
|
+
return visible.length > 0 && visible.every((i) => isQuestionAnswered(i));
|
|
236
|
+
}
|
|
237
|
+
function clearQuestionState(idx) {
|
|
238
|
+
states[idx].cursorIndex = 0;
|
|
239
|
+
states[idx].committedIndex = null;
|
|
240
|
+
states[idx].checkedIndices.clear();
|
|
241
|
+
states[idx].notes = "";
|
|
242
|
+
states[idx].notesVisible = false;
|
|
243
|
+
}
|
|
244
|
+
function reconcileVisibility() {
|
|
245
|
+
const visible = new Set(visibleQuestionIndices());
|
|
246
|
+
for (let i = 0; i < questions.length; i++) {
|
|
247
|
+
if (!visible.has(i))
|
|
248
|
+
clearQuestionState(i);
|
|
249
|
+
}
|
|
250
|
+
if (!visible.has(currentIdx)) {
|
|
251
|
+
const fallback = visibleQuestionIndices()[0] ?? 0;
|
|
252
|
+
currentIdx = fallback;
|
|
253
|
+
loadStateToEditor();
|
|
254
|
+
focusNotes = false;
|
|
255
|
+
}
|
|
191
256
|
}
|
|
192
257
|
function switchQuestion(newIdx) {
|
|
193
258
|
if (newIdx === currentIdx)
|
|
@@ -200,7 +265,10 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
200
265
|
}
|
|
201
266
|
function buildResult() {
|
|
202
267
|
const answers = {};
|
|
268
|
+
const visible = new Set(visibleQuestionIndices());
|
|
203
269
|
for (let i = 0; i < questions.length; i++) {
|
|
270
|
+
if (!visible.has(i))
|
|
271
|
+
continue;
|
|
204
272
|
const q = questions[i];
|
|
205
273
|
const st = states[i];
|
|
206
274
|
const notes = st.notes.trim();
|
|
@@ -234,6 +302,7 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
234
302
|
if (!isMultiSelect(currentIdx)) {
|
|
235
303
|
states[currentIdx].committedIndex = states[currentIdx].cursorIndex;
|
|
236
304
|
}
|
|
305
|
+
reconcileVisibility();
|
|
237
306
|
// Auto-open the notes field when "None of the above" is selected
|
|
238
307
|
// so the user can immediately provide a free-text explanation
|
|
239
308
|
// instead of being trapped in a re-asking loop (bug #2715).
|
|
@@ -245,10 +314,13 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
245
314
|
refresh();
|
|
246
315
|
return;
|
|
247
316
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
317
|
+
const visible = visibleQuestionIndices();
|
|
318
|
+
const currentVisiblePos = visible.indexOf(currentIdx);
|
|
319
|
+
const isMultiQuestion = visible.length > 1;
|
|
320
|
+
if (isMultiQuestion && currentVisiblePos >= 0 && currentVisiblePos < visible.length - 1) {
|
|
321
|
+
let next = visible[currentVisiblePos + 1] ?? visible[0] ?? currentIdx;
|
|
322
|
+
for (let i = 0; i < visible.length; i++) {
|
|
323
|
+
const candidate = visible[(currentVisiblePos + 1 + i) % visible.length] ?? currentIdx;
|
|
252
324
|
if (!isQuestionAnswered(candidate)) {
|
|
253
325
|
next = candidate;
|
|
254
326
|
break;
|
|
@@ -306,7 +378,8 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
306
378
|
if (showingReview) {
|
|
307
379
|
if (matchesKey(data, Key.escape) || matchesKey(data, Key.left)) {
|
|
308
380
|
showingReview = false;
|
|
309
|
-
|
|
381
|
+
const visible = visibleQuestionIndices();
|
|
382
|
+
switchQuestion(visible[visible.length - 1] ?? 0);
|
|
310
383
|
return;
|
|
311
384
|
}
|
|
312
385
|
if (matchesKey(data, Key.enter) || matchesKey(data, Key.right) || matchesKey(data, Key.space)) {
|
|
@@ -355,14 +428,19 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
355
428
|
return;
|
|
356
429
|
}
|
|
357
430
|
// ── Multi-question navigation ────────────────────────────────
|
|
431
|
+
const visible = visibleQuestionIndices();
|
|
432
|
+
const isMultiQuestion = visible.length > 1;
|
|
358
433
|
if (isMultiQuestion) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
434
|
+
const visiblePos = visible.indexOf(currentIdx);
|
|
435
|
+
if (visiblePos >= 0) {
|
|
436
|
+
if (matchesKey(data, Key.left)) {
|
|
437
|
+
switchQuestion(visible[(visiblePos - 1 + visible.length) % visible.length] ?? currentIdx);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (matchesKey(data, Key.right)) {
|
|
441
|
+
switchQuestion(visible[(visiblePos + 1) % visible.length] ?? currentIdx);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
366
444
|
}
|
|
367
445
|
}
|
|
368
446
|
// ── Cursor navigation ────────────────────────────────────────
|
|
@@ -435,7 +513,8 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
435
513
|
const push = (...rows) => { for (const r of rows)
|
|
436
514
|
lines.push(...r); };
|
|
437
515
|
push(ui.bar(), ui.blank(), ui.header(` ${opts.reviewHeadline ?? "Review your answers"}`), ui.blank());
|
|
438
|
-
|
|
516
|
+
const visible = visibleQuestionIndices();
|
|
517
|
+
for (const i of visible) {
|
|
439
518
|
const q = questions[i];
|
|
440
519
|
const st = states[i];
|
|
441
520
|
push(ui.subtitle(` ${q.question}`));
|
|
@@ -501,19 +580,23 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
501
580
|
const lines = [];
|
|
502
581
|
const push = (...rows) => { for (const r of rows)
|
|
503
582
|
lines.push(...r); };
|
|
583
|
+
reconcileVisibility();
|
|
584
|
+
const visible = visibleQuestionIndices();
|
|
585
|
+
const isMultiQuestion = visible.length > 1;
|
|
586
|
+
const visiblePos = Math.max(visible.indexOf(currentIdx), 0);
|
|
504
587
|
const q = questions[currentIdx];
|
|
505
588
|
const st = states[currentIdx];
|
|
506
589
|
const multiSel = isMultiSelect(currentIdx);
|
|
507
590
|
push(ui.bar());
|
|
508
591
|
// ── Progress header ────────────────────────────────────────────
|
|
509
592
|
if (isMultiQuestion) {
|
|
510
|
-
const unanswered =
|
|
511
|
-
const answeredSet = new Set(
|
|
512
|
-
push(ui.questionTabs(
|
|
593
|
+
const unanswered = visible.filter((i) => !isQuestionAnswered(i)).length;
|
|
594
|
+
const answeredSet = new Set(visible.map((i, visibleIndex) => (isQuestionAnswered(i) ? visibleIndex : -1)).filter((i) => i >= 0));
|
|
595
|
+
push(ui.questionTabs(visible.map((i) => questions[i]?.header ?? ""), visiblePos, answeredSet));
|
|
513
596
|
push(ui.blank());
|
|
514
597
|
const progressParts = [
|
|
515
598
|
opts.progress,
|
|
516
|
-
`Question ${
|
|
599
|
+
`Question ${visiblePos + 1}/${visible.length}`,
|
|
517
600
|
unanswered > 0 ? `${unanswered} unanswered` : null,
|
|
518
601
|
].filter(Boolean).join(" • ");
|
|
519
602
|
if (progressParts)
|
|
@@ -582,7 +665,7 @@ export async function showInterviewRound(questions, opts, ctx) {
|
|
|
582
665
|
}
|
|
583
666
|
// ── Footer hints ───────────────────────────────────────────────
|
|
584
667
|
push(ui.blank());
|
|
585
|
-
const isLast = !isMultiQuestion ||
|
|
668
|
+
const isLast = !isMultiQuestion || visiblePos === visible.length - 1;
|
|
586
669
|
const hints = [];
|
|
587
670
|
if (focusNotes) {
|
|
588
671
|
hints.push("enter to confirm");
|
|
@@ -395,25 +395,18 @@ function buildNewSessionOptionLabel() {
|
|
|
395
395
|
return `${APPROVE_LABEL} — ${APPROVE_NEW_SESSION_LABEL} (${suffix})`;
|
|
396
396
|
}
|
|
397
397
|
function buildApprovalActionInstructions() {
|
|
398
|
-
return [
|
|
399
|
-
"Ask for plan approval now using ask_user_questions.",
|
|
400
|
-
`One single-select question with id \"${PLAN_APPROVAL_ACTION_QUESTION_ID}\". Ask what to do next with the plan.`,
|
|
401
|
-
`Options: ${APPROVE_LABEL}, ${REVIEW_LABEL}, ${REVISE_LABEL}.`,
|
|
402
|
-
`Do not include \"${CANCEL_LABEL}\" as an explicit option — if the user wants to cancel they should choose \"None of the above\" and type \"${CANCEL_LABEL}\" in the note.`,
|
|
403
|
-
"Do not restate the plan. Just show the question.",
|
|
404
|
-
].join(" ");
|
|
405
|
-
}
|
|
406
|
-
function buildApprovalModeInstructions() {
|
|
407
398
|
const autoSwitchEnabled = readAutoSwitchPlanModelSetting();
|
|
408
399
|
const showNewSessionOption = autoSwitchEnabled;
|
|
409
400
|
const newSessionLabel = buildNewSessionOptionLabel();
|
|
410
|
-
const options = showNewSessionOption
|
|
411
|
-
? `${APPROVE_AUTO_LABEL}, ${APPROVE_BYPASS_LABEL}, ${APPROVE_AUTO_SUBAGENT_LABEL}, ${APPROVE_BYPASS_SUBAGENT_LABEL}, ${newSessionLabel}`
|
|
412
|
-
: `${APPROVE_AUTO_LABEL}, ${APPROVE_BYPASS_LABEL}, ${APPROVE_AUTO_SUBAGENT_LABEL}, ${APPROVE_BYPASS_SUBAGENT_LABEL}`;
|
|
413
401
|
return [
|
|
414
|
-
"
|
|
415
|
-
`
|
|
416
|
-
`
|
|
402
|
+
"Ask for plan approval now via exactly one ask_user_questions tool call.",
|
|
403
|
+
`Question 1 (single-select) id \"${PLAN_APPROVAL_ACTION_QUESTION_ID}\": ask what to do next with the plan.`,
|
|
404
|
+
`Question 1 options: ${APPROVE_LABEL}, ${REVIEW_LABEL}, ${REVISE_LABEL}. Put "${APPROVE_LABEL}" first with a "(Recommended)" suffix in the description, not in the label.`,
|
|
405
|
+
`Do not include \"${CANCEL_LABEL}\" as an explicit option — if the user wants to cancel they should choose \"None of the above\" and type \"${CANCEL_LABEL}\" in the note.`,
|
|
406
|
+
`Question 2 (single-select) id \"${PLAN_APPROVAL_PERMISSION_QUESTION_ID}\": ask which execution mode to use.`,
|
|
407
|
+
`Question 2 options: ${APPROVE_AUTO_LABEL} (Recommended), ${APPROVE_BYPASS_LABEL}, ${APPROVE_AUTO_SUBAGENT_LABEL}, ${APPROVE_BYPASS_SUBAGENT_LABEL}${showNewSessionOption ? `, ${newSessionLabel}` : ""}.`,
|
|
408
|
+
`Set question 2 showWhen.questionId to \"${PLAN_APPROVAL_ACTION_QUESTION_ID}\" and showWhen.selectedAnyOf to [\"${APPROVE_LABEL}\"] so it appears only when the user selects Approve plan.`,
|
|
409
|
+
"Do not restate the plan in a normal assistant response. Just call ask_user_questions.",
|
|
417
410
|
].join(" ");
|
|
418
411
|
}
|
|
419
412
|
// Keep for external callers that reference the combined form (headless path)
|
|
@@ -679,8 +672,16 @@ export default function planCommand(pi) {
|
|
|
679
672
|
if (!actionSelection)
|
|
680
673
|
return;
|
|
681
674
|
if (actionSelection.includes(APPROVE_LABEL)) {
|
|
682
|
-
|
|
683
|
-
|
|
675
|
+
const executionMode = approvalSelectionToExecutionMode(permissionValues[0]) ?? {
|
|
676
|
+
permissionMode: DEFAULT_APPROVAL_PERMISSION_MODE,
|
|
677
|
+
executeWithSubagent: false,
|
|
678
|
+
};
|
|
679
|
+
state = { ...state, targetPermissionMode: executionMode.permissionMode };
|
|
680
|
+
if (executionMode.executeWithSubagent) {
|
|
681
|
+
const modeLabel = executionMode.permissionMode === "danger-full-access" ? "bypass" : "auto";
|
|
682
|
+
ctx.ui?.notify?.(`Plan approved: subagent(${modeLabel})`, "info");
|
|
683
|
+
}
|
|
684
|
+
await approvePlan(pi, ctx, executionMode.permissionMode, executionMode.executeWithSubagent);
|
|
684
685
|
return;
|
|
685
686
|
}
|
|
686
687
|
if (actionSelection.includes(REVIEW_LABEL)) {
|
|
@@ -37,6 +37,30 @@ function getBalancedToolNames(activeToolNames) {
|
|
|
37
37
|
"ask_user_questions",
|
|
38
38
|
];
|
|
39
39
|
}
|
|
40
|
+
const STANDARD_TOOLS = [
|
|
41
|
+
// Core
|
|
42
|
+
"read", "bash", "edit", "write", "lsp", "grep", "find", "ls",
|
|
43
|
+
// Background
|
|
44
|
+
"bg_shell",
|
|
45
|
+
// Search
|
|
46
|
+
"web_search", "fetch_page",
|
|
47
|
+
// Docs
|
|
48
|
+
"resolve_library", "get_library_docs",
|
|
49
|
+
// Agent
|
|
50
|
+
"subagent", "await_subagent", "Skill",
|
|
51
|
+
// User interaction
|
|
52
|
+
"ask_user_questions", "secure_env_collect",
|
|
53
|
+
// Browser (essential)
|
|
54
|
+
"browser_navigate", "browser_click", "browser_type", "browser_screenshot",
|
|
55
|
+
"browser_scroll", "browser_key_press", "browser_evaluate",
|
|
56
|
+
"browser_find", "browser_wait_for", "browser_close",
|
|
57
|
+
"browser_assert", "browser_batch",
|
|
58
|
+
// Tool management
|
|
59
|
+
"tool_search", "tool_enable",
|
|
60
|
+
];
|
|
61
|
+
function getStandardToolNames() {
|
|
62
|
+
return [...STANDARD_TOOLS];
|
|
63
|
+
}
|
|
40
64
|
function getFullToolNames(pi) {
|
|
41
65
|
return pi.getAllTools().map((tool) => tool.name).filter((name) => Boolean(name));
|
|
42
66
|
}
|
|
@@ -168,7 +192,8 @@ export default function toolSearchExtension(pi) {
|
|
|
168
192
|
currentActive.length > 0 ? currentActive.join(", ") : "(none)",
|
|
169
193
|
"",
|
|
170
194
|
"Usage:",
|
|
171
|
-
" /tools balanced Switch to the balanced tool profile",
|
|
195
|
+
" /tools balanced Switch to the balanced tool profile (12 tools)",
|
|
196
|
+
" /tools standard Switch to the standard tool profile (~32 tools)",
|
|
172
197
|
" /tools full Switch to the full tool profile (all available tools)",
|
|
173
198
|
" /tools on Alias for /tools full",
|
|
174
199
|
" /tools off Alias for /tools balanced",
|
|
@@ -183,7 +208,18 @@ export default function toolSearchExtension(pi) {
|
|
|
183
208
|
pi.setActiveTools(nextActive);
|
|
184
209
|
pi.sendMessage({
|
|
185
210
|
customType: "tools:mode",
|
|
186
|
-
content: `Balanced tool profile active: ${pi.getActiveTools().join(", ")}`,
|
|
211
|
+
content: `Balanced tool profile active (${pi.getActiveTools().length} tools): ${pi.getActiveTools().join(", ")}`,
|
|
212
|
+
display: true,
|
|
213
|
+
});
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (input === "standard") {
|
|
217
|
+
settings.setToolProfile("standard");
|
|
218
|
+
const nextActive = getStandardToolNames();
|
|
219
|
+
pi.setActiveTools(nextActive);
|
|
220
|
+
pi.sendMessage({
|
|
221
|
+
customType: "tools:mode",
|
|
222
|
+
content: `Standard tool profile active (${pi.getActiveTools().length} tools): ${pi.getActiveTools().join(", ")}`,
|
|
187
223
|
display: true,
|
|
188
224
|
});
|
|
189
225
|
return;
|
|
@@ -194,14 +230,14 @@ export default function toolSearchExtension(pi) {
|
|
|
194
230
|
pi.setActiveTools(nextActive);
|
|
195
231
|
pi.sendMessage({
|
|
196
232
|
customType: "tools:mode",
|
|
197
|
-
content: `Full tool profile active: ${pi.getActiveTools().join(", ")}`,
|
|
233
|
+
content: `Full tool profile active (${pi.getActiveTools().length} tools): ${pi.getActiveTools().join(", ")}`,
|
|
198
234
|
display: true,
|
|
199
235
|
});
|
|
200
236
|
return;
|
|
201
237
|
}
|
|
202
238
|
pi.sendMessage({
|
|
203
239
|
customType: "tools:help",
|
|
204
|
-
content: `Unknown /tools subcommand: ${input}\n\nTry /tools, /tools balanced, /tools full, /tools on, or /tools off.`,
|
|
240
|
+
content: `Unknown /tools subcommand: ${input}\n\nTry /tools, /tools balanced, /tools standard, /tools full, /tools on, or /tools off.`,
|
|
205
241
|
display: true,
|
|
206
242
|
});
|
|
207
243
|
},
|