@weavetab/mcp 2.5.0-beta.2 → 2.5.0-beta.4
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/AGENTS.md +1 -1
- package/ARCHITECTURE.md +6 -6
- package/LICENSE +1 -1
- package/README.md +158 -961
- package/SECURITY.md +33 -22
- package/TROUBLESHOOTING.md +2 -2
- package/dist/cdp/bridge.js +2 -1
- package/dist/cdp/connector.d.ts +2 -0
- package/dist/cdp/connector.js +8 -4
- package/dist/cdp/helpers.d.ts +4 -0
- package/dist/cdp/helpers.js +181 -0
- package/dist/cdp/omni_broker.d.ts +1 -1
- package/dist/cdp/omni_broker.js +1 -1
- package/dist/cdp/walker.d.ts +25 -1
- package/dist/cdp/walker.js +304 -7
- package/dist/cli/plugin.js +24 -17
- package/dist/cli/updater.d.ts +1 -1
- package/dist/cli/updater.js +27 -7
- package/dist/config/loader.d.ts +8 -0
- package/dist/config/loader.js +41 -2
- package/dist/desktop/discovery.d.ts +44 -0
- package/dist/desktop/discovery.js +364 -0
- package/dist/index.js +95 -15
- package/dist/intelligence/marks.d.ts +36 -0
- package/dist/intelligence/marks.js +30 -0
- package/dist/intelligence/patternCompiler.d.ts +118 -0
- package/dist/intelligence/patternCompiler.js +259 -0
- package/dist/intelligence/sessionMemory.d.ts +2 -0
- package/dist/intelligence/sessionMemory.js +18 -8
- package/dist/overlay/injector.js +2 -2
- package/dist/plugin/interface.d.ts +76 -2
- package/dist/plugin/loader.d.ts +15 -1
- package/dist/plugin/loader.js +217 -70
- package/dist/plugin/pipeline.d.ts +75 -0
- package/dist/plugin/pipeline.js +183 -0
- package/dist/plugin/registry.js +3 -2
- package/dist/security/secrets.d.ts +1 -0
- package/dist/security/secrets.js +13 -0
- package/dist/sensors/actionability.js +1 -2
- package/dist/sensors/guard.js +4 -10
- package/dist/sensors/mutations.js +12 -0
- package/dist/sensors/operation_monitor.js +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +428 -156
- package/dist/state/agent.d.ts +1 -0
- package/dist/state/agent.js +3 -0
- package/dist/state/delta.d.ts +12 -4
- package/dist/state/delta.js +67 -14
- package/dist/state/session.d.ts +6 -0
- package/dist/state/session.js +27 -0
- package/dist/tools/browser_detect.d.ts +16 -3
- package/dist/tools/browser_detect.js +50 -5
- package/dist/tools/burst.d.ts +17 -8
- package/dist/tools/burst.js +236 -77
- package/dist/tools/checkpoint.d.ts +38 -0
- package/dist/tools/checkpoint.js +271 -0
- package/dist/tools/click.d.ts +1 -0
- package/dist/tools/click.js +74 -70
- package/dist/tools/design_extract.js +1 -1
- package/dist/tools/eval.js +1 -1
- package/dist/tools/fill.d.ts +20 -1
- package/dist/tools/fill.js +199 -40
- package/dist/tools/find.d.ts +16 -0
- package/dist/tools/find.js +67 -44
- package/dist/tools/github/index.d.ts +19 -4
- package/dist/tools/github/index.js +40 -4
- package/dist/tools/highlight.d.ts +6 -2
- package/dist/tools/highlight.js +158 -72
- package/dist/tools/inspect.js +1 -1
- package/dist/tools/key.js +65 -56
- package/dist/tools/navigate.js +29 -34
- package/dist/tools/pdf.js +21 -13
- package/dist/tools/pointer.d.ts +18 -3
- package/dist/tools/pointer.js +89 -1
- package/dist/tools/read.d.ts +28 -8
- package/dist/tools/read.js +230 -56
- package/dist/tools/scrape.js +67 -13
- package/dist/tools/screenshot.js +21 -16
- package/dist/tools/scroll.js +6 -11
- package/dist/tools/select.js +8 -2
- package/dist/tools/snapshot.js +3 -34
- package/dist/tools/tabs.js +14 -6
- package/dist/tools/thought.d.ts +2 -0
- package/dist/tools/thought.js +13 -14
- package/dist/tools/type.d.ts +2 -0
- package/dist/tools/type.js +107 -58
- package/dist/tools/type_secret.js +42 -76
- package/dist/tools/upload.js +1 -1
- package/dist/tools/video_compiler.d.ts +1 -1
- package/dist/tools/video_compiler.js +11 -12
- package/dist/version.d.ts +5 -0
- package/dist/version.js +5 -0
- package/docs/DOCUMENTATION.md +21 -32
- package/docs/PLUGINS.md +121 -0
- package/docs/TOOLS.md +56 -0
- package/docs/architecture/blind-injection.md +83 -20
- package/docs/architecture/overview.md +49 -49
- package/docs/configuration/folders.md +55 -54
- package/docs/desktop-automation/electron-apps.md +217 -162
- package/docs/get-started/introduction.md +60 -60
- package/docs/intelligence/site-profiles.md +151 -0
- package/docs/tools/tools.md +631 -293
- package/docs/troubleshooting/trouble-loop.md +31 -31
- package/ext-dist/background.js +10 -62
- package/ext-dist/content.js +333 -920
- package/ext-dist/hud/hud.js +9 -9
- package/ext-dist/manifest.json +2 -6
- package/ext-dist/styles.css +6 -1
- package/mcp.json +101 -67
- package/package.json +5 -6
- package/server.json +3 -3
- package/ext-dist/sidepanel/sidepanel.js +0 -25
- package/ext-dist/sidepanel.html +0 -547
package/dist/state/agent.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ declare class AgentStateManager {
|
|
|
15
15
|
constructor(idleTimeoutMs?: number);
|
|
16
16
|
setCallbacks(cb: AgentStateCallbacks): void;
|
|
17
17
|
setSession(session: CDP.Client): void;
|
|
18
|
+
getSession(): CDP.Client | null;
|
|
18
19
|
setIdleTimeout(ms: number): void;
|
|
19
20
|
reportToolCall(): void;
|
|
20
21
|
reportToolSuccess(): void;
|
package/dist/state/agent.js
CHANGED
package/dist/state/delta.d.ts
CHANGED
|
@@ -46,19 +46,19 @@ export interface RichDelta {
|
|
|
46
46
|
/**
|
|
47
47
|
* Store a full snapshot for a tab target.
|
|
48
48
|
*/
|
|
49
|
-
export declare function storeSnapshot(targetId: string,
|
|
49
|
+
export declare function storeSnapshot(targetId: string, urlOrRefs: string | RefEntry[], maybeRefs?: RefEntry[]): void;
|
|
50
50
|
/**
|
|
51
51
|
* Eagerly initialize the property snapshot cache for a tab.
|
|
52
52
|
*/
|
|
53
|
-
export declare function seedRichSnapshot(targetId: string,
|
|
53
|
+
export declare function seedRichSnapshot(targetId: string, urlOrElements: string | ActionElement[], maybeElements?: ActionElement[]): void;
|
|
54
54
|
/**
|
|
55
55
|
* Compute basic delta.
|
|
56
56
|
*/
|
|
57
|
-
export declare function computeDelta(targetId: string,
|
|
57
|
+
export declare function computeDelta(targetId: string, urlOrNewRefs: string | RefEntry[], maybeNewRefs?: RefEntry[]): SnapshotDiff | null;
|
|
58
58
|
/**
|
|
59
59
|
* Rich delta: wraps computeDelta with property-level change details.
|
|
60
60
|
*/
|
|
61
|
-
export declare function computeRichDelta(targetId: string,
|
|
61
|
+
export declare function computeRichDelta(targetId: string, urlOrNewElements: string | ActionElement[], maybeNewElements?: ActionElement[]): Promise<RichDelta | {
|
|
62
62
|
delta_timeout: true;
|
|
63
63
|
} | null>;
|
|
64
64
|
/**
|
|
@@ -69,3 +69,11 @@ export declare function clearSnapshot(targetId: string): void;
|
|
|
69
69
|
* Clear all snapshots (called on CDP disconnect).
|
|
70
70
|
*/
|
|
71
71
|
export declare function clearAllSnapshots(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Get stored ref entry from snapshot for recovery of detached nodes.
|
|
74
|
+
*/
|
|
75
|
+
export declare function getStoredRef(targetId: string, refId: string): RefEntry | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Get stored element properties from rich snapshot for recovery.
|
|
78
|
+
*/
|
|
79
|
+
export declare function getStoredProps(targetId: string, refId: string): Record<string, string> | undefined;
|
package/dist/state/delta.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// weave_read first visit → full snapshot stored here.
|
|
4
4
|
// Subsequent calls → diff against stored snapshot → return only changed refs.
|
|
5
5
|
import { SessionSecretTracker } from "../security/secrets.js";
|
|
6
|
+
import { hookPipeline } from "../plugin/pipeline.js";
|
|
6
7
|
const snapshots = new Map();
|
|
7
8
|
const propSnapshots = new Map();
|
|
8
9
|
const frameSnapshots = new Map();
|
|
@@ -13,22 +14,27 @@ const INTERACTIVE_ROLES = new Set([
|
|
|
13
14
|
function serializeProps(el, targetId) {
|
|
14
15
|
const isSecret = (el.backendNodeId !== undefined && targetId &&
|
|
15
16
|
SessionSecretTracker.isNodeSecret(targetId, el.backendNodeId)) ||
|
|
16
|
-
el.label === '[REDACTED]'
|
|
17
|
+
el.label === '[REDACTED]' ||
|
|
18
|
+
el.value === '[REDACTED]' ||
|
|
19
|
+
el.role === 'password' ||
|
|
20
|
+
el.type === 'password';
|
|
17
21
|
return {
|
|
18
|
-
label: isSecret ? '[REDACTED]' : (el.label ?? ''),
|
|
19
|
-
value: isSecret ? '[REDACTED]' : (el.value ?? ''),
|
|
22
|
+
label: isSecret ? '[REDACTED]' : (targetId ? SessionSecretTracker.redact(targetId, el.label ?? '') : (el.label ?? '')),
|
|
23
|
+
value: isSecret ? '[REDACTED]' : (targetId ? SessionSecretTracker.redact(targetId, el.value ?? '') : (el.value ?? '')),
|
|
20
24
|
disabled: String(!!el.disabled),
|
|
21
25
|
role: el.role,
|
|
22
26
|
href: el.href ?? '',
|
|
23
|
-
placeholder: el.placeholder ?? '',
|
|
24
|
-
textContent: isSecret ? '[REDACTED]' : (el.textContent ?? ''),
|
|
27
|
+
placeholder: isSecret ? '[REDACTED]' : (targetId ? SessionSecretTracker.redact(targetId, el.placeholder ?? '') : (el.placeholder ?? '')),
|
|
28
|
+
textContent: isSecret ? '[REDACTED]' : (targetId ? SessionSecretTracker.redact(targetId, el.textContent ?? '') : (el.textContent ?? '')),
|
|
25
29
|
className: (el.className ?? '').split(' ').filter(Boolean).sort().join(' '),
|
|
26
30
|
};
|
|
27
31
|
}
|
|
28
32
|
/**
|
|
29
33
|
* Store a full snapshot for a tab target.
|
|
30
34
|
*/
|
|
31
|
-
export function storeSnapshot(targetId,
|
|
35
|
+
export function storeSnapshot(targetId, urlOrRefs, maybeRefs) {
|
|
36
|
+
const url = typeof urlOrRefs === 'string' ? urlOrRefs : '';
|
|
37
|
+
const refs = Array.isArray(urlOrRefs) ? urlOrRefs : (maybeRefs || []);
|
|
32
38
|
const map = new Map();
|
|
33
39
|
for (const r of refs)
|
|
34
40
|
map.set(r.id, r);
|
|
@@ -37,7 +43,9 @@ export function storeSnapshot(targetId, url, refs) {
|
|
|
37
43
|
/**
|
|
38
44
|
* Eagerly initialize the property snapshot cache for a tab.
|
|
39
45
|
*/
|
|
40
|
-
export function seedRichSnapshot(targetId,
|
|
46
|
+
export function seedRichSnapshot(targetId, urlOrElements, maybeElements) {
|
|
47
|
+
const url = typeof urlOrElements === 'string' ? urlOrElements : '';
|
|
48
|
+
const elements = Array.isArray(urlOrElements) ? urlOrElements : (maybeElements || []);
|
|
41
49
|
const propMap = new Map();
|
|
42
50
|
const snapMap = new Map();
|
|
43
51
|
const frameMap = new Map();
|
|
@@ -63,9 +71,13 @@ export function seedRichSnapshot(targetId, url, elements) {
|
|
|
63
71
|
/**
|
|
64
72
|
* Compute basic delta.
|
|
65
73
|
*/
|
|
66
|
-
export function computeDelta(targetId,
|
|
74
|
+
export function computeDelta(targetId, urlOrNewRefs, maybeNewRefs) {
|
|
75
|
+
const url = typeof urlOrNewRefs === 'string' ? urlOrNewRefs : '';
|
|
76
|
+
const newRefs = Array.isArray(urlOrNewRefs) ? urlOrNewRefs : (maybeNewRefs || []);
|
|
67
77
|
const prevWrapper = snapshots.get(targetId);
|
|
68
|
-
if (!prevWrapper
|
|
78
|
+
if (!prevWrapper)
|
|
79
|
+
return null;
|
|
80
|
+
if (url && prevWrapper.url && prevWrapper.url !== url)
|
|
69
81
|
return null;
|
|
70
82
|
const prev = prevWrapper.refs;
|
|
71
83
|
const next = new Map();
|
|
@@ -103,15 +115,30 @@ export function computeDelta(targetId, url, newRefs) {
|
|
|
103
115
|
removed.push(id);
|
|
104
116
|
}
|
|
105
117
|
snapshots.set(targetId, { url, refs: next });
|
|
106
|
-
|
|
118
|
+
const diff = { added, removed, changed, stable_count };
|
|
119
|
+
if (added.length > 0 || removed.length > 0 || changed.length > 0) {
|
|
120
|
+
hookPipeline.dispatchDOMMutation({
|
|
121
|
+
type: "dom_diff",
|
|
122
|
+
timestamp: Date.now(),
|
|
123
|
+
url,
|
|
124
|
+
added,
|
|
125
|
+
removed,
|
|
126
|
+
changed,
|
|
127
|
+
stable_count,
|
|
128
|
+
significantChange: added.length > 0 || changed.length > 0,
|
|
129
|
+
}).catch(() => { });
|
|
130
|
+
}
|
|
131
|
+
return diff;
|
|
107
132
|
}
|
|
108
133
|
/**
|
|
109
134
|
* Rich delta: wraps computeDelta with property-level change details.
|
|
110
135
|
*/
|
|
111
|
-
export async function computeRichDelta(targetId,
|
|
136
|
+
export async function computeRichDelta(targetId, urlOrNewElements, maybeNewElements) {
|
|
137
|
+
const url = typeof urlOrNewElements === 'string' ? urlOrNewElements : '';
|
|
138
|
+
const newElements = Array.isArray(urlOrNewElements) ? urlOrNewElements : (maybeNewElements || []);
|
|
112
139
|
// Wrap computation in a 5-second race against a timeout to avoid O(n^2) hangs
|
|
113
140
|
const computePromise = new Promise((resolve) => {
|
|
114
|
-
if (!propSnapshots.has(targetId) || propSnapshots.get(targetId).url !== url) {
|
|
141
|
+
if (!propSnapshots.has(targetId) || (url && propSnapshots.get(targetId).url && propSnapshots.get(targetId).url !== url)) {
|
|
115
142
|
seedRichSnapshot(targetId, url, newElements);
|
|
116
143
|
resolve(null);
|
|
117
144
|
return;
|
|
@@ -204,13 +231,27 @@ export async function computeRichDelta(targetId, url, newElements) {
|
|
|
204
231
|
newPropMap.set(el.id, serializeProps(el, targetId));
|
|
205
232
|
}
|
|
206
233
|
propSnapshots.set(targetId, { url, props: newPropMap });
|
|
207
|
-
|
|
234
|
+
const richResult = {
|
|
208
235
|
added: basicDiff.added,
|
|
209
236
|
removed: basicDiff.removed,
|
|
210
237
|
changed: richChanged,
|
|
211
238
|
stable_count: basicDiff.stable_count,
|
|
212
239
|
...(iframeChanges.length > 0 ? { iframes: iframeChanges } : {}),
|
|
213
|
-
}
|
|
240
|
+
};
|
|
241
|
+
if (basicDiff.added.length > 0 || basicDiff.removed.length > 0 || richChanged.length > 0) {
|
|
242
|
+
hookPipeline.dispatchDOMMutation({
|
|
243
|
+
type: "rich_delta",
|
|
244
|
+
timestamp: Date.now(),
|
|
245
|
+
url,
|
|
246
|
+
added: basicDiff.added,
|
|
247
|
+
removed: basicDiff.removed,
|
|
248
|
+
changed: richChanged,
|
|
249
|
+
stable_count: basicDiff.stable_count,
|
|
250
|
+
iframes: iframeChanges,
|
|
251
|
+
significantChange: basicDiff.added.length > 0 || richChanged.some(c => c.actionable),
|
|
252
|
+
}).catch(() => { });
|
|
253
|
+
}
|
|
254
|
+
resolve(richResult);
|
|
214
255
|
});
|
|
215
256
|
const timeoutPromise = new Promise((resolve) => {
|
|
216
257
|
setTimeout(() => resolve({ delta_timeout: true }), 5000);
|
|
@@ -232,3 +273,15 @@ export function clearAllSnapshots() {
|
|
|
232
273
|
propSnapshots.clear();
|
|
233
274
|
frameSnapshots.clear();
|
|
234
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Get stored ref entry from snapshot for recovery of detached nodes.
|
|
278
|
+
*/
|
|
279
|
+
export function getStoredRef(targetId, refId) {
|
|
280
|
+
return snapshots.get(targetId)?.refs.get(refId);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Get stored element properties from rich snapshot for recovery.
|
|
284
|
+
*/
|
|
285
|
+
export function getStoredProps(targetId, refId) {
|
|
286
|
+
return propSnapshots.get(targetId)?.props.get(refId);
|
|
287
|
+
}
|
package/dist/state/session.d.ts
CHANGED
|
@@ -15,6 +15,12 @@ export declare class SessionRegistry {
|
|
|
15
15
|
getActive(agentId?: string, appName?: string): BrowserClient | null;
|
|
16
16
|
getMostRecent(agentId?: string): BrowserClient | null;
|
|
17
17
|
setActive(targetId: string, agentId: string, appName?: string): void;
|
|
18
|
+
private lastActiveApp;
|
|
19
|
+
getLastActiveApp(): string | null;
|
|
20
|
+
setLastActiveApp(app?: string | null): void;
|
|
21
|
+
findClientByTargetId(targetId: string): BrowserClient | null;
|
|
22
|
+
getActiveElectronClients(): BrowserClient[];
|
|
23
|
+
isBrowserSessionActive(): boolean;
|
|
18
24
|
getAll(): BrowserClient[];
|
|
19
25
|
getAllForAgent(agentId: string): BrowserClient[];
|
|
20
26
|
register(targetId: string, client: BrowserClient): void;
|
package/dist/state/session.js
CHANGED
|
@@ -85,6 +85,32 @@ export class SessionRegistry {
|
|
|
85
85
|
this.activeTargetIdByAgent.set(key, targetId);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
+
lastActiveApp = null;
|
|
89
|
+
getLastActiveApp() {
|
|
90
|
+
return this.lastActiveApp;
|
|
91
|
+
}
|
|
92
|
+
setLastActiveApp(app) {
|
|
93
|
+
if (!app) {
|
|
94
|
+
this.lastActiveApp = null;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const low = app.toLowerCase();
|
|
98
|
+
if (low !== "browser" && low !== "chrome" && low !== "chromium") {
|
|
99
|
+
this.lastActiveApp = low;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
this.lastActiveApp = null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
findClientByTargetId(targetId) {
|
|
106
|
+
return this.sessions.get(targetId) || null;
|
|
107
|
+
}
|
|
108
|
+
getActiveElectronClients() {
|
|
109
|
+
return Array.from(this.sessions.values()).filter(c => c.isElectron);
|
|
110
|
+
}
|
|
111
|
+
isBrowserSessionActive() {
|
|
112
|
+
return Array.from(this.sessions.values()).some(c => !c.isElectron);
|
|
113
|
+
}
|
|
88
114
|
getAll() {
|
|
89
115
|
return Array.from(this.sessions.values());
|
|
90
116
|
}
|
|
@@ -151,6 +177,7 @@ export class SessionRegistry {
|
|
|
151
177
|
// heartbeat failed — tab may be dead, will be caught by getHealth()
|
|
152
178
|
}
|
|
153
179
|
}, HEARTBEAT_INTERVAL_MS);
|
|
180
|
+
interval.unref();
|
|
154
181
|
this.heartbeatIntervals.set(targetId, interval);
|
|
155
182
|
}
|
|
156
183
|
stopHeartbeat(targetId) {
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
import { type BrowserEngine
|
|
1
|
+
import { type BrowserEngine } from "../config/loader.js";
|
|
2
|
+
import { type DiscoveredElectronApp } from "../desktop/discovery.js";
|
|
3
|
+
export interface ConfiguredAppStatus {
|
|
4
|
+
name: string;
|
|
5
|
+
status: "connected" | "running_no_debug" | "offline";
|
|
6
|
+
configuredPath?: string;
|
|
7
|
+
activeTabs?: {
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
url: string;
|
|
11
|
+
}[];
|
|
12
|
+
port?: number;
|
|
13
|
+
}
|
|
2
14
|
export interface BrowserDetectResult {
|
|
3
15
|
available: {
|
|
4
16
|
engine: BrowserEngine;
|
|
@@ -6,9 +18,10 @@ export interface BrowserDetectResult {
|
|
|
6
18
|
path: string;
|
|
7
19
|
}[];
|
|
8
20
|
current: BrowserEngine;
|
|
9
|
-
|
|
21
|
+
configuredApps?: ConfiguredAppStatus[];
|
|
22
|
+
runningUnconfiguredApps?: DiscoveredElectronApp[];
|
|
10
23
|
toolCoverage: Record<string, number>;
|
|
11
24
|
unsupportedTools: Record<string, string[]>;
|
|
12
25
|
}
|
|
13
|
-
export declare function detectBrowsers(currentEngine: BrowserEngine): BrowserDetectResult
|
|
26
|
+
export declare function detectBrowsers(currentEngine: BrowserEngine): Promise<BrowserDetectResult>;
|
|
14
27
|
export declare function isToolSupported(engine: BrowserEngine, toolName: string): boolean;
|
|
@@ -40,7 +40,11 @@ const ENGINE_COVERAGE = {
|
|
|
40
40
|
],
|
|
41
41
|
},
|
|
42
42
|
};
|
|
43
|
-
|
|
43
|
+
import { sessionRegistry } from "../state/session.js";
|
|
44
|
+
import { getTabList } from "../cdp/connector.js";
|
|
45
|
+
import { getConfigAgentId } from "../config/loader.js";
|
|
46
|
+
import { discoverElectronApps } from "../desktop/discovery.js";
|
|
47
|
+
export async function detectBrowsers(currentEngine) {
|
|
44
48
|
const available = [];
|
|
45
49
|
// Detect Chromium-based browsers
|
|
46
50
|
const allBrowsers = probeAllBrowsers();
|
|
@@ -52,19 +56,60 @@ export function detectBrowsers(currentEngine) {
|
|
|
52
56
|
if (ff) {
|
|
53
57
|
available.push({ engine: "firefox", name: ff.name, path: ff.path });
|
|
54
58
|
}
|
|
55
|
-
// WebKit detection is best-effort (Safari Technology Preview)
|
|
56
|
-
// We do not auto-detect WebKit — only report if manually configured
|
|
57
59
|
const toolCoverage = {};
|
|
58
60
|
const unsupportedMap = {};
|
|
59
61
|
for (const engine of ["chromium", "firefox", "webkit"]) {
|
|
60
62
|
toolCoverage[engine] = ENGINE_COVERAGE[engine].coverage;
|
|
61
63
|
unsupportedMap[engine] = [...ENGINE_COVERAGE[engine].unsupported];
|
|
62
64
|
}
|
|
63
|
-
const
|
|
65
|
+
const config = getCachedConfig();
|
|
66
|
+
const electronApps = getElectronApps(config);
|
|
67
|
+
const runningElectronApps = await discoverElectronApps().catch(() => []);
|
|
68
|
+
const configuredApps = [];
|
|
69
|
+
const runningUnconfiguredApps = [];
|
|
70
|
+
// Identify configured app statuses
|
|
71
|
+
for (const [appName, appCfg] of Object.entries(electronApps)) {
|
|
72
|
+
const clients = sessionRegistry.getAllForAgent(getConfigAgentId(config));
|
|
73
|
+
const activeClient = clients.find(c => c.isElectron && c.appName === appName);
|
|
74
|
+
let status = "offline";
|
|
75
|
+
let activeTabs = [];
|
|
76
|
+
let port;
|
|
77
|
+
if (activeClient) {
|
|
78
|
+
status = "connected";
|
|
79
|
+
port = activeClient.port;
|
|
80
|
+
try {
|
|
81
|
+
const tabs = await getTabList(getConfigAgentId(config), appName);
|
|
82
|
+
activeTabs = tabs.map(t => ({ id: t.id, title: t.title, url: t.url }));
|
|
83
|
+
}
|
|
84
|
+
catch { /* ignore tab list failure */ }
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const running = runningElectronApps.find(r => r.name.toLowerCase() === appName.toLowerCase());
|
|
88
|
+
if (running) {
|
|
89
|
+
status = running.status === "debug_port_open" ? "connected" : "running_no_debug";
|
|
90
|
+
port = running.port;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
configuredApps.push({
|
|
94
|
+
name: appName,
|
|
95
|
+
status,
|
|
96
|
+
configuredPath: appCfg.path,
|
|
97
|
+
activeTabs: activeTabs.length > 0 ? activeTabs : undefined,
|
|
98
|
+
port
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
// Find running apps that are not configured
|
|
102
|
+
for (const running of runningElectronApps) {
|
|
103
|
+
const isConfigured = Object.keys(electronApps).some(n => n.toLowerCase() === running.name.toLowerCase());
|
|
104
|
+
if (!isConfigured) {
|
|
105
|
+
runningUnconfiguredApps.push(running);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
64
108
|
return {
|
|
65
109
|
available,
|
|
66
110
|
current: currentEngine,
|
|
67
|
-
|
|
111
|
+
configuredApps: configuredApps.length > 0 ? configuredApps : undefined,
|
|
112
|
+
runningUnconfiguredApps: runningUnconfiguredApps.length > 0 ? runningUnconfiguredApps : undefined,
|
|
68
113
|
toolCoverage,
|
|
69
114
|
unsupportedTools: unsupportedMap,
|
|
70
115
|
};
|
package/dist/tools/burst.d.ts
CHANGED
|
@@ -5,16 +5,26 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import CDP from "chrome-remote-interface";
|
|
7
7
|
import type { Config } from "../config/loader.js";
|
|
8
|
+
import { type TrailEntry } from "../intelligence/trail.js";
|
|
8
9
|
export interface BurstStep {
|
|
9
|
-
tool:
|
|
10
|
+
tool: string;
|
|
10
11
|
args: Record<string, unknown>;
|
|
11
12
|
}
|
|
12
|
-
/** Macro step types — expanded server-side into multiple primitive calls. */
|
|
13
13
|
export interface BurstMacroStep {
|
|
14
|
-
tool: "type_and_send" | "navigate_and_read" | "click_and_wait" | "scroll_and_read" | "fill_form" | "drag_and_drop" | "hover_and_read";
|
|
14
|
+
tool: "type_and_send" | "navigate_and_read" | "click_and_wait" | "scroll_and_read" | "fill_form" | "drag_and_drop" | "hover_and_read" | string;
|
|
15
15
|
args: Record<string, unknown>;
|
|
16
16
|
}
|
|
17
17
|
export type AnyBurstStep = BurstStep | BurstMacroStep;
|
|
18
|
+
export interface BurstOptions {
|
|
19
|
+
steps?: AnyBurstStep[];
|
|
20
|
+
actions?: AnyBurstStep[];
|
|
21
|
+
compile_from_history?: boolean;
|
|
22
|
+
history_limit?: number;
|
|
23
|
+
dry_run?: boolean;
|
|
24
|
+
stop_on_error?: boolean;
|
|
25
|
+
batch?: boolean;
|
|
26
|
+
app?: string;
|
|
27
|
+
}
|
|
18
28
|
export interface BurstStepResult {
|
|
19
29
|
step: number;
|
|
20
30
|
tool: string;
|
|
@@ -28,9 +38,8 @@ export interface BurstResult {
|
|
|
28
38
|
results: BurstStepResult[];
|
|
29
39
|
aborted: boolean;
|
|
30
40
|
abort_reason?: string;
|
|
41
|
+
compiled_steps?: AnyBurstStep[];
|
|
42
|
+
message?: string;
|
|
31
43
|
}
|
|
32
|
-
export declare function
|
|
33
|
-
|
|
34
|
-
batch?: boolean;
|
|
35
|
-
app?: string;
|
|
36
|
-
}, config: Config): Promise<BurstResult>;
|
|
44
|
+
export declare function compileTraceToMacro(steps: TrailEntry[]): AnyBurstStep[];
|
|
45
|
+
export declare function browserBurst(session: CDP.Client, args: BurstOptions, config: Config): Promise<BurstResult>;
|