btcp-browser-agent 0.1.0 → 0.1.1
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/package.json +8 -9
- package/packages/core/dist/actions.d.ts +97 -0
- package/packages/core/dist/actions.js +940 -0
- package/packages/core/dist/errors.d.ts +138 -0
- package/packages/core/dist/errors.js +157 -0
- package/packages/core/dist/index.d.ts +120 -0
- package/packages/core/dist/index.js +134 -0
- package/packages/core/dist/ref-map.d.ts +16 -0
- package/packages/core/dist/ref-map.js +91 -0
- package/packages/core/dist/snapshot.d.ts +37 -0
- package/packages/core/dist/snapshot.js +751 -0
- package/packages/core/dist/types.d.ts +396 -0
- package/packages/core/dist/types.js +7 -0
- package/packages/extension/dist/background.d.ts +227 -0
- package/packages/extension/dist/background.js +737 -0
- package/packages/extension/dist/content.d.ts +18 -0
- package/packages/extension/dist/content.js +149 -0
- package/packages/extension/dist/index.d.ts +228 -0
- package/packages/extension/dist/index.js +350 -0
- package/packages/extension/dist/session-manager.d.ts +87 -0
- package/packages/extension/dist/session-manager.js +322 -0
- package/packages/extension/{src/session-types.ts → dist/session-types.d.ts} +113 -144
- package/packages/extension/dist/session-types.js +5 -0
- package/packages/extension/dist/types.d.ts +88 -0
- package/packages/extension/dist/types.js +7 -0
- package/CLAUDE.md +0 -230
- package/SKILL.md +0 -143
- package/SNAPSHOT_IMPROVEMENTS.md +0 -302
- package/USAGE.md +0 -146
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/docs/browser-cli-design.md +0 -500
- package/examples/chrome-extension/CHANGELOG.md +0 -210
- package/examples/chrome-extension/DEBUG.md +0 -231
- package/examples/chrome-extension/ERROR_FIXED.md +0 -147
- package/examples/chrome-extension/QUICK_TEST.md +0 -189
- package/examples/chrome-extension/README.md +0 -149
- package/examples/chrome-extension/SESSION_ONLY_MODE.md +0 -305
- package/examples/chrome-extension/TEST_WITH_YOUR_TABS.md +0 -97
- package/examples/chrome-extension/build.js +0 -43
- package/examples/chrome-extension/manifest.json +0 -37
- package/examples/chrome-extension/package-lock.json +0 -1063
- package/examples/chrome-extension/package.json +0 -21
- package/examples/chrome-extension/popup.html +0 -195
- package/examples/chrome-extension/src/background.ts +0 -12
- package/examples/chrome-extension/src/content.ts +0 -7
- package/examples/chrome-extension/src/popup.ts +0 -303
- package/examples/chrome-extension/src/scenario-google-github.ts +0 -389
- package/examples/chrome-extension/test-page.html +0 -127
- package/examples/chrome-extension/tests/README.md +0 -206
- package/examples/chrome-extension/tests/scenario-google-to-github-star.ts +0 -380
- package/examples/chrome-extension/tsconfig.json +0 -14
- package/examples/snapshots/README.md +0 -207
- package/examples/snapshots/amazon-com-detail.html +0 -9528
- package/examples/snapshots/amazon-com-detail.snapshot.txt +0 -997
- package/examples/snapshots/convert-snapshots.ts +0 -97
- package/examples/snapshots/edition-cnn-com.html +0 -13292
- package/examples/snapshots/edition-cnn-com.snapshot.txt +0 -562
- package/examples/snapshots/github-com-microsoft-vscode.html +0 -2916
- package/examples/snapshots/github-com-microsoft-vscode.snapshot.txt +0 -455
- package/examples/snapshots/google-search.html +0 -20012
- package/examples/snapshots/google-search.snapshot.txt +0 -195
- package/examples/snapshots/metadata.json +0 -86
- package/examples/snapshots/npr-org-templates.html +0 -2031
- package/examples/snapshots/npr-org-templates.snapshot.txt +0 -224
- package/examples/snapshots/stackoverflow-com.html +0 -5216
- package/examples/snapshots/stackoverflow-com.snapshot.txt +0 -2404
- package/examples/snapshots/test-all-mode.html +0 -46
- package/examples/snapshots/test-all-mode.snapshot.txt +0 -5
- package/examples/snapshots/validate.test.ts +0 -296
- package/packages/cli/package.json +0 -42
- package/packages/cli/src/__tests__/cli.test.ts +0 -434
- package/packages/cli/src/__tests__/errors.test.ts +0 -226
- package/packages/cli/src/__tests__/executor.test.ts +0 -275
- package/packages/cli/src/__tests__/formatter.test.ts +0 -260
- package/packages/cli/src/__tests__/parser.test.ts +0 -288
- package/packages/cli/src/__tests__/suggestions.test.ts +0 -255
- package/packages/cli/src/commands/back.ts +0 -22
- package/packages/cli/src/commands/check.ts +0 -33
- package/packages/cli/src/commands/clear.ts +0 -33
- package/packages/cli/src/commands/click.ts +0 -32
- package/packages/cli/src/commands/closetab.ts +0 -31
- package/packages/cli/src/commands/eval.ts +0 -41
- package/packages/cli/src/commands/fill.ts +0 -30
- package/packages/cli/src/commands/focus.ts +0 -33
- package/packages/cli/src/commands/forward.ts +0 -22
- package/packages/cli/src/commands/goto.ts +0 -34
- package/packages/cli/src/commands/help.ts +0 -162
- package/packages/cli/src/commands/hover.ts +0 -34
- package/packages/cli/src/commands/index.ts +0 -129
- package/packages/cli/src/commands/newtab.ts +0 -35
- package/packages/cli/src/commands/press.ts +0 -40
- package/packages/cli/src/commands/reload.ts +0 -25
- package/packages/cli/src/commands/screenshot.ts +0 -27
- package/packages/cli/src/commands/scroll.ts +0 -64
- package/packages/cli/src/commands/select.ts +0 -35
- package/packages/cli/src/commands/snapshot.ts +0 -21
- package/packages/cli/src/commands/tab.ts +0 -32
- package/packages/cli/src/commands/tabs.ts +0 -26
- package/packages/cli/src/commands/text.ts +0 -27
- package/packages/cli/src/commands/title.ts +0 -17
- package/packages/cli/src/commands/type.ts +0 -38
- package/packages/cli/src/commands/uncheck.ts +0 -33
- package/packages/cli/src/commands/url.ts +0 -17
- package/packages/cli/src/commands/wait.ts +0 -54
- package/packages/cli/src/errors.ts +0 -164
- package/packages/cli/src/executor.ts +0 -68
- package/packages/cli/src/formatter.ts +0 -215
- package/packages/cli/src/index.ts +0 -257
- package/packages/cli/src/parser.ts +0 -195
- package/packages/cli/src/suggestions.ts +0 -207
- package/packages/cli/src/terminal/Terminal.ts +0 -365
- package/packages/cli/src/terminal/index.ts +0 -5
- package/packages/cli/src/types.ts +0 -155
- package/packages/cli/tsconfig.json +0 -20
- package/packages/core/package.json +0 -35
- package/packages/core/src/actions.ts +0 -1210
- package/packages/core/src/errors.ts +0 -296
- package/packages/core/src/index.test.ts +0 -638
- package/packages/core/src/index.ts +0 -220
- package/packages/core/src/ref-map.ts +0 -107
- package/packages/core/src/snapshot.ts +0 -873
- package/packages/core/src/types.ts +0 -536
- package/packages/core/tsconfig.json +0 -23
- package/packages/extension/README.md +0 -129
- package/packages/extension/package.json +0 -43
- package/packages/extension/src/background.ts +0 -888
- package/packages/extension/src/content.ts +0 -172
- package/packages/extension/src/index.ts +0 -579
- package/packages/extension/src/session-manager.ts +0 -385
- package/packages/extension/src/types.ts +0 -162
- package/packages/extension/tsconfig.json +0 -28
- package/src/index.ts +0 -64
- package/tsconfig.build.json +0 -12
- package/tsconfig.json +0 -26
- package/vitest.config.ts +0 -13
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @btcp/core - Type definitions
|
|
3
|
+
*
|
|
4
|
+
* Core types for DOM automation commands and responses.
|
|
5
|
+
*/
|
|
6
|
+
export type CoreAction = 'click' | 'dblclick' | 'type' | 'fill' | 'clear' | 'check' | 'uncheck' | 'select' | 'focus' | 'blur' | 'hover' | 'scroll' | 'scrollIntoView' | 'snapshot' | 'querySelector' | 'querySelectorAll' | 'getText' | 'getAttribute' | 'getProperty' | 'getBoundingBox' | 'isVisible' | 'isEnabled' | 'isChecked' | 'press' | 'keyDown' | 'keyUp' | 'wait' | 'evaluate' | 'validateElement' | 'validateRefs' | 'highlight' | 'clearHighlight';
|
|
7
|
+
export interface BaseCommand {
|
|
8
|
+
id: string;
|
|
9
|
+
action: CoreAction;
|
|
10
|
+
}
|
|
11
|
+
export type Selector = string;
|
|
12
|
+
export interface ClickCommand extends BaseCommand {
|
|
13
|
+
action: 'click';
|
|
14
|
+
selector: Selector;
|
|
15
|
+
button?: 'left' | 'right' | 'middle';
|
|
16
|
+
clickCount?: number;
|
|
17
|
+
modifiers?: Modifier[];
|
|
18
|
+
}
|
|
19
|
+
export interface DblClickCommand extends BaseCommand {
|
|
20
|
+
action: 'dblclick';
|
|
21
|
+
selector: Selector;
|
|
22
|
+
}
|
|
23
|
+
export interface TypeCommand extends BaseCommand {
|
|
24
|
+
action: 'type';
|
|
25
|
+
selector: Selector;
|
|
26
|
+
text: string;
|
|
27
|
+
delay?: number;
|
|
28
|
+
clear?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface FillCommand extends BaseCommand {
|
|
31
|
+
action: 'fill';
|
|
32
|
+
selector: Selector;
|
|
33
|
+
value: string;
|
|
34
|
+
}
|
|
35
|
+
export interface ClearCommand extends BaseCommand {
|
|
36
|
+
action: 'clear';
|
|
37
|
+
selector: Selector;
|
|
38
|
+
}
|
|
39
|
+
export interface CheckCommand extends BaseCommand {
|
|
40
|
+
action: 'check';
|
|
41
|
+
selector: Selector;
|
|
42
|
+
}
|
|
43
|
+
export interface UncheckCommand extends BaseCommand {
|
|
44
|
+
action: 'uncheck';
|
|
45
|
+
selector: Selector;
|
|
46
|
+
}
|
|
47
|
+
export interface SelectCommand extends BaseCommand {
|
|
48
|
+
action: 'select';
|
|
49
|
+
selector: Selector;
|
|
50
|
+
values: string | string[];
|
|
51
|
+
}
|
|
52
|
+
export interface FocusCommand extends BaseCommand {
|
|
53
|
+
action: 'focus';
|
|
54
|
+
selector: Selector;
|
|
55
|
+
}
|
|
56
|
+
export interface BlurCommand extends BaseCommand {
|
|
57
|
+
action: 'blur';
|
|
58
|
+
selector: Selector;
|
|
59
|
+
}
|
|
60
|
+
export interface HoverCommand extends BaseCommand {
|
|
61
|
+
action: 'hover';
|
|
62
|
+
selector: Selector;
|
|
63
|
+
}
|
|
64
|
+
export interface ScrollCommand extends BaseCommand {
|
|
65
|
+
action: 'scroll';
|
|
66
|
+
selector?: Selector;
|
|
67
|
+
x?: number;
|
|
68
|
+
y?: number;
|
|
69
|
+
direction?: 'up' | 'down' | 'left' | 'right';
|
|
70
|
+
amount?: number;
|
|
71
|
+
}
|
|
72
|
+
export interface ScrollIntoViewCommand extends BaseCommand {
|
|
73
|
+
action: 'scrollIntoView';
|
|
74
|
+
selector: Selector;
|
|
75
|
+
block?: 'start' | 'center' | 'end' | 'nearest';
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Grep options for filtering snapshot output (mirrors Unix grep flags)
|
|
79
|
+
*/
|
|
80
|
+
export interface GrepOptions {
|
|
81
|
+
/** Pattern to search for (regex by default) */
|
|
82
|
+
pattern: string;
|
|
83
|
+
/** Case-insensitive matching (grep -i) */
|
|
84
|
+
ignoreCase?: boolean;
|
|
85
|
+
/** Invert match - return non-matching lines (grep -v) */
|
|
86
|
+
invert?: boolean;
|
|
87
|
+
/** Treat pattern as fixed string, not regex (grep -F) */
|
|
88
|
+
fixedStrings?: boolean;
|
|
89
|
+
}
|
|
90
|
+
export interface SnapshotCommand extends BaseCommand {
|
|
91
|
+
action: 'snapshot';
|
|
92
|
+
selector?: Selector;
|
|
93
|
+
maxDepth?: number;
|
|
94
|
+
includeHidden?: boolean;
|
|
95
|
+
interactive?: boolean;
|
|
96
|
+
compact?: boolean;
|
|
97
|
+
minDepth?: number;
|
|
98
|
+
samplingStrategy?: 'importance' | 'balanced' | 'depth-first';
|
|
99
|
+
contentPreview?: boolean;
|
|
100
|
+
landmarks?: boolean;
|
|
101
|
+
incremental?: boolean;
|
|
102
|
+
baseSnapshot?: SnapshotData;
|
|
103
|
+
all?: boolean;
|
|
104
|
+
format?: 'tree' | 'html';
|
|
105
|
+
/** Filter output lines - simple string or full grep options */
|
|
106
|
+
grep?: string | GrepOptions;
|
|
107
|
+
}
|
|
108
|
+
export interface QuerySelectorCommand extends BaseCommand {
|
|
109
|
+
action: 'querySelector';
|
|
110
|
+
selector: Selector;
|
|
111
|
+
}
|
|
112
|
+
export interface QuerySelectorAllCommand extends BaseCommand {
|
|
113
|
+
action: 'querySelectorAll';
|
|
114
|
+
selector: Selector;
|
|
115
|
+
}
|
|
116
|
+
export interface GetTextCommand extends BaseCommand {
|
|
117
|
+
action: 'getText';
|
|
118
|
+
selector: Selector;
|
|
119
|
+
}
|
|
120
|
+
export interface GetAttributeCommand extends BaseCommand {
|
|
121
|
+
action: 'getAttribute';
|
|
122
|
+
selector: Selector;
|
|
123
|
+
attribute: string;
|
|
124
|
+
}
|
|
125
|
+
export interface GetPropertyCommand extends BaseCommand {
|
|
126
|
+
action: 'getProperty';
|
|
127
|
+
selector: Selector;
|
|
128
|
+
property: string;
|
|
129
|
+
}
|
|
130
|
+
export interface GetBoundingBoxCommand extends BaseCommand {
|
|
131
|
+
action: 'getBoundingBox';
|
|
132
|
+
selector: Selector;
|
|
133
|
+
}
|
|
134
|
+
export interface IsVisibleCommand extends BaseCommand {
|
|
135
|
+
action: 'isVisible';
|
|
136
|
+
selector: Selector;
|
|
137
|
+
}
|
|
138
|
+
export interface IsEnabledCommand extends BaseCommand {
|
|
139
|
+
action: 'isEnabled';
|
|
140
|
+
selector: Selector;
|
|
141
|
+
}
|
|
142
|
+
export interface IsCheckedCommand extends BaseCommand {
|
|
143
|
+
action: 'isChecked';
|
|
144
|
+
selector: Selector;
|
|
145
|
+
}
|
|
146
|
+
export interface PressCommand extends BaseCommand {
|
|
147
|
+
action: 'press';
|
|
148
|
+
key: string;
|
|
149
|
+
selector?: Selector;
|
|
150
|
+
modifiers?: Modifier[];
|
|
151
|
+
}
|
|
152
|
+
export interface KeyDownCommand extends BaseCommand {
|
|
153
|
+
action: 'keyDown';
|
|
154
|
+
key: string;
|
|
155
|
+
}
|
|
156
|
+
export interface KeyUpCommand extends BaseCommand {
|
|
157
|
+
action: 'keyUp';
|
|
158
|
+
key: string;
|
|
159
|
+
}
|
|
160
|
+
export interface WaitCommand extends BaseCommand {
|
|
161
|
+
action: 'wait';
|
|
162
|
+
selector?: Selector;
|
|
163
|
+
state?: 'visible' | 'hidden' | 'attached' | 'detached';
|
|
164
|
+
timeout?: number;
|
|
165
|
+
}
|
|
166
|
+
export interface EvaluateCommand extends BaseCommand {
|
|
167
|
+
action: 'evaluate';
|
|
168
|
+
script: string;
|
|
169
|
+
args?: unknown[];
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Validate element capabilities before attempting an action
|
|
173
|
+
*
|
|
174
|
+
* Allows AI agents to check element compatibility and get actionable feedback
|
|
175
|
+
* before executing commands that might fail.
|
|
176
|
+
*
|
|
177
|
+
* @example Pre-validate before typing
|
|
178
|
+
* ```typescript
|
|
179
|
+
* const validation = await agent.execute({
|
|
180
|
+
* id: 'v1',
|
|
181
|
+
* action: 'validateElement',
|
|
182
|
+
* selector: '#username',
|
|
183
|
+
* capabilities: ['editable']
|
|
184
|
+
* });
|
|
185
|
+
*
|
|
186
|
+
* if (validation.data.compatible) {
|
|
187
|
+
* await agent.execute({
|
|
188
|
+
* id: 'a1',
|
|
189
|
+
* action: 'type',
|
|
190
|
+
* selector: '#username',
|
|
191
|
+
* text: 'user@example.com'
|
|
192
|
+
* });
|
|
193
|
+
* } else {
|
|
194
|
+
* console.log(validation.data.suggestion);
|
|
195
|
+
* }
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
export interface ValidateElementCommand extends BaseCommand {
|
|
199
|
+
action: 'validateElement';
|
|
200
|
+
/** Element selector to validate */
|
|
201
|
+
selector: Selector;
|
|
202
|
+
/** Expected element type (optional) */
|
|
203
|
+
expectedType?: 'input' | 'textarea' | 'button' | 'link' | 'select';
|
|
204
|
+
/** Required capabilities (optional) */
|
|
205
|
+
capabilities?: Array<'clickable' | 'editable' | 'checkable' | 'hoverable'>;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Validate that refs are still valid
|
|
209
|
+
*
|
|
210
|
+
* Checks if refs from a previous snapshot are still valid or have expired.
|
|
211
|
+
* Helps AI agents avoid using stale refs.
|
|
212
|
+
*
|
|
213
|
+
* @example Check ref validity
|
|
214
|
+
* ```typescript
|
|
215
|
+
* const validation = await agent.execute({
|
|
216
|
+
* id: 'v1',
|
|
217
|
+
* action: 'validateRefs',
|
|
218
|
+
* refs: ['@ref:0', '@ref:1', '@ref:2']
|
|
219
|
+
* });
|
|
220
|
+
*
|
|
221
|
+
* // Use only valid refs
|
|
222
|
+
* for (const ref of validation.data.valid) {
|
|
223
|
+
* await agent.execute({ id: '...', action: 'click', selector: ref });
|
|
224
|
+
* }
|
|
225
|
+
*
|
|
226
|
+
* // Handle invalid refs
|
|
227
|
+
* if (validation.data.invalid.length > 0) {
|
|
228
|
+
* // Take new snapshot to get fresh refs
|
|
229
|
+
* await agent.execute({ id: '...', action: 'snapshot' });
|
|
230
|
+
* }
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
export interface ValidateRefsCommand extends BaseCommand {
|
|
234
|
+
action: 'validateRefs';
|
|
235
|
+
/** List of refs to validate */
|
|
236
|
+
refs: string[];
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Display visual overlay labels for interactive elements
|
|
240
|
+
*
|
|
241
|
+
* Shows reference numbers (@ref:0, @ref:1, etc.) as overlay labels
|
|
242
|
+
* positioned near each interactive element from the last snapshot.
|
|
243
|
+
* Labels persist until explicitly cleared.
|
|
244
|
+
*
|
|
245
|
+
* @example Highlight elements after snapshot
|
|
246
|
+
* ```typescript
|
|
247
|
+
* // Take a snapshot first
|
|
248
|
+
* await agent.execute({ id: 's1', action: 'snapshot' });
|
|
249
|
+
*
|
|
250
|
+
* // Show visual highlights
|
|
251
|
+
* await agent.execute({ id: 'h1', action: 'highlight' });
|
|
252
|
+
*
|
|
253
|
+
* // Labels now visible on page with @ref:0, @ref:1, etc.
|
|
254
|
+
* // Use the refs to interact with elements
|
|
255
|
+
* await agent.execute({ id: 'c1', action: 'click', selector: '@ref:5' });
|
|
256
|
+
*
|
|
257
|
+
* // Clear highlights when done
|
|
258
|
+
* await agent.execute({ id: 'ch1', action: 'clearHighlight' });
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
export interface HighlightCommand extends BaseCommand {
|
|
262
|
+
action: 'highlight';
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Remove visual overlay labels
|
|
266
|
+
*
|
|
267
|
+
* Clears all highlight overlays from the page.
|
|
268
|
+
*
|
|
269
|
+
* @example Clear highlights
|
|
270
|
+
* ```typescript
|
|
271
|
+
* await agent.execute({ id: 'ch1', action: 'clearHighlight' });
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
export interface ClearHighlightCommand extends BaseCommand {
|
|
275
|
+
action: 'clearHighlight';
|
|
276
|
+
}
|
|
277
|
+
export type Modifier = 'Alt' | 'Control' | 'Meta' | 'Shift';
|
|
278
|
+
export type Command = ClickCommand | DblClickCommand | TypeCommand | FillCommand | ClearCommand | CheckCommand | UncheckCommand | SelectCommand | FocusCommand | BlurCommand | HoverCommand | ScrollCommand | ScrollIntoViewCommand | SnapshotCommand | QuerySelectorCommand | QuerySelectorAllCommand | GetTextCommand | GetAttributeCommand | GetPropertyCommand | GetBoundingBoxCommand | IsVisibleCommand | IsEnabledCommand | IsCheckedCommand | PressCommand | KeyDownCommand | KeyUpCommand | WaitCommand | EvaluateCommand | ValidateElementCommand | ValidateRefsCommand | HighlightCommand | ClearHighlightCommand;
|
|
279
|
+
export interface SuccessResponse<T = unknown> {
|
|
280
|
+
id: string;
|
|
281
|
+
success: true;
|
|
282
|
+
data: T;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Error response with structured data for AI agents
|
|
286
|
+
*
|
|
287
|
+
* Includes both human-readable error messages and machine-readable
|
|
288
|
+
* error codes, context, and recovery suggestions.
|
|
289
|
+
*/
|
|
290
|
+
export interface ErrorResponse {
|
|
291
|
+
id: string;
|
|
292
|
+
success: false;
|
|
293
|
+
/** Human-readable error message */
|
|
294
|
+
error: string;
|
|
295
|
+
/** Machine-readable error code (optional) */
|
|
296
|
+
errorCode?: string;
|
|
297
|
+
/** Structured error context (optional) */
|
|
298
|
+
errorContext?: {
|
|
299
|
+
selector?: string;
|
|
300
|
+
expectedType?: string;
|
|
301
|
+
actualType?: string;
|
|
302
|
+
elementState?: {
|
|
303
|
+
attached: boolean;
|
|
304
|
+
visible: boolean;
|
|
305
|
+
enabled: boolean;
|
|
306
|
+
};
|
|
307
|
+
availableActions?: string[];
|
|
308
|
+
similarSelectors?: Array<{
|
|
309
|
+
selector: string;
|
|
310
|
+
role: string;
|
|
311
|
+
name: string;
|
|
312
|
+
}>;
|
|
313
|
+
nearbyElements?: Array<{
|
|
314
|
+
ref: string;
|
|
315
|
+
role: string;
|
|
316
|
+
name: string;
|
|
317
|
+
}>;
|
|
318
|
+
[key: string]: any;
|
|
319
|
+
};
|
|
320
|
+
/** Actionable recovery suggestions (optional) */
|
|
321
|
+
suggestions?: string[];
|
|
322
|
+
}
|
|
323
|
+
export type Response<T = unknown> = SuccessResponse<T> | ErrorResponse;
|
|
324
|
+
/**
|
|
325
|
+
* Response data for validateElement command
|
|
326
|
+
*/
|
|
327
|
+
export interface ValidateElementResponse {
|
|
328
|
+
/** Whether element is compatible with requested capabilities */
|
|
329
|
+
compatible: boolean;
|
|
330
|
+
/** Actual element role/tag */
|
|
331
|
+
actualRole: string;
|
|
332
|
+
/** Actual element type (for inputs) */
|
|
333
|
+
actualType?: string;
|
|
334
|
+
/** Capabilities this element supports */
|
|
335
|
+
capabilities: string[];
|
|
336
|
+
/** Current element state */
|
|
337
|
+
state: {
|
|
338
|
+
visible: boolean;
|
|
339
|
+
enabled: boolean;
|
|
340
|
+
attached: boolean;
|
|
341
|
+
};
|
|
342
|
+
/** Suggestion if not compatible */
|
|
343
|
+
suggestion?: string;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Response data for validateRefs command
|
|
347
|
+
*/
|
|
348
|
+
export interface ValidateRefsResponse {
|
|
349
|
+
/** List of valid refs */
|
|
350
|
+
valid: string[];
|
|
351
|
+
/** List of invalid refs */
|
|
352
|
+
invalid: string[];
|
|
353
|
+
/** Reasons why each ref is invalid */
|
|
354
|
+
reasons: Record<string, string>;
|
|
355
|
+
}
|
|
356
|
+
export interface SnapshotNode {
|
|
357
|
+
role: string;
|
|
358
|
+
name?: string;
|
|
359
|
+
ref?: string;
|
|
360
|
+
value?: string;
|
|
361
|
+
checked?: boolean;
|
|
362
|
+
disabled?: boolean;
|
|
363
|
+
children?: SnapshotNode[];
|
|
364
|
+
}
|
|
365
|
+
export interface SnapshotData {
|
|
366
|
+
tree: string;
|
|
367
|
+
refs: Record<string, {
|
|
368
|
+
selector: string;
|
|
369
|
+
role: string;
|
|
370
|
+
name?: string;
|
|
371
|
+
bbox?: BoundingBox;
|
|
372
|
+
inViewport?: boolean;
|
|
373
|
+
importance?: 'primary' | 'secondary' | 'utility';
|
|
374
|
+
context?: string;
|
|
375
|
+
}>;
|
|
376
|
+
metadata?: {
|
|
377
|
+
totalInteractiveElements?: number;
|
|
378
|
+
capturedElements?: number;
|
|
379
|
+
quality?: 'high' | 'medium' | 'low';
|
|
380
|
+
depthLimited?: boolean;
|
|
381
|
+
warnings?: string[];
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
export interface BoundingBox {
|
|
385
|
+
x: number;
|
|
386
|
+
y: number;
|
|
387
|
+
width: number;
|
|
388
|
+
height: number;
|
|
389
|
+
}
|
|
390
|
+
export interface RefMap {
|
|
391
|
+
get(ref: string): Element | null;
|
|
392
|
+
set(ref: string, element: Element): void;
|
|
393
|
+
clear(): void;
|
|
394
|
+
generateRef(element: Element): string;
|
|
395
|
+
}
|
|
396
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @btcp/extension - Background Script
|
|
3
|
+
*
|
|
4
|
+
* Contains BrowserAgent - the high-level orchestrator that runs in the
|
|
5
|
+
* extension's background/service worker context.
|
|
6
|
+
*
|
|
7
|
+
* BrowserAgent manages:
|
|
8
|
+
* - Tab lifecycle (create, close, switch, list)
|
|
9
|
+
* - Navigation (goto, back, forward, reload)
|
|
10
|
+
* - Screenshots (chrome.tabs.captureVisibleTab)
|
|
11
|
+
* - Session state
|
|
12
|
+
* - Routing DOM commands to ContentAgents in target tabs
|
|
13
|
+
*/
|
|
14
|
+
import type { Command, ExtensionCommand, Response, TabInfo, ChromeTab } from './types.js';
|
|
15
|
+
/**
|
|
16
|
+
* TabHandle - Interface for interacting with a specific tab
|
|
17
|
+
*
|
|
18
|
+
* Returned by BackgroundAgent.tab(tabId) for tab-specific operations.
|
|
19
|
+
*/
|
|
20
|
+
export interface TabHandle {
|
|
21
|
+
readonly tabId: number;
|
|
22
|
+
execute(command: Command): Promise<Response>;
|
|
23
|
+
snapshot(options?: {
|
|
24
|
+
selector?: string;
|
|
25
|
+
maxDepth?: number;
|
|
26
|
+
}): Promise<Response>;
|
|
27
|
+
click(selector: string): Promise<Response>;
|
|
28
|
+
fill(selector: string, value: string): Promise<Response>;
|
|
29
|
+
type(selector: string, text: string, options?: {
|
|
30
|
+
clear?: boolean;
|
|
31
|
+
}): Promise<Response>;
|
|
32
|
+
getText(selector: string): Promise<Response>;
|
|
33
|
+
isVisible(selector: string): Promise<Response>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* BackgroundAgent - High-level browser automation orchestrator
|
|
37
|
+
*
|
|
38
|
+
* Runs in the extension's background script/service worker.
|
|
39
|
+
* Manages browser-level operations and routes DOM commands to
|
|
40
|
+
* ContentAgent instances running in content scripts.
|
|
41
|
+
*
|
|
42
|
+
* @example Single tab (default - uses activeTabId)
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const agent = new BackgroundAgent();
|
|
45
|
+
* await agent.navigate('https://example.com');
|
|
46
|
+
* await agent.execute({ id: '1', action: 'click', selector: '#submit' });
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @example Multi-tab with explicit tabId
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const agent = new BackgroundAgent();
|
|
52
|
+
*
|
|
53
|
+
* // Open two tabs
|
|
54
|
+
* const tab1 = await agent.newTab({ url: 'https://google.com' });
|
|
55
|
+
* const tab2 = await agent.newTab({ url: 'https://github.com', active: false });
|
|
56
|
+
*
|
|
57
|
+
* // Interact with specific tabs without switching
|
|
58
|
+
* await agent.tab(tab1.id).click('#search');
|
|
59
|
+
* await agent.tab(tab2.id).snapshot();
|
|
60
|
+
*
|
|
61
|
+
* // Or specify tabId in command
|
|
62
|
+
* await agent.execute({ id: '1', action: 'snapshot' }, { tabId: tab2.id });
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare class BackgroundAgent {
|
|
66
|
+
private activeTabId;
|
|
67
|
+
private sessionManager;
|
|
68
|
+
private heartbeatInterval;
|
|
69
|
+
private readonly HEARTBEAT_INTERVAL;
|
|
70
|
+
constructor();
|
|
71
|
+
private initActiveTab;
|
|
72
|
+
/**
|
|
73
|
+
* Get the current active tab ID
|
|
74
|
+
*/
|
|
75
|
+
getActiveTabId(): number | null;
|
|
76
|
+
/**
|
|
77
|
+
* Set the active tab ID (for manual control)
|
|
78
|
+
*/
|
|
79
|
+
setActiveTabId(tabId: number): void;
|
|
80
|
+
/**
|
|
81
|
+
* Get a handle for interacting with a specific tab
|
|
82
|
+
*
|
|
83
|
+
* This allows you to send commands to any tab without switching the active tab.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* const tab2Handle = browser.tab(tab2.id);
|
|
88
|
+
* await tab2Handle.snapshot();
|
|
89
|
+
* await tab2Handle.click('@ref:5');
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
tab(tabId: number): TabHandle;
|
|
93
|
+
/**
|
|
94
|
+
* Get the currently active tab (only if in session)
|
|
95
|
+
*/
|
|
96
|
+
getActiveTab(): Promise<ChromeTab | null>;
|
|
97
|
+
/**
|
|
98
|
+
* List all tabs (only in session group)
|
|
99
|
+
*/
|
|
100
|
+
listTabs(): Promise<TabInfo[]>;
|
|
101
|
+
/**
|
|
102
|
+
* Create a new tab (only in session group)
|
|
103
|
+
*/
|
|
104
|
+
newTab(options?: {
|
|
105
|
+
url?: string;
|
|
106
|
+
active?: boolean;
|
|
107
|
+
}): Promise<TabInfo>;
|
|
108
|
+
/**
|
|
109
|
+
* Check if a tab is in the active session
|
|
110
|
+
*/
|
|
111
|
+
private isTabInSession;
|
|
112
|
+
/**
|
|
113
|
+
* Close a tab (only if in session)
|
|
114
|
+
*/
|
|
115
|
+
closeTab(tabId?: number): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Switch to a tab (only if in session)
|
|
118
|
+
*/
|
|
119
|
+
switchTab(tabId: number): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Navigate to a URL (only in session tabs)
|
|
122
|
+
*/
|
|
123
|
+
navigate(url: string, options?: {
|
|
124
|
+
waitUntil?: 'load' | 'domcontentloaded';
|
|
125
|
+
}): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Go back in history
|
|
128
|
+
*/
|
|
129
|
+
back(): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Go forward in history
|
|
132
|
+
*/
|
|
133
|
+
forward(): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Reload the current page
|
|
136
|
+
*/
|
|
137
|
+
reload(options?: {
|
|
138
|
+
bypassCache?: boolean;
|
|
139
|
+
}): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* Get the current URL
|
|
142
|
+
*/
|
|
143
|
+
getUrl(): Promise<string>;
|
|
144
|
+
/**
|
|
145
|
+
* Get the page title
|
|
146
|
+
*/
|
|
147
|
+
getTitle(): Promise<string>;
|
|
148
|
+
/**
|
|
149
|
+
* Capture a screenshot of the visible tab
|
|
150
|
+
*/
|
|
151
|
+
screenshot(options?: {
|
|
152
|
+
format?: 'png' | 'jpeg';
|
|
153
|
+
quality?: number;
|
|
154
|
+
}): Promise<string>;
|
|
155
|
+
/**
|
|
156
|
+
* Execute a command - routes to appropriate handler
|
|
157
|
+
*
|
|
158
|
+
* Browser-level commands (navigate, screenshot, tabs) are handled here.
|
|
159
|
+
* DOM-level commands are forwarded to the ContentAgent in the target tab.
|
|
160
|
+
*
|
|
161
|
+
* @param command - The command to execute
|
|
162
|
+
* @param options - Optional settings including target tabId
|
|
163
|
+
*
|
|
164
|
+
* @example Default (active tab)
|
|
165
|
+
* ```typescript
|
|
166
|
+
* await browser.execute({ id: '1', action: 'snapshot' });
|
|
167
|
+
* ```
|
|
168
|
+
*
|
|
169
|
+
* @example Specific tab
|
|
170
|
+
* ```typescript
|
|
171
|
+
* await browser.execute({ id: '1', action: 'snapshot' }, { tabId: 123 });
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
execute(command: Command, options?: {
|
|
175
|
+
tabId?: number;
|
|
176
|
+
}): Promise<Response>;
|
|
177
|
+
/**
|
|
178
|
+
* Send a command to the ContentAgent in a specific tab
|
|
179
|
+
*/
|
|
180
|
+
sendToContentAgent(command: Command, tabId?: number): Promise<Response>;
|
|
181
|
+
/**
|
|
182
|
+
* Send message with automatic content script re-injection on failure
|
|
183
|
+
*/
|
|
184
|
+
private sendMessageWithRetry;
|
|
185
|
+
/**
|
|
186
|
+
* Re-inject content script into a tab (for recovery from frozen state)
|
|
187
|
+
*/
|
|
188
|
+
private reinjectContentScript;
|
|
189
|
+
/**
|
|
190
|
+
* Start heartbeat to monitor session tabs
|
|
191
|
+
*/
|
|
192
|
+
private startHeartbeat;
|
|
193
|
+
/**
|
|
194
|
+
* Stop heartbeat (for cleanup)
|
|
195
|
+
* Note: Currently not called as service workers are terminated by Chrome
|
|
196
|
+
* Could be used if explicit cleanup is needed in the future
|
|
197
|
+
*/
|
|
198
|
+
private _stopHeartbeat;
|
|
199
|
+
/**
|
|
200
|
+
* Ping all session tabs to check health
|
|
201
|
+
*/
|
|
202
|
+
private pingSessionTabs;
|
|
203
|
+
private isExtensionCommand;
|
|
204
|
+
private executeExtensionCommand;
|
|
205
|
+
private waitForTabLoad;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Get or create the BackgroundAgent singleton
|
|
209
|
+
*/
|
|
210
|
+
export declare function getBackgroundAgent(): BackgroundAgent;
|
|
211
|
+
/**
|
|
212
|
+
* @deprecated Use getBackgroundAgent instead
|
|
213
|
+
*/
|
|
214
|
+
export declare const getBrowserAgent: typeof getBackgroundAgent;
|
|
215
|
+
/**
|
|
216
|
+
* Set up the message listener for the background script
|
|
217
|
+
* Call this once in your background.ts to enable command routing
|
|
218
|
+
*/
|
|
219
|
+
export declare function setupMessageListener(): void;
|
|
220
|
+
export declare const handleCommand: (command: Command, _tabId?: number) => Promise<Response>;
|
|
221
|
+
export declare const executeExtensionCommand: (command: ExtensionCommand) => Promise<Response>;
|
|
222
|
+
export declare const sendToContentScript: (_tabId: number, command: Command) => Promise<Response>;
|
|
223
|
+
/**
|
|
224
|
+
* @deprecated Use BackgroundAgent instead
|
|
225
|
+
*/
|
|
226
|
+
export declare const BrowserAgent: typeof BackgroundAgent;
|
|
227
|
+
//# sourceMappingURL=background.d.ts.map
|