lsd-pi 1.3.2 → 1.3.7
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/dist/cli.js +2 -1
- package/dist/lsd-settings-manager.d.ts +2 -0
- package/dist/lsd-settings-manager.js +5 -0
- package/dist/resource-loader.js +33 -3
- 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/cache-timer/index.js +3 -2
- 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 +37 -12
- package/dist/resources/extensions/subagent/background-job-manager.js +13 -0
- package/dist/resources/extensions/subagent/in-process-runner.js +387 -0
- package/dist/resources/extensions/subagent/index.js +278 -626
- 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/welcome-screen.js +2 -2
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +19 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +16 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/src/agent.ts +32 -2
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +34 -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 +32 -4
- 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-responses.d.ts +8 -1
- 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/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +2 -0
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +5 -0
- 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/providers/openai-codex-responses.test.ts +143 -20
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +47 -4
- package/packages/pi-ai/src/providers/openai-responses.fast-mode.test.ts +73 -0
- package/packages/pi-ai/src/providers/openai-responses.ts +26 -3
- package/packages/pi-ai/src/providers/simple-options.ts +2 -0
- package/packages/pi-ai/src/types.ts +5 -0
- 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/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +4 -2
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.js +35 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +12 -0
- 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 +24 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.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 +1 -0
- 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 -1
- 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/edit-diff.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.js +21 -0
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +16 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.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 +34 -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/diff.d.ts +7 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +86 -28
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +4 -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 +23 -10
- 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 +8 -0
- 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 +52 -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/tool-execution.d.ts +19 -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 +127 -14
- 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 +14 -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 +93 -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 +328 -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 +123 -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/extension-ui-controller.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-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 +4 -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 +9 -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 +103 -23
- 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/themes.js +4 -4
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/keybindings.ts +4 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +4 -2
- package/packages/pi-coding-agent/src/core/settings-manager.collapse-tool-calls.test.ts +46 -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 +36 -0
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -1
- 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/edit-diff.test.ts +20 -0
- package/packages/pi-coding-agent/src/core/tools/edit-diff.ts +26 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-summary-line.test.ts +41 -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/diff.ts +105 -28
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +21 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +63 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1262 -1138
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-summary-line.ts +120 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.ts +396 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +530 -398
- package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +1 -1
- 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 +4 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +109 -23
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +60 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +4 -4
- package/packages/pi-tui/dist/components/editor.js +3 -3
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/src/components/editor.ts +3 -3
- package/pkg/dist/modes/interactive/theme/themes.js +4 -4
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- 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/cache-timer/index.ts +3 -2
- 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 +42 -12
- package/src/resources/extensions/subagent/background-job-manager.ts +28 -0
- package/src/resources/extensions/subagent/in-process-runner.ts +534 -0
- package/src/resources/extensions/subagent/index.ts +489 -799
- 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
package/dist/cli.js
CHANGED
|
@@ -17,6 +17,7 @@ import { getProjectSessionsDir } from './project-sessions.js';
|
|
|
17
17
|
import { markStartup, printStartupTimings } from './startup-timings.js';
|
|
18
18
|
import { bootstrapRtk, GSD_RTK_DISABLED_ENV } from './rtk.js';
|
|
19
19
|
import { loadEffectivePreferences } from './shared-preferences.js';
|
|
20
|
+
import { createLsdSettingsManager } from './lsd-settings-manager.js';
|
|
20
21
|
// ---------------------------------------------------------------------------
|
|
21
22
|
// V8 compile cache — Node 22+ can cache compiled bytecode across runs,
|
|
22
23
|
// eliminating repeated parse/compile overhead for unchanged modules.
|
|
@@ -270,7 +271,7 @@ const { resolveModelsJsonPath } = await import('./models-resolver.js');
|
|
|
270
271
|
const modelsJsonPath = resolveModelsJsonPath();
|
|
271
272
|
const modelRegistry = new ModelRegistry(authStorage, modelsJsonPath);
|
|
272
273
|
markStartup('ModelRegistry');
|
|
273
|
-
const settingsManager =
|
|
274
|
+
const settingsManager = createLsdSettingsManager(process.cwd(), agentDir);
|
|
274
275
|
markStartup('SettingsManager.create');
|
|
275
276
|
if (cliFlags.noSandbox) {
|
|
276
277
|
process.env.PI_NO_SANDBOX = '1';
|
package/dist/resource-loader.js
CHANGED
|
@@ -127,6 +127,25 @@ function collectFileEntries(dir, root, out) {
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
+
function hasMissingResourceEntries(srcDir, destDir) {
|
|
131
|
+
if (!existsSync(srcDir))
|
|
132
|
+
return false;
|
|
133
|
+
if (!existsSync(destDir))
|
|
134
|
+
return true;
|
|
135
|
+
for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
|
|
136
|
+
const srcPath = join(srcDir, entry.name);
|
|
137
|
+
const destPath = join(destDir, entry.name);
|
|
138
|
+
if (!existsSync(destPath))
|
|
139
|
+
return true;
|
|
140
|
+
if (entry.isDirectory() && hasMissingResourceEntries(srcPath, destPath))
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
function hasMissingManagedResources(agentDir) {
|
|
146
|
+
return hasMissingResourceEntries(bundledExtensionsDir, join(agentDir, 'extensions'))
|
|
147
|
+
|| hasMissingResourceEntries(join(resourcesDir, 'agents'), join(agentDir, 'agents'));
|
|
148
|
+
}
|
|
130
149
|
export function getNewerManagedResourceVersion(agentDir, currentVersion) {
|
|
131
150
|
const managedVersion = readManagedResourceVersion(agentDir);
|
|
132
151
|
if (!managedVersion) {
|
|
@@ -192,8 +211,18 @@ function syncResourceDir(srcDir, destDir) {
|
|
|
192
211
|
for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
|
|
193
212
|
if (entry.isDirectory()) {
|
|
194
213
|
const target = join(destDir, entry.name);
|
|
195
|
-
if (existsSync(target))
|
|
196
|
-
|
|
214
|
+
if (existsSync(target)) {
|
|
215
|
+
try {
|
|
216
|
+
rmSync(target, { recursive: true, force: true });
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
// Retry once — macOS can create .DS_Store mid-deletion causing ENOTEMPTY
|
|
220
|
+
try {
|
|
221
|
+
rmSync(target, { recursive: true, force: true });
|
|
222
|
+
}
|
|
223
|
+
catch { /* non-fatal */ }
|
|
224
|
+
}
|
|
225
|
+
}
|
|
197
226
|
}
|
|
198
227
|
}
|
|
199
228
|
try {
|
|
@@ -386,7 +415,8 @@ export function initResources(agentDir) {
|
|
|
386
415
|
// Version matches — check content fingerprint for same-version staleness.
|
|
387
416
|
const currentHash = computeResourceFingerprint();
|
|
388
417
|
const hasStaleExtensionFiles = hasStaleCompiledExtensionSiblings(join(agentDir, 'extensions'));
|
|
389
|
-
|
|
418
|
+
const hasMissingResources = hasMissingManagedResources(agentDir);
|
|
419
|
+
if (manifest.contentHash && manifest.contentHash === currentHash && !hasStaleExtensionFiles && !hasMissingResources) {
|
|
390
420
|
return;
|
|
391
421
|
}
|
|
392
422
|
}
|
|
@@ -62,9 +62,10 @@ export function registerCodegenTools(pi, deps) {
|
|
|
62
62
|
}
|
|
63
63
|
break;
|
|
64
64
|
}
|
|
65
|
-
case "
|
|
65
|
+
case "browser_ref": {
|
|
66
66
|
// Refs are session-specific — add comment
|
|
67
|
-
|
|
67
|
+
const refAction = params.action ?? "click";
|
|
68
|
+
testLines.push(` // browser_ref (${refAction}): ${entry.paramsSummary} — replace with stable selector`);
|
|
68
69
|
actionCount++;
|
|
69
70
|
break;
|
|
70
71
|
}
|
|
@@ -77,9 +78,8 @@ export function registerCodegenTools(pi, deps) {
|
|
|
77
78
|
}
|
|
78
79
|
break;
|
|
79
80
|
}
|
|
80
|
-
case "
|
|
81
|
-
|
|
82
|
-
actionCount++;
|
|
81
|
+
case "browser_fill_ref_handled": {
|
|
82
|
+
// Already handled by browser_ref above
|
|
83
83
|
break;
|
|
84
84
|
}
|
|
85
85
|
case "browser_key_press": {
|
|
@@ -8,201 +8,130 @@ export function registerNavigationTools(pi, deps) {
|
|
|
8
8
|
pi.registerTool({
|
|
9
9
|
name: "browser_navigate",
|
|
10
10
|
label: "Browser Navigate",
|
|
11
|
-
description: "
|
|
11
|
+
description: "Navigate to a URL, go back/forward in history, or reload the page. " +
|
|
12
|
+
"Use ONLY for locally-running web apps (e.g. http://localhost:3000). " +
|
|
13
|
+
"Do NOT use for documentation sites, GitHub, or external URLs — use web_search instead.",
|
|
12
14
|
parameters: Type.Object({
|
|
13
|
-
|
|
15
|
+
action: Type.Union([
|
|
16
|
+
Type.Literal("goto"),
|
|
17
|
+
Type.Literal("go_back"),
|
|
18
|
+
Type.Literal("go_forward"),
|
|
19
|
+
Type.Literal("reload"),
|
|
20
|
+
], { description: "'goto' — navigate to url (default), 'go_back'/'go_forward' — history, 'reload' — refresh page" }),
|
|
21
|
+
url: Type.Optional(Type.String({ description: "URL to navigate to (required for goto action)." })),
|
|
14
22
|
screenshot: Type.Optional(Type.Boolean({ description: "Capture and return a screenshot (default: false)", default: false })),
|
|
15
23
|
}),
|
|
16
24
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
17
|
-
|
|
18
|
-
let beforeState = null;
|
|
25
|
+
const action = params.action ?? "goto";
|
|
19
26
|
try {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
actionId = deps.beginTrackedAction("browser_navigate", params, beforeState.url).id;
|
|
23
|
-
await p.goto(params.url, { waitUntil: "domcontentloaded", timeout: 30000 });
|
|
24
|
-
await p.waitForLoadState("networkidle", { timeout: 5000 }).catch(() => { });
|
|
25
|
-
await new Promise(resolve => setTimeout(resolve, 300));
|
|
26
|
-
const title = await p.title();
|
|
27
|
-
const url = p.url();
|
|
28
|
-
const viewport = p.viewportSize();
|
|
29
|
-
const vpText = viewport ? `${viewport.width}x${viewport.height}` : "unknown";
|
|
30
|
-
const afterState = await deps.captureCompactPageState(p, { includeBodyText: true });
|
|
31
|
-
const summary = deps.formatCompactStateSummary(afterState);
|
|
32
|
-
const jsErrors = deps.getRecentErrors(p.url());
|
|
33
|
-
const diff = diffCompactStates(beforeState, afterState);
|
|
34
|
-
setLastActionBeforeState(beforeState);
|
|
35
|
-
setLastActionAfterState(afterState);
|
|
36
|
-
deps.finishTrackedAction(actionId, {
|
|
37
|
-
status: "success",
|
|
38
|
-
afterUrl: afterState.url,
|
|
39
|
-
warningSummary: jsErrors.trim() || undefined,
|
|
40
|
-
diffSummary: diff.summary,
|
|
41
|
-
changed: diff.changed,
|
|
42
|
-
beforeState,
|
|
43
|
-
afterState,
|
|
44
|
-
});
|
|
45
|
-
let screenshotContent = [];
|
|
46
|
-
if (params.screenshot) {
|
|
47
|
-
try {
|
|
48
|
-
let buf = await p.screenshot({ type: "jpeg", quality: 80, scale: "css" });
|
|
49
|
-
buf = await deps.constrainScreenshot(p, buf, "image/jpeg", 80);
|
|
50
|
-
screenshotContent = [{ type: "image", data: buf.toString("base64"), mimeType: "image/jpeg" }];
|
|
51
|
-
}
|
|
52
|
-
catch { /* non-fatal — screenshot is optional, navigation result is still valid */ }
|
|
27
|
+
if (action === "goto") {
|
|
28
|
+
return await gotoAction(params);
|
|
53
29
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
{ type: "text", text: `Navigated to: ${url}\nTitle: ${title}\nViewport: ${vpText}\nAction: ${actionId}${jsErrors}\n\nDiff:\n${deps.formatDiffText(diff)}\n\nPage summary:\n${summary}` },
|
|
57
|
-
...screenshotContent,
|
|
58
|
-
],
|
|
59
|
-
details: { title, url, status: "loaded", viewport: vpText, actionId, diff },
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
if (actionId !== null) {
|
|
64
|
-
deps.finishTrackedAction(actionId, { status: "error", afterUrl: deps.getActivePageOrNull()?.url() ?? "", error: err.message, beforeState: beforeState ?? undefined });
|
|
30
|
+
else if (action === "go_back") {
|
|
31
|
+
return await goBackForward("back");
|
|
65
32
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (errorShot) {
|
|
69
|
-
content.push({ type: "image", data: errorShot.data, mimeType: errorShot.mimeType });
|
|
33
|
+
else if (action === "go_forward") {
|
|
34
|
+
return await goBackForward("forward");
|
|
70
35
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
details: { status: "error", error: err.message, actionId },
|
|
74
|
-
isError: true,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
// -------------------------------------------------------------------------
|
|
80
|
-
// browser_go_back
|
|
81
|
-
// -------------------------------------------------------------------------
|
|
82
|
-
pi.registerTool({
|
|
83
|
-
name: "browser_go_back",
|
|
84
|
-
label: "Browser Go Back",
|
|
85
|
-
description: "Navigate back in browser history. Returns a compact page summary after navigation.",
|
|
86
|
-
parameters: Type.Object({}),
|
|
87
|
-
async execute(_toolCallId, _params, _signal, _onUpdate, _ctx) {
|
|
88
|
-
try {
|
|
89
|
-
const { page: p } = await deps.ensureBrowser();
|
|
90
|
-
const response = await p.goBack({ waitUntil: "domcontentloaded", timeout: 10000 });
|
|
91
|
-
if (!response) {
|
|
92
|
-
return {
|
|
93
|
-
content: [{ type: "text", text: "No previous page in history." }],
|
|
94
|
-
details: {},
|
|
95
|
-
isError: true,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
await p.waitForLoadState("networkidle", { timeout: 5000 }).catch(() => { });
|
|
99
|
-
const title = await p.title();
|
|
100
|
-
const url = p.url();
|
|
101
|
-
const summary = await deps.postActionSummary(p);
|
|
102
|
-
const jsErrors = deps.getRecentErrors(p.url());
|
|
103
|
-
return {
|
|
104
|
-
content: [{ type: "text", text: `Navigated back to: ${url}\nTitle: ${title}${jsErrors}\n\nPage summary:\n${summary}` }],
|
|
105
|
-
details: { title, url },
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
const errorShot = await deps.captureErrorScreenshot(deps.getActivePageOrNull());
|
|
110
|
-
const content = [{ type: "text", text: `Go back failed: ${err.message}` }];
|
|
111
|
-
if (errorShot) {
|
|
112
|
-
content.push({ type: "image", data: errorShot.data, mimeType: errorShot.mimeType });
|
|
113
|
-
}
|
|
114
|
-
return { content, details: { error: err.message }, isError: true };
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
});
|
|
118
|
-
// -------------------------------------------------------------------------
|
|
119
|
-
// browser_go_forward
|
|
120
|
-
// -------------------------------------------------------------------------
|
|
121
|
-
pi.registerTool({
|
|
122
|
-
name: "browser_go_forward",
|
|
123
|
-
label: "Browser Go Forward",
|
|
124
|
-
description: "Navigate forward in browser history. Returns a compact page summary after navigation.",
|
|
125
|
-
parameters: Type.Object({}),
|
|
126
|
-
async execute(_toolCallId, _params, _signal, _onUpdate, _ctx) {
|
|
127
|
-
try {
|
|
128
|
-
const { page: p } = await deps.ensureBrowser();
|
|
129
|
-
const response = await p.goForward({ waitUntil: "domcontentloaded", timeout: 10000 });
|
|
130
|
-
if (!response) {
|
|
131
|
-
return {
|
|
132
|
-
content: [{ type: "text", text: "No forward page in history." }],
|
|
133
|
-
details: {},
|
|
134
|
-
isError: true,
|
|
135
|
-
};
|
|
36
|
+
else {
|
|
37
|
+
return await reloadAction();
|
|
136
38
|
}
|
|
137
|
-
await p.waitForLoadState("networkidle", { timeout: 5000 }).catch(() => { });
|
|
138
|
-
const title = await p.title();
|
|
139
|
-
const url = p.url();
|
|
140
|
-
const summary = await deps.postActionSummary(p);
|
|
141
|
-
const jsErrors = deps.getRecentErrors(p.url());
|
|
142
|
-
return {
|
|
143
|
-
content: [{ type: "text", text: `Navigated forward to: ${url}\nTitle: ${title}${jsErrors}\n\nPage summary:\n${summary}` }],
|
|
144
|
-
details: { title, url },
|
|
145
|
-
};
|
|
146
39
|
}
|
|
147
40
|
catch (err) {
|
|
148
41
|
const errorShot = await deps.captureErrorScreenshot(deps.getActivePageOrNull());
|
|
149
|
-
const content = [{ type: "text", text: `
|
|
150
|
-
if (errorShot)
|
|
42
|
+
const content = [{ type: "text", text: `Navigation '${action}' failed: ${err.message}` }];
|
|
43
|
+
if (errorShot)
|
|
151
44
|
content.push({ type: "image", data: errorShot.data, mimeType: errorShot.mimeType });
|
|
152
|
-
}
|
|
153
45
|
return { content, details: { error: err.message }, isError: true };
|
|
154
46
|
}
|
|
155
47
|
},
|
|
156
48
|
});
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
49
|
+
// ── action implementations ──
|
|
50
|
+
async function gotoAction(params) {
|
|
51
|
+
if (!params.url) {
|
|
52
|
+
return { content: [{ type: "text", text: "Goto requires a 'url' parameter." }], details: { error: "missing_url" }, isError: true };
|
|
53
|
+
}
|
|
54
|
+
let actionId = null;
|
|
55
|
+
let beforeState = null;
|
|
56
|
+
const { page: p } = await deps.ensureBrowser();
|
|
57
|
+
beforeState = await deps.captureCompactPageState(p, { includeBodyText: true });
|
|
58
|
+
actionId = deps.beginTrackedAction("browser_navigate", params, beforeState.url).id;
|
|
59
|
+
await p.goto(params.url, { waitUntil: "domcontentloaded", timeout: 30000 });
|
|
60
|
+
await p.waitForLoadState("networkidle", { timeout: 5000 }).catch(() => { });
|
|
61
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
62
|
+
const title = await p.title();
|
|
63
|
+
const url = p.url();
|
|
64
|
+
const viewport = p.viewportSize();
|
|
65
|
+
const vpText = viewport ? `${viewport.width}x${viewport.height}` : "unknown";
|
|
66
|
+
const afterState = await deps.captureCompactPageState(p, { includeBodyText: true });
|
|
67
|
+
const summary = deps.formatCompactStateSummary(afterState);
|
|
68
|
+
const jsErrors = deps.getRecentErrors(p.url());
|
|
69
|
+
const diff = diffCompactStates(beforeState, afterState);
|
|
70
|
+
setLastActionBeforeState(beforeState);
|
|
71
|
+
setLastActionAfterState(afterState);
|
|
72
|
+
deps.finishTrackedAction(actionId, {
|
|
73
|
+
status: "success", afterUrl: afterState.url, warningSummary: jsErrors.trim() || undefined,
|
|
74
|
+
diffSummary: diff.summary, changed: diff.changed, beforeState, afterState,
|
|
75
|
+
});
|
|
76
|
+
let screenshotContent = [];
|
|
77
|
+
if (params.screenshot) {
|
|
166
78
|
try {
|
|
167
|
-
|
|
168
|
-
await
|
|
169
|
-
|
|
170
|
-
const title = await p.title();
|
|
171
|
-
const url = p.url();
|
|
172
|
-
const viewport = p.viewportSize();
|
|
173
|
-
const vpText = viewport ? `${viewport.width}x${viewport.height}` : "unknown";
|
|
174
|
-
const summary = await deps.postActionSummary(p);
|
|
175
|
-
const jsErrors = deps.getRecentErrors(p.url());
|
|
176
|
-
let screenshotContent = [];
|
|
177
|
-
try {
|
|
178
|
-
let buf = await p.screenshot({ type: "jpeg", quality: 80, scale: "css" });
|
|
179
|
-
buf = await deps.constrainScreenshot(p, buf, "image/jpeg", 80);
|
|
180
|
-
screenshotContent = [{
|
|
181
|
-
type: "image",
|
|
182
|
-
data: buf.toString("base64"),
|
|
183
|
-
mimeType: "image/jpeg",
|
|
184
|
-
}];
|
|
185
|
-
}
|
|
186
|
-
catch { /* non-fatal — screenshot is optional, reload result is still valid */ }
|
|
187
|
-
return {
|
|
188
|
-
content: [
|
|
189
|
-
{
|
|
190
|
-
type: "text",
|
|
191
|
-
text: `Reloaded: ${url}\nTitle: ${title}\nViewport: ${vpText}${jsErrors}\n\nPage summary:\n${summary}`,
|
|
192
|
-
},
|
|
193
|
-
...screenshotContent,
|
|
194
|
-
],
|
|
195
|
-
details: { title, url, viewport: vpText },
|
|
196
|
-
};
|
|
79
|
+
let buf = await p.screenshot({ type: "jpeg", quality: 80, scale: "css" });
|
|
80
|
+
buf = await deps.constrainScreenshot(p, buf, "image/jpeg", 80);
|
|
81
|
+
screenshotContent = [{ type: "image", data: buf.toString("base64"), mimeType: "image/jpeg" }];
|
|
197
82
|
}
|
|
198
|
-
catch
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
83
|
+
catch { /* non-fatal */ }
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
content: [
|
|
87
|
+
{ type: "text", text: `Navigated to: ${url}\nTitle: ${title}\nViewport: ${vpText}\nAction: ${actionId}${jsErrors}\n\nDiff:\n${deps.formatDiffText(diff)}\n\nPage summary:\n${summary}` },
|
|
88
|
+
...screenshotContent,
|
|
89
|
+
],
|
|
90
|
+
details: { title, url, status: "loaded", viewport: vpText, actionId, diff },
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async function goBackForward(direction) {
|
|
94
|
+
const { page: p } = await deps.ensureBrowser();
|
|
95
|
+
const response = direction === "back"
|
|
96
|
+
? await p.goBack({ waitUntil: "domcontentloaded", timeout: 10000 })
|
|
97
|
+
: await p.goForward({ waitUntil: "domcontentloaded", timeout: 10000 });
|
|
98
|
+
if (!response) {
|
|
99
|
+
return {
|
|
100
|
+
content: [{ type: "text", text: `No ${direction} page in history.` }],
|
|
101
|
+
details: {},
|
|
102
|
+
isError: true,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
await p.waitForLoadState("networkidle", { timeout: 5000 }).catch(() => { });
|
|
106
|
+
const title = await p.title();
|
|
107
|
+
const url = p.url();
|
|
108
|
+
const summary = await deps.postActionSummary(p);
|
|
109
|
+
const jsErrors = deps.getRecentErrors(p.url());
|
|
110
|
+
return {
|
|
111
|
+
content: [{ type: "text", text: `Navigated ${direction} to: ${url}\nTitle: ${title}${jsErrors}\n\nPage summary:\n${summary}` }],
|
|
112
|
+
details: { title, url },
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async function reloadAction() {
|
|
116
|
+
const { page: p } = await deps.ensureBrowser();
|
|
117
|
+
await p.reload({ waitUntil: "domcontentloaded", timeout: 30000 });
|
|
118
|
+
await p.waitForLoadState("networkidle", { timeout: 5000 }).catch(() => { });
|
|
119
|
+
const title = await p.title();
|
|
120
|
+
const url = p.url();
|
|
121
|
+
const viewport = p.viewportSize();
|
|
122
|
+
const vpText = viewport ? `${viewport.width}x${viewport.height}` : "unknown";
|
|
123
|
+
const summary = await deps.postActionSummary(p);
|
|
124
|
+
const jsErrors = deps.getRecentErrors(p.url());
|
|
125
|
+
let screenshotContent = [];
|
|
126
|
+
try {
|
|
127
|
+
let buf = await p.screenshot({ type: "jpeg", quality: 80, scale: "css" });
|
|
128
|
+
buf = await deps.constrainScreenshot(p, buf, "image/jpeg", 80);
|
|
129
|
+
screenshotContent = [{ type: "image", data: buf.toString("base64"), mimeType: "image/jpeg" }];
|
|
130
|
+
}
|
|
131
|
+
catch { /* non-fatal */ }
|
|
132
|
+
return {
|
|
133
|
+
content: [{ type: "text", text: `Reloaded: ${url}\nTitle: ${title}\nViewport: ${vpText}${jsErrors}\n\nPage summary:\n${summary}` }, ...screenshotContent],
|
|
134
|
+
details: { title, url, viewport: vpText },
|
|
135
|
+
};
|
|
136
|
+
}
|
|
208
137
|
}
|