btcp-browser-agent 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @btcp/core
|
|
3
|
-
*
|
|
4
|
-
* Core DOM actions for browser automation.
|
|
5
|
-
* Runs in content script context (web page, extension content script, iframe).
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```typescript
|
|
9
|
-
* import { createContentAgent } from '@btcp/core';
|
|
10
|
-
*
|
|
11
|
-
* const agent = createContentAgent(document, window);
|
|
12
|
-
*
|
|
13
|
-
* // Take a snapshot
|
|
14
|
-
* const snapshot = await agent.execute({
|
|
15
|
-
* id: '1',
|
|
16
|
-
* action: 'snapshot'
|
|
17
|
-
* });
|
|
18
|
-
*
|
|
19
|
-
* // Click an element
|
|
20
|
-
* await agent.execute({
|
|
21
|
-
* id: '2',
|
|
22
|
-
* action: 'click',
|
|
23
|
-
* selector: '@ref:5' // From snapshot
|
|
24
|
-
* });
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
import { DOMActions } from './actions.js';
|
|
29
|
-
import { createRefMap, createSimpleRefMap } from './ref-map.js';
|
|
30
|
-
import type { Command, Response, RefMap } from './types.js';
|
|
31
|
-
|
|
32
|
-
export * from './types.js';
|
|
33
|
-
export * from './errors.js';
|
|
34
|
-
export { createSnapshot } from './snapshot.js';
|
|
35
|
-
export { createRefMap, createSimpleRefMap } from './ref-map.js';
|
|
36
|
-
export { DOMActions } from './actions.js';
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* ContentAgent - DOM automation agent that runs in content script context
|
|
40
|
-
*
|
|
41
|
-
* This agent handles all DOM-level operations:
|
|
42
|
-
* - Element interaction (click, type, fill, etc.)
|
|
43
|
-
* - DOM queries (snapshot, getText, getAttribute, etc.)
|
|
44
|
-
* - Keyboard/mouse events
|
|
45
|
-
*
|
|
46
|
-
* Use this in content scripts or directly in web pages.
|
|
47
|
-
* For browser-level operations (tabs, navigation, screenshots),
|
|
48
|
-
* use BrowserAgent from @btcp/extension.
|
|
49
|
-
*/
|
|
50
|
-
export interface ContentAgent {
|
|
51
|
-
/**
|
|
52
|
-
* Execute a command and return a response
|
|
53
|
-
*/
|
|
54
|
-
execute(command: Command): Promise<Response>;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Execute a command from JSON string
|
|
58
|
-
*/
|
|
59
|
-
executeJson(json: string): Promise<string>;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Get the element reference map
|
|
63
|
-
*/
|
|
64
|
-
getRefMap(): RefMap;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Clear all element references
|
|
68
|
-
*/
|
|
69
|
-
clearRefs(): void;
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Message handler for chrome.runtime.onMessage
|
|
73
|
-
*
|
|
74
|
-
* @example
|
|
75
|
-
* ```typescript
|
|
76
|
-
* const agent = createContentAgent();
|
|
77
|
-
* chrome.runtime.onMessage.addListener(agent.handleMessage);
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
handleMessage: (
|
|
81
|
-
message: unknown,
|
|
82
|
-
sender: unknown,
|
|
83
|
-
sendResponse: (response: unknown) => void
|
|
84
|
-
) => boolean;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Create a ContentAgent for DOM automation
|
|
89
|
-
*
|
|
90
|
-
* @param doc - The document to operate on (defaults to current document)
|
|
91
|
-
* @param win - The window context (defaults to current window)
|
|
92
|
-
* @returns A ContentAgent instance
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* ```typescript
|
|
96
|
-
* // In content script
|
|
97
|
-
* const agent = createContentAgent();
|
|
98
|
-
*
|
|
99
|
-
* // Take a snapshot of the page
|
|
100
|
-
* const { data } = await agent.execute({ id: '1', action: 'snapshot' });
|
|
101
|
-
*
|
|
102
|
-
* // Click an element using ref from snapshot
|
|
103
|
-
* await agent.execute({ id: '2', action: 'click', selector: '@ref:5' });
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
|
-
export function createContentAgent(doc: Document = document, win: Window = window): ContentAgent {
|
|
107
|
-
// Use WeakRef-based map if available for better memory management
|
|
108
|
-
const refMap = typeof WeakRef !== 'undefined'
|
|
109
|
-
? createRefMap()
|
|
110
|
-
: createSimpleRefMap();
|
|
111
|
-
|
|
112
|
-
const actions = new DOMActions(doc, win, refMap);
|
|
113
|
-
|
|
114
|
-
const agent: ContentAgent = {
|
|
115
|
-
async execute(command: Command): Promise<Response> {
|
|
116
|
-
return actions.execute(command);
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
async executeJson(json: string): Promise<string> {
|
|
120
|
-
try {
|
|
121
|
-
const command = JSON.parse(json) as Command;
|
|
122
|
-
const response = await actions.execute(command);
|
|
123
|
-
return JSON.stringify(response);
|
|
124
|
-
} catch (error) {
|
|
125
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
126
|
-
return JSON.stringify({
|
|
127
|
-
id: 'unknown',
|
|
128
|
-
success: false,
|
|
129
|
-
error: `Failed to parse command: ${message}`,
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
|
|
134
|
-
getRefMap(): RefMap {
|
|
135
|
-
return refMap;
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
clearRefs(): void {
|
|
139
|
-
refMap.clear();
|
|
140
|
-
actions.invalidateSnapshot();
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
handleMessage(
|
|
144
|
-
message: unknown,
|
|
145
|
-
_sender: unknown,
|
|
146
|
-
sendResponse: (response: unknown) => void
|
|
147
|
-
): boolean {
|
|
148
|
-
const msg = message as { type?: string; command?: Command };
|
|
149
|
-
if (msg?.type !== 'btcp:command') return false;
|
|
150
|
-
|
|
151
|
-
agent.execute(msg.command!).then(response => {
|
|
152
|
-
sendResponse({ type: 'btcp:response', response });
|
|
153
|
-
}).catch(error => {
|
|
154
|
-
sendResponse({
|
|
155
|
-
type: 'btcp:response',
|
|
156
|
-
response: {
|
|
157
|
-
id: msg.command?.id ?? 'unknown',
|
|
158
|
-
success: false,
|
|
159
|
-
error: error instanceof Error ? error.message : String(error),
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
return true; // Keep channel open for async response
|
|
165
|
-
},
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
return agent;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* @deprecated Use createContentAgent instead
|
|
173
|
-
*/
|
|
174
|
-
export const createAgent = createContentAgent;
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* @deprecated Use ContentAgent instead
|
|
178
|
-
*/
|
|
179
|
-
export type Agent = ContentAgent;
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Message types for extension communication
|
|
183
|
-
*/
|
|
184
|
-
export interface AgentMessage {
|
|
185
|
-
type: 'aspect:command';
|
|
186
|
-
command: Command;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export interface AgentResponse {
|
|
190
|
-
type: 'aspect:response';
|
|
191
|
-
response: Response;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Install message listener for extension communication
|
|
196
|
-
* Call this in your content script to enable command execution via postMessage
|
|
197
|
-
*
|
|
198
|
-
* @param agent - The agent instance
|
|
199
|
-
* @returns Cleanup function to remove the listener
|
|
200
|
-
*/
|
|
201
|
-
export function installMessageListener(agent: Agent): () => void {
|
|
202
|
-
const handler = async (event: MessageEvent) => {
|
|
203
|
-
// Only accept messages from same window
|
|
204
|
-
if (event.source !== window) return;
|
|
205
|
-
|
|
206
|
-
const data = event.data as AgentMessage;
|
|
207
|
-
if (data?.type !== 'aspect:command') return;
|
|
208
|
-
|
|
209
|
-
const response = await agent.execute(data.command);
|
|
210
|
-
|
|
211
|
-
window.postMessage({
|
|
212
|
-
type: 'aspect:response',
|
|
213
|
-
response,
|
|
214
|
-
} satisfies AgentResponse, '*');
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
window.addEventListener('message', handler);
|
|
218
|
-
|
|
219
|
-
return () => window.removeEventListener('message', handler);
|
|
220
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @btcp/core - Element Reference Map
|
|
3
|
-
*
|
|
4
|
-
* Maintains a mapping between string refs and DOM elements.
|
|
5
|
-
* Used by the snapshot system to enable @ref:xxx selectors.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { RefMap } from './types.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Create a new element reference map
|
|
12
|
-
*/
|
|
13
|
-
export function createRefMap(): RefMap {
|
|
14
|
-
const map = new Map<string, WeakRef<Element>>();
|
|
15
|
-
let counter = 0;
|
|
16
|
-
|
|
17
|
-
return {
|
|
18
|
-
get(ref: string): Element | null {
|
|
19
|
-
const weakRef = map.get(ref);
|
|
20
|
-
if (!weakRef) return null;
|
|
21
|
-
|
|
22
|
-
const element = weakRef.deref();
|
|
23
|
-
if (!element) {
|
|
24
|
-
// Element was garbage collected
|
|
25
|
-
map.delete(ref);
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Check if element is still in DOM
|
|
30
|
-
if (!element.isConnected) {
|
|
31
|
-
map.delete(ref);
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return element;
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
set(ref: string, element: Element): void {
|
|
39
|
-
map.set(ref, new WeakRef(element));
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
clear(): void {
|
|
43
|
-
map.clear();
|
|
44
|
-
counter = 0;
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
generateRef(element: Element): string {
|
|
48
|
-
// Check if element already has a ref
|
|
49
|
-
for (const [ref, weakRef] of map.entries()) {
|
|
50
|
-
if (weakRef.deref() === element) {
|
|
51
|
-
return ref;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Generate new ref
|
|
56
|
-
const ref = `@ref:${counter++}`;
|
|
57
|
-
map.set(ref, new WeakRef(element));
|
|
58
|
-
return ref;
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Simple ref map without WeakRef (for environments that don't support it)
|
|
65
|
-
*/
|
|
66
|
-
export function createSimpleRefMap(): RefMap {
|
|
67
|
-
const map = new Map<string, Element>();
|
|
68
|
-
let counter = 0;
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
get(ref: string): Element | null {
|
|
72
|
-
const element = map.get(ref);
|
|
73
|
-
if (!element) return null;
|
|
74
|
-
|
|
75
|
-
// Check if element is still in DOM
|
|
76
|
-
if (!element.isConnected) {
|
|
77
|
-
map.delete(ref);
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return element;
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
set(ref: string, element: Element): void {
|
|
85
|
-
map.set(ref, element);
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
clear(): void {
|
|
89
|
-
map.clear();
|
|
90
|
-
counter = 0;
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
generateRef(element: Element): string {
|
|
94
|
-
// Check if element already has a ref
|
|
95
|
-
for (const [ref, el] of map.entries()) {
|
|
96
|
-
if (el === element) {
|
|
97
|
-
return ref;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Generate new ref
|
|
102
|
-
const ref = `@ref:${counter++}`;
|
|
103
|
-
map.set(ref, element);
|
|
104
|
-
return ref;
|
|
105
|
-
},
|
|
106
|
-
};
|
|
107
|
-
}
|