@narumitw/pi-chrome-devtools 0.52.2 → 0.52.3
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 +18 -10
- package/dist/chunks/{browser-settings-menu-VI2I3TXI.js → browser-settings-menu-VWCNG4HB.js} +2 -2
- package/dist/chunks/{chunk-CC37WUUE.js → chunk-RH6KESL3.js} +67 -14
- package/dist/chunks/{chunk-CC37WUUE.js.map → chunk-RH6KESL3.js.map} +2 -2
- package/dist/chunks/{menu-LLR455UX.js → menu-PLD3S3EO.js} +8 -7
- package/dist/chunks/{menu-LLR455UX.js.map → menu-PLD3S3EO.js.map} +2 -2
- package/dist/index.ts +14 -7
- package/dist/index.ts.map +2 -2
- package/package.json +1 -1
- package/src/chrome-devtools.ts +11 -3
- package/src/lazy-tools.ts +70 -6
- package/src/menu.ts +5 -4
- package/src/tool-selector.ts +12 -6
- /package/dist/chunks/{browser-settings-menu-VI2I3TXI.js.map → browser-settings-menu-VWCNG4HB.js.map} +0 -0
package/src/lazy-tools.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
defineTool,
|
|
3
|
+
type ExtensionAPI,
|
|
4
|
+
type ExtensionContext,
|
|
5
|
+
} from "@earendil-works/pi-coding-agent";
|
|
2
6
|
import { Type } from "typebox";
|
|
3
7
|
import { CHROME_DEVTOOLS_TOOL_NAMES, type ChromeDevToolsToolName } from "./tool-names.js";
|
|
4
8
|
|
|
@@ -13,6 +17,7 @@ const existingAvailableToolsStore = sharedGlobal[AVAILABLE_TOOLS_STORE];
|
|
|
13
17
|
const availableToolsByApi =
|
|
14
18
|
existingAvailableToolsStore ?? new WeakMap<ExtensionAPI, Set<ChromeDevToolsToolName>>();
|
|
15
19
|
if (!existingAvailableToolsStore) sharedGlobal[AVAILABLE_TOOLS_STORE] = availableToolsByApi;
|
|
20
|
+
const lazyExposureByApi = new WeakMap<ExtensionAPI, boolean>();
|
|
16
21
|
|
|
17
22
|
const SEARCH_TEXT: Record<ChromeDevToolsToolName, string> = {
|
|
18
23
|
chrome_devtools_list_pages: "list open inspectable chrome browser pages tabs targets",
|
|
@@ -31,15 +36,30 @@ export function initializeAvailableChromeDevtoolsTools(pi: ExtensionAPI) {
|
|
|
31
36
|
);
|
|
32
37
|
}
|
|
33
38
|
|
|
34
|
-
export function
|
|
39
|
+
export function configureChromeDevtoolsToolExposure(
|
|
35
40
|
pi: ExtensionAPI,
|
|
36
41
|
availableTools: readonly ChromeDevToolsToolName[],
|
|
42
|
+
model?: ExtensionContext["model"],
|
|
37
43
|
) {
|
|
38
|
-
setAvailableTools(pi, availableTools);
|
|
44
|
+
const available = setAvailableTools(pi, availableTools);
|
|
45
|
+
const lazyExposure = supportsNativeDeferredToolLoading(model);
|
|
46
|
+
lazyExposureByApi.set(pi, lazyExposure);
|
|
47
|
+
const exposedTools = lazyExposure
|
|
48
|
+
? []
|
|
49
|
+
: CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));
|
|
39
50
|
const nonCapabilityTools = pi
|
|
40
51
|
.getActiveTools()
|
|
41
52
|
.filter((name) => !CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName));
|
|
42
|
-
pi.setActiveTools(
|
|
53
|
+
pi.setActiveTools(
|
|
54
|
+
unique([...nonCapabilityTools, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...exposedTools]),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function requireEagerChromeDevtoolsToolExposure(pi: ExtensionAPI) {
|
|
59
|
+
lazyExposureByApi.set(pi, false);
|
|
60
|
+
const active = pi.getActiveTools();
|
|
61
|
+
const available = availableChromeDevtoolsTools(pi);
|
|
62
|
+
pi.setActiveTools(unique([...active, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...available]));
|
|
43
63
|
}
|
|
44
64
|
|
|
45
65
|
export function applyAvailableChromeDevtoolsTools(
|
|
@@ -47,14 +67,46 @@ export function applyAvailableChromeDevtoolsTools(
|
|
|
47
67
|
availableTools: readonly ChromeDevToolsToolName[],
|
|
48
68
|
) {
|
|
49
69
|
const available = setAvailableTools(pi, availableTools);
|
|
70
|
+
const lazyExposure = lazyExposureByApi.get(pi) === true;
|
|
50
71
|
const active = pi
|
|
51
72
|
.getActiveTools()
|
|
52
73
|
.filter(
|
|
53
74
|
(name) =>
|
|
54
75
|
!CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName) ||
|
|
55
|
-
available.has(name as ChromeDevToolsToolName),
|
|
76
|
+
(lazyExposure && available.has(name as ChromeDevToolsToolName)),
|
|
56
77
|
);
|
|
57
|
-
|
|
78
|
+
const eagerTools = lazyExposure
|
|
79
|
+
? []
|
|
80
|
+
: CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));
|
|
81
|
+
pi.setActiveTools(unique([...active, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...eagerTools]));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function chromeDevtoolsToolExposureMode(pi: ExtensionAPI) {
|
|
85
|
+
return lazyExposureByApi.get(pi) === true ? "native deferred" : "eager";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function supportsNativeDeferredToolLoading(model: ExtensionContext["model"]): boolean {
|
|
89
|
+
if (!model) return false;
|
|
90
|
+
if (model.api === "anthropic-messages") {
|
|
91
|
+
const configured = compatBoolean(model.compat, "supportsToolReferences");
|
|
92
|
+
if (configured !== undefined) return configured;
|
|
93
|
+
if (model.provider !== "anthropic" || model.id.includes("haiku")) return false;
|
|
94
|
+
const version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\d+)(?:-(\d+))?(?:-|$)/);
|
|
95
|
+
if (!version) return false;
|
|
96
|
+
const major = Number(version[1]);
|
|
97
|
+
const minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;
|
|
98
|
+
return major > 4 || (major === 4 && minor >= 5);
|
|
99
|
+
}
|
|
100
|
+
if (model.api === "openai-completions") {
|
|
101
|
+
return compatString(model.compat, "deferredToolsMode") === "kimi";
|
|
102
|
+
}
|
|
103
|
+
if (model.api === "openai-responses" || model.api === "openai-codex-responses") {
|
|
104
|
+
return (
|
|
105
|
+
compatBoolean(model.compat, "supportsAdditionalTools") === true ||
|
|
106
|
+
compatBoolean(model.compat, "supportsToolSearch") === true
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return false;
|
|
58
110
|
}
|
|
59
111
|
|
|
60
112
|
export function availableChromeDevtoolsTools(pi: ExtensionAPI) {
|
|
@@ -138,6 +190,18 @@ function setAvailableTools(pi: ExtensionAPI, availableTools: readonly ChromeDevT
|
|
|
138
190
|
return available;
|
|
139
191
|
}
|
|
140
192
|
|
|
193
|
+
function compatBoolean(value: unknown, key: string) {
|
|
194
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return undefined;
|
|
195
|
+
const record = value as Record<string, unknown>;
|
|
196
|
+
return typeof record[key] === "boolean" ? record[key] : undefined;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function compatString(value: unknown, key: string) {
|
|
200
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return undefined;
|
|
201
|
+
const record = value as Record<string, unknown>;
|
|
202
|
+
return typeof record[key] === "string" ? record[key] : undefined;
|
|
203
|
+
}
|
|
204
|
+
|
|
141
205
|
function unique(values: readonly string[]) {
|
|
142
206
|
return [...new Set(values)];
|
|
143
207
|
}
|
package/src/menu.ts
CHANGED
|
@@ -306,7 +306,7 @@ export async function showChromeDevtoolsToolWorkflow(
|
|
|
306
306
|
current.draft = new Set(selectedTools);
|
|
307
307
|
current.applied = true;
|
|
308
308
|
ctx.ui.notify(
|
|
309
|
-
`Saved: ${selectedTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} browser tools available
|
|
309
|
+
`Saved: ${selectedTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} browser tools available.`,
|
|
310
310
|
"info",
|
|
311
311
|
);
|
|
312
312
|
return { kind: "close" };
|
|
@@ -378,7 +378,7 @@ function buildMenuSnapshot(pi: ExtensionAPI, settings: SettingsLoadResult): Menu
|
|
|
378
378
|
|
|
379
379
|
function mainStateLines(snapshot: MenuSnapshot) {
|
|
380
380
|
return sanitizeLines([
|
|
381
|
-
`
|
|
381
|
+
`Tool catalog: ${snapshot.activeTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} available · ${snapshot.persistenceLabel}`,
|
|
382
382
|
`Browser: ${browserLifecycleSummary()}`,
|
|
383
383
|
`Endpoint: ${devToolsEndpoint()}`,
|
|
384
384
|
...(snapshot.settingsWarning ? [`Settings warning: ${snapshot.settingsWarning}`] : []),
|
|
@@ -421,7 +421,7 @@ function buildToolReview(current: ToolWorkflowState) {
|
|
|
421
421
|
`Current available browser tools: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,
|
|
422
422
|
`Proposed available browser tools: ${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,
|
|
423
423
|
"",
|
|
424
|
-
"Available
|
|
424
|
+
"Available after apply:",
|
|
425
425
|
...(available.length > 0
|
|
426
426
|
? available.map((name) => ` - ${TOOL_PRESENTATION[name].label} (${name})`)
|
|
427
427
|
: [" - none"]),
|
|
@@ -432,7 +432,8 @@ function buildToolReview(current: ToolWorkflowState) {
|
|
|
432
432
|
: [" - none"]),
|
|
433
433
|
"",
|
|
434
434
|
"Other active Pi tools remain unchanged.",
|
|
435
|
-
"
|
|
435
|
+
"Native-capable models defer these tools until chrome_devtools_load selects them.",
|
|
436
|
+
"Other models expose available tools eagerly before the next model request.",
|
|
436
437
|
"The accepted availability policy is saved for future sessions.",
|
|
437
438
|
].join("\n"),
|
|
438
439
|
);
|
package/src/tool-selector.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
applyAvailableChromeDevtoolsTools,
|
|
15
15
|
availableChromeDevtoolsTools,
|
|
16
16
|
CHROME_DEVTOOLS_LOAD_TOOL_NAME,
|
|
17
|
+
chromeDevtoolsToolExposureMode,
|
|
17
18
|
} from "./lazy-tools.js";
|
|
18
19
|
import { state } from "./runtime.js";
|
|
19
20
|
import { loadSettings, saveSettings, settingsFilePath } from "./settings.js";
|
|
@@ -49,7 +50,7 @@ export async function updateChromeDevtoolsTools(
|
|
|
49
50
|
if (result !== "saved" || generation !== state.sessionGeneration) return;
|
|
50
51
|
const status = await buildToolStatusMessage(pi);
|
|
51
52
|
if (generation !== state.sessionGeneration) return;
|
|
52
|
-
ctx.ui.notify(`Chrome DevTools
|
|
53
|
+
ctx.ui.notify(`Chrome DevTools tool catalog ${action}.\n\n${status}`, "info");
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
export async function setSelectedChromeDevtoolsTools(
|
|
@@ -121,7 +122,11 @@ async function transactSelectedToolsNow(
|
|
|
121
122
|
const previousLoadedChromeTools = previousActiveTools.filter((name) =>
|
|
122
123
|
CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName),
|
|
123
124
|
);
|
|
124
|
-
|
|
125
|
+
const restoredChromeTools =
|
|
126
|
+
chromeDevtoolsToolExposureMode(pi) === "eager"
|
|
127
|
+
? previousAvailableTools
|
|
128
|
+
: previousLoadedChromeTools;
|
|
129
|
+
pi.setActiveTools(unique([...currentNonChromeTools, ...restoredChromeTools]));
|
|
125
130
|
} catch (caught) {
|
|
126
131
|
rollbackError = caught;
|
|
127
132
|
}
|
|
@@ -179,10 +184,11 @@ export async function buildToolStatusMessage(pi: ExtensionAPI) {
|
|
|
179
184
|
const persistedSetting = await persistedSettingLabel();
|
|
180
185
|
return sanitizeChromeDevtoolsDisplay(
|
|
181
186
|
[
|
|
182
|
-
`Chrome DevTools tools available
|
|
187
|
+
`Chrome DevTools tools available: ${formatRuntimeStatus(summary)}`,
|
|
188
|
+
`Tool exposure: ${chromeDevtoolsToolExposureMode(pi)}`,
|
|
183
189
|
`Loaded capability tools this session: ${summary.loadedChromeToolCount}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,
|
|
184
190
|
`Loader: ${pi.getActiveTools().includes(CHROME_DEVTOOLS_LOAD_TOOL_NAME) ? "active" : "inactive"}`,
|
|
185
|
-
`Persisted
|
|
191
|
+
`Persisted tool catalog: ${persistedSetting}`,
|
|
186
192
|
...browserSettingsStatusLines(),
|
|
187
193
|
...(state.settingsNotice ? [`Settings note: ${state.settingsNotice}`] : []),
|
|
188
194
|
`Other active tools preserved: ${summary.activeNonChromeToolCount}`,
|
|
@@ -289,9 +295,9 @@ export function buildCommandGuide() {
|
|
|
289
295
|
"/chrome-devtools quickstart — show endpoint and launch help",
|
|
290
296
|
"/chrome-devtools status — show tool and settings status",
|
|
291
297
|
"/chrome-devtools settings — edit browser connection settings",
|
|
292
|
-
"/chrome-devtools tools — choose
|
|
298
|
+
"/chrome-devtools tools — choose available Chrome DevTools tools",
|
|
293
299
|
"/chrome-devtools toggle|select — compatibility aliases for tools",
|
|
294
|
-
"/chrome-devtools enable|on — make all Chrome DevTools tools available
|
|
300
|
+
"/chrome-devtools enable|on — make all Chrome DevTools tools available",
|
|
295
301
|
"/chrome-devtools disable|off — make all Chrome DevTools capability tools unavailable",
|
|
296
302
|
].join("\n");
|
|
297
303
|
}
|
/package/dist/chunks/{browser-settings-menu-VI2I3TXI.js.map → browser-settings-menu-VWCNG4HB.js.map}
RENAMED
|
File without changes
|