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.
Files changed (136) hide show
  1. package/package.json +8 -9
  2. package/packages/core/dist/actions.d.ts +97 -0
  3. package/packages/core/dist/actions.js +940 -0
  4. package/packages/core/dist/errors.d.ts +138 -0
  5. package/packages/core/dist/errors.js +157 -0
  6. package/packages/core/dist/index.d.ts +120 -0
  7. package/packages/core/dist/index.js +134 -0
  8. package/packages/core/dist/ref-map.d.ts +16 -0
  9. package/packages/core/dist/ref-map.js +91 -0
  10. package/packages/core/dist/snapshot.d.ts +37 -0
  11. package/packages/core/dist/snapshot.js +751 -0
  12. package/packages/core/dist/types.d.ts +396 -0
  13. package/packages/core/dist/types.js +7 -0
  14. package/packages/extension/dist/background.d.ts +227 -0
  15. package/packages/extension/dist/background.js +737 -0
  16. package/packages/extension/dist/content.d.ts +18 -0
  17. package/packages/extension/dist/content.js +149 -0
  18. package/packages/extension/dist/index.d.ts +228 -0
  19. package/packages/extension/dist/index.js +350 -0
  20. package/packages/extension/dist/session-manager.d.ts +87 -0
  21. package/packages/extension/dist/session-manager.js +322 -0
  22. package/packages/extension/{src/session-types.ts → dist/session-types.d.ts} +113 -144
  23. package/packages/extension/dist/session-types.js +5 -0
  24. package/packages/extension/dist/types.d.ts +88 -0
  25. package/packages/extension/dist/types.js +7 -0
  26. package/CLAUDE.md +0 -230
  27. package/SKILL.md +0 -143
  28. package/SNAPSHOT_IMPROVEMENTS.md +0 -302
  29. package/USAGE.md +0 -146
  30. package/dist/index.d.ts.map +0 -1
  31. package/dist/index.js.map +0 -1
  32. package/docs/browser-cli-design.md +0 -500
  33. package/examples/chrome-extension/CHANGELOG.md +0 -210
  34. package/examples/chrome-extension/DEBUG.md +0 -231
  35. package/examples/chrome-extension/ERROR_FIXED.md +0 -147
  36. package/examples/chrome-extension/QUICK_TEST.md +0 -189
  37. package/examples/chrome-extension/README.md +0 -149
  38. package/examples/chrome-extension/SESSION_ONLY_MODE.md +0 -305
  39. package/examples/chrome-extension/TEST_WITH_YOUR_TABS.md +0 -97
  40. package/examples/chrome-extension/build.js +0 -43
  41. package/examples/chrome-extension/manifest.json +0 -37
  42. package/examples/chrome-extension/package-lock.json +0 -1063
  43. package/examples/chrome-extension/package.json +0 -21
  44. package/examples/chrome-extension/popup.html +0 -195
  45. package/examples/chrome-extension/src/background.ts +0 -12
  46. package/examples/chrome-extension/src/content.ts +0 -7
  47. package/examples/chrome-extension/src/popup.ts +0 -303
  48. package/examples/chrome-extension/src/scenario-google-github.ts +0 -389
  49. package/examples/chrome-extension/test-page.html +0 -127
  50. package/examples/chrome-extension/tests/README.md +0 -206
  51. package/examples/chrome-extension/tests/scenario-google-to-github-star.ts +0 -380
  52. package/examples/chrome-extension/tsconfig.json +0 -14
  53. package/examples/snapshots/README.md +0 -207
  54. package/examples/snapshots/amazon-com-detail.html +0 -9528
  55. package/examples/snapshots/amazon-com-detail.snapshot.txt +0 -997
  56. package/examples/snapshots/convert-snapshots.ts +0 -97
  57. package/examples/snapshots/edition-cnn-com.html +0 -13292
  58. package/examples/snapshots/edition-cnn-com.snapshot.txt +0 -562
  59. package/examples/snapshots/github-com-microsoft-vscode.html +0 -2916
  60. package/examples/snapshots/github-com-microsoft-vscode.snapshot.txt +0 -455
  61. package/examples/snapshots/google-search.html +0 -20012
  62. package/examples/snapshots/google-search.snapshot.txt +0 -195
  63. package/examples/snapshots/metadata.json +0 -86
  64. package/examples/snapshots/npr-org-templates.html +0 -2031
  65. package/examples/snapshots/npr-org-templates.snapshot.txt +0 -224
  66. package/examples/snapshots/stackoverflow-com.html +0 -5216
  67. package/examples/snapshots/stackoverflow-com.snapshot.txt +0 -2404
  68. package/examples/snapshots/test-all-mode.html +0 -46
  69. package/examples/snapshots/test-all-mode.snapshot.txt +0 -5
  70. package/examples/snapshots/validate.test.ts +0 -296
  71. package/packages/cli/package.json +0 -42
  72. package/packages/cli/src/__tests__/cli.test.ts +0 -434
  73. package/packages/cli/src/__tests__/errors.test.ts +0 -226
  74. package/packages/cli/src/__tests__/executor.test.ts +0 -275
  75. package/packages/cli/src/__tests__/formatter.test.ts +0 -260
  76. package/packages/cli/src/__tests__/parser.test.ts +0 -288
  77. package/packages/cli/src/__tests__/suggestions.test.ts +0 -255
  78. package/packages/cli/src/commands/back.ts +0 -22
  79. package/packages/cli/src/commands/check.ts +0 -33
  80. package/packages/cli/src/commands/clear.ts +0 -33
  81. package/packages/cli/src/commands/click.ts +0 -32
  82. package/packages/cli/src/commands/closetab.ts +0 -31
  83. package/packages/cli/src/commands/eval.ts +0 -41
  84. package/packages/cli/src/commands/fill.ts +0 -30
  85. package/packages/cli/src/commands/focus.ts +0 -33
  86. package/packages/cli/src/commands/forward.ts +0 -22
  87. package/packages/cli/src/commands/goto.ts +0 -34
  88. package/packages/cli/src/commands/help.ts +0 -162
  89. package/packages/cli/src/commands/hover.ts +0 -34
  90. package/packages/cli/src/commands/index.ts +0 -129
  91. package/packages/cli/src/commands/newtab.ts +0 -35
  92. package/packages/cli/src/commands/press.ts +0 -40
  93. package/packages/cli/src/commands/reload.ts +0 -25
  94. package/packages/cli/src/commands/screenshot.ts +0 -27
  95. package/packages/cli/src/commands/scroll.ts +0 -64
  96. package/packages/cli/src/commands/select.ts +0 -35
  97. package/packages/cli/src/commands/snapshot.ts +0 -21
  98. package/packages/cli/src/commands/tab.ts +0 -32
  99. package/packages/cli/src/commands/tabs.ts +0 -26
  100. package/packages/cli/src/commands/text.ts +0 -27
  101. package/packages/cli/src/commands/title.ts +0 -17
  102. package/packages/cli/src/commands/type.ts +0 -38
  103. package/packages/cli/src/commands/uncheck.ts +0 -33
  104. package/packages/cli/src/commands/url.ts +0 -17
  105. package/packages/cli/src/commands/wait.ts +0 -54
  106. package/packages/cli/src/errors.ts +0 -164
  107. package/packages/cli/src/executor.ts +0 -68
  108. package/packages/cli/src/formatter.ts +0 -215
  109. package/packages/cli/src/index.ts +0 -257
  110. package/packages/cli/src/parser.ts +0 -195
  111. package/packages/cli/src/suggestions.ts +0 -207
  112. package/packages/cli/src/terminal/Terminal.ts +0 -365
  113. package/packages/cli/src/terminal/index.ts +0 -5
  114. package/packages/cli/src/types.ts +0 -155
  115. package/packages/cli/tsconfig.json +0 -20
  116. package/packages/core/package.json +0 -35
  117. package/packages/core/src/actions.ts +0 -1210
  118. package/packages/core/src/errors.ts +0 -296
  119. package/packages/core/src/index.test.ts +0 -638
  120. package/packages/core/src/index.ts +0 -220
  121. package/packages/core/src/ref-map.ts +0 -107
  122. package/packages/core/src/snapshot.ts +0 -873
  123. package/packages/core/src/types.ts +0 -536
  124. package/packages/core/tsconfig.json +0 -23
  125. package/packages/extension/README.md +0 -129
  126. package/packages/extension/package.json +0 -43
  127. package/packages/extension/src/background.ts +0 -888
  128. package/packages/extension/src/content.ts +0 -172
  129. package/packages/extension/src/index.ts +0 -579
  130. package/packages/extension/src/session-manager.ts +0 -385
  131. package/packages/extension/src/types.ts +0 -162
  132. package/packages/extension/tsconfig.json +0 -28
  133. package/src/index.ts +0 -64
  134. package/tsconfig.build.json +0 -12
  135. package/tsconfig.json +0 -26
  136. package/vitest.config.ts +0 -13
@@ -0,0 +1,350 @@
1
+ /**
2
+ * @btcp/extension
3
+ *
4
+ * Chrome extension bridge for browser automation.
5
+ *
6
+ * Architecture:
7
+ * - BackgroundAgent: Runs in background script, manages tabs/navigation/screenshots
8
+ * - ContentAgent: Runs in content scripts, handles DOM operations (from @btcp/core)
9
+ * - Client: API for sending commands from popup or external scripts
10
+ *
11
+ * @example Background script setup:
12
+ * ```typescript
13
+ * import { BackgroundAgent, setupMessageListener } from '@btcp/extension';
14
+ *
15
+ * // Set up message routing
16
+ * setupMessageListener();
17
+ *
18
+ * // Or use BackgroundAgent directly
19
+ * const agent = new BackgroundAgent();
20
+ * await agent.navigate('https://example.com');
21
+ * await agent.screenshot();
22
+ * ```
23
+ *
24
+ * @example Content script setup:
25
+ * ```typescript
26
+ * import { createContentAgent } from '@btcp/core';
27
+ *
28
+ * const agent = createContentAgent();
29
+ * await agent.execute({ id: '1', action: 'snapshot' });
30
+ * ```
31
+ *
32
+ * @example Popup/external usage:
33
+ * ```typescript
34
+ * import { createClient } from '@btcp/extension';
35
+ *
36
+ * const client = createClient();
37
+ * await client.navigate('https://example.com');
38
+ * const snapshot = await client.snapshot();
39
+ * await client.click('@ref:5');
40
+ * ```
41
+ */
42
+ // Import for local use (and re-export below)
43
+ import { BackgroundAgent as _BackgroundAgent, getBackgroundAgent as _getBackgroundAgent, setupMessageListener as _setupMessageListener, BrowserAgent as _BrowserAgent, getBrowserAgent as _getBrowserAgent, } from './background.js';
44
+ export * from './types.js';
45
+ // Re-export BackgroundAgent for background script usage
46
+ export { _BackgroundAgent as BackgroundAgent, _getBackgroundAgent as getBackgroundAgent, _setupMessageListener as setupMessageListener,
47
+ // Deprecated aliases for backwards compatibility
48
+ _BrowserAgent as BrowserAgent, _getBrowserAgent as getBrowserAgent, };
49
+ // Re-export ContentAgent for content script usage
50
+ export { createContentAgent } from '@btcp/core';
51
+ let commandIdCounter = 0;
52
+ function generateCommandId() {
53
+ return `cmd_${Date.now()}_${commandIdCounter++}`;
54
+ }
55
+ /**
56
+ * Check if we're running in a background/service worker context
57
+ */
58
+ function isBackgroundContext() {
59
+ // In Manifest V3, background scripts run as service workers
60
+ return typeof ServiceWorkerGlobalScope !== 'undefined' && self instanceof ServiceWorkerGlobalScope;
61
+ }
62
+ /**
63
+ * Create a client for communicating with the extension
64
+ *
65
+ * This function works in both popup/content scripts and background scripts:
66
+ * - In popup/content scripts: Uses chrome.runtime.sendMessage to communicate with background
67
+ * - In background scripts: Uses BackgroundAgent directly for better performance
68
+ *
69
+ * @example Popup usage:
70
+ * ```typescript
71
+ * import { createClient } from '@btcp/browser-agent/extension';
72
+ * const client = createClient();
73
+ * await client.navigate('https://example.com');
74
+ * ```
75
+ *
76
+ * @example Background script usage:
77
+ * ```typescript
78
+ * import { createClient } from '@btcp/browser-agent/extension';
79
+ * const client = createClient();
80
+ * // Works the same way - commands go directly to BackgroundAgent
81
+ * await client.navigate('https://example.com');
82
+ * ```
83
+ */
84
+ export function createClient() {
85
+ // Detect if we're in background context
86
+ const inBackground = isBackgroundContext();
87
+ // Lazily get the background agent to avoid circular dependency issues
88
+ let bgAgent = null;
89
+ function getAgent() {
90
+ if (!bgAgent) {
91
+ // Use the singleton getter from background.js
92
+ bgAgent = _getBackgroundAgent();
93
+ }
94
+ return bgAgent;
95
+ }
96
+ async function sendCommand(command) {
97
+ // In background context, use BackgroundAgent directly
98
+ if (inBackground) {
99
+ return getAgent().execute(command);
100
+ }
101
+ // In popup/content context, use message passing
102
+ return new Promise((resolve) => {
103
+ chrome.runtime.sendMessage({ type: 'btcp:command', command }, (response) => {
104
+ if (chrome.runtime.lastError) {
105
+ resolve({
106
+ id: command.id,
107
+ success: false,
108
+ error: chrome.runtime.lastError.message || 'Unknown error',
109
+ });
110
+ }
111
+ else {
112
+ const resp = response;
113
+ if (resp.type === 'btcp:response') {
114
+ resolve(resp.response);
115
+ }
116
+ else {
117
+ // Unexpected pong response
118
+ resolve({
119
+ id: command.id,
120
+ success: false,
121
+ error: 'Unexpected response type',
122
+ });
123
+ }
124
+ }
125
+ });
126
+ });
127
+ }
128
+ function assertSuccess(response) {
129
+ if (!response.success) {
130
+ throw new Error(response.error);
131
+ }
132
+ }
133
+ return {
134
+ execute: sendCommand,
135
+ // Navigation
136
+ async navigate(url, options) {
137
+ return sendCommand({
138
+ id: generateCommandId(),
139
+ action: 'navigate',
140
+ url,
141
+ waitUntil: options?.waitUntil,
142
+ });
143
+ },
144
+ async back() {
145
+ return sendCommand({ id: generateCommandId(), action: 'back' });
146
+ },
147
+ async forward() {
148
+ return sendCommand({ id: generateCommandId(), action: 'forward' });
149
+ },
150
+ async reload(options) {
151
+ return sendCommand({
152
+ id: generateCommandId(),
153
+ action: 'reload',
154
+ bypassCache: options?.bypassCache,
155
+ });
156
+ },
157
+ async getUrl() {
158
+ const response = await sendCommand({ id: generateCommandId(), action: 'getUrl' });
159
+ assertSuccess(response);
160
+ return response.data.url;
161
+ },
162
+ async getTitle() {
163
+ const response = await sendCommand({ id: generateCommandId(), action: 'getTitle' });
164
+ assertSuccess(response);
165
+ return response.data.title;
166
+ },
167
+ // DOM
168
+ async snapshot(options) {
169
+ const response = await sendCommand({
170
+ id: generateCommandId(),
171
+ action: 'snapshot',
172
+ selector: options?.selector,
173
+ maxDepth: options?.maxDepth,
174
+ interactive: options?.interactive,
175
+ compact: options?.compact,
176
+ format: options?.format,
177
+ });
178
+ assertSuccess(response);
179
+ return response.data;
180
+ },
181
+ async click(selector, options) {
182
+ return sendCommand({
183
+ id: generateCommandId(),
184
+ action: 'click',
185
+ selector,
186
+ button: options?.button,
187
+ });
188
+ },
189
+ async type(selector, text, options) {
190
+ return sendCommand({
191
+ id: generateCommandId(),
192
+ action: 'type',
193
+ selector,
194
+ text,
195
+ delay: options?.delay,
196
+ clear: options?.clear,
197
+ });
198
+ },
199
+ async fill(selector, value) {
200
+ return sendCommand({
201
+ id: generateCommandId(),
202
+ action: 'fill',
203
+ selector,
204
+ value,
205
+ });
206
+ },
207
+ async getText(selector) {
208
+ const response = await sendCommand({
209
+ id: generateCommandId(),
210
+ action: 'getText',
211
+ selector,
212
+ });
213
+ assertSuccess(response);
214
+ return response.data.text;
215
+ },
216
+ async isVisible(selector) {
217
+ const response = await sendCommand({
218
+ id: generateCommandId(),
219
+ action: 'isVisible',
220
+ selector,
221
+ });
222
+ assertSuccess(response);
223
+ return response.data.visible;
224
+ },
225
+ // Tabs
226
+ async screenshot(options) {
227
+ const response = await sendCommand({
228
+ id: generateCommandId(),
229
+ action: 'screenshot',
230
+ format: options?.format,
231
+ quality: options?.quality,
232
+ });
233
+ assertSuccess(response);
234
+ return response.data.screenshot;
235
+ },
236
+ async tabNew(options) {
237
+ const response = await sendCommand({
238
+ id: generateCommandId(),
239
+ action: 'tabNew',
240
+ url: options?.url,
241
+ active: options?.active,
242
+ });
243
+ assertSuccess(response);
244
+ return response.data;
245
+ },
246
+ async tabClose(tabId) {
247
+ return sendCommand({
248
+ id: generateCommandId(),
249
+ action: 'tabClose',
250
+ tabId,
251
+ });
252
+ },
253
+ async tabSwitch(tabId) {
254
+ return sendCommand({
255
+ id: generateCommandId(),
256
+ action: 'tabSwitch',
257
+ tabId,
258
+ });
259
+ },
260
+ async tabList() {
261
+ const response = await sendCommand({
262
+ id: generateCommandId(),
263
+ action: 'tabList',
264
+ });
265
+ assertSuccess(response);
266
+ return response.data.tabs;
267
+ },
268
+ // Tab Groups & Sessions
269
+ async groupCreate(options) {
270
+ const response = await sendCommand({
271
+ id: generateCommandId(),
272
+ action: 'groupCreate',
273
+ tabIds: options?.tabIds,
274
+ title: options?.title,
275
+ color: options?.color,
276
+ collapsed: options?.collapsed,
277
+ });
278
+ assertSuccess(response);
279
+ return response.data;
280
+ },
281
+ async groupUpdate(groupId, options) {
282
+ const response = await sendCommand({
283
+ id: generateCommandId(),
284
+ action: 'groupUpdate',
285
+ groupId,
286
+ title: options.title,
287
+ color: options.color,
288
+ collapsed: options.collapsed,
289
+ });
290
+ assertSuccess(response);
291
+ return response.data;
292
+ },
293
+ async groupDelete(groupId) {
294
+ return sendCommand({
295
+ id: generateCommandId(),
296
+ action: 'groupDelete',
297
+ groupId,
298
+ });
299
+ },
300
+ async groupList() {
301
+ const response = await sendCommand({
302
+ id: generateCommandId(),
303
+ action: 'groupList',
304
+ });
305
+ assertSuccess(response);
306
+ return response.data.groups;
307
+ },
308
+ async groupAddTabs(groupId, tabIds) {
309
+ return sendCommand({
310
+ id: generateCommandId(),
311
+ action: 'groupAddTabs',
312
+ groupId,
313
+ tabIds,
314
+ });
315
+ },
316
+ async groupRemoveTabs(tabIds) {
317
+ return sendCommand({
318
+ id: generateCommandId(),
319
+ action: 'groupRemoveTabs',
320
+ tabIds,
321
+ });
322
+ },
323
+ async groupGet(groupId) {
324
+ const response = await sendCommand({
325
+ id: generateCommandId(),
326
+ action: 'groupGet',
327
+ groupId,
328
+ });
329
+ assertSuccess(response);
330
+ return response.data;
331
+ },
332
+ async sessionGetCurrent() {
333
+ const response = await sendCommand({
334
+ id: generateCommandId(),
335
+ action: 'sessionGetCurrent',
336
+ });
337
+ assertSuccess(response);
338
+ return response.data;
339
+ },
340
+ async popupInitialize() {
341
+ const response = await sendCommand({
342
+ id: generateCommandId(),
343
+ action: 'popupInitialize',
344
+ });
345
+ assertSuccess(response);
346
+ return response.data;
347
+ },
348
+ };
349
+ }
350
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,87 @@
1
+ /**
2
+ * SessionManager - Manages tab groups and sessions for BTCP Browser Agent
3
+ */
4
+ import type { GroupInfo, SessionInfo, GroupCreateOptions, GroupUpdateOptions } from './session-types.js';
5
+ /**
6
+ * SessionManager handles Chrome tab group operations and session state
7
+ */
8
+ export declare class SessionManager {
9
+ private activeSessionGroupId;
10
+ private sessionCounter;
11
+ private initialized;
12
+ constructor();
13
+ /**
14
+ * Restore session from storage
15
+ */
16
+ private restoreSession;
17
+ /**
18
+ * Persist session to storage
19
+ */
20
+ private persistSession;
21
+ /**
22
+ * Clear stored session
23
+ */
24
+ private clearStoredSession;
25
+ /**
26
+ * Reconnect to a specific session group
27
+ * Used when popup detects a stored session that isn't currently active
28
+ */
29
+ reconnectSession(groupId: number): Promise<boolean>;
30
+ /**
31
+ * Create a new tab group
32
+ */
33
+ createGroup(options?: GroupCreateOptions): Promise<GroupInfo>;
34
+ /**
35
+ * Update an existing tab group
36
+ */
37
+ updateGroup(groupId: number, options: GroupUpdateOptions): Promise<GroupInfo>;
38
+ /**
39
+ * Delete a tab group (closes all tabs in the group)
40
+ */
41
+ deleteGroup(groupId: number): Promise<void>;
42
+ /**
43
+ * List all tab groups
44
+ */
45
+ listGroups(): Promise<GroupInfo[]>;
46
+ /**
47
+ * Get a specific tab group
48
+ */
49
+ getGroup(groupId: number): Promise<GroupInfo>;
50
+ /**
51
+ * Add tabs to a group
52
+ */
53
+ addTabsToGroup(groupId: number, tabIds: number[]): Promise<void>;
54
+ /**
55
+ * Remove tabs from their group (ungroup them)
56
+ */
57
+ removeTabsFromGroup(tabIds: number[]): Promise<void>;
58
+ /**
59
+ * Get current active session info
60
+ */
61
+ getCurrentSession(): Promise<SessionInfo | null>;
62
+ /**
63
+ * Get the active session group ID
64
+ */
65
+ getActiveSessionGroupId(): number | null;
66
+ /**
67
+ * Set the active session group ID
68
+ */
69
+ setActiveSessionGroupId(groupId: number | null): void;
70
+ /**
71
+ * Add a tab to the active session (if one exists)
72
+ */
73
+ addTabToActiveSession(tabId: number): Promise<boolean>;
74
+ /**
75
+ * Generate a session name
76
+ */
77
+ private generateSessionName;
78
+ /**
79
+ * Map Chrome tab group to GroupInfo
80
+ */
81
+ private mapChromeGroupToGroupInfo;
82
+ }
83
+ /**
84
+ * Get the singleton SessionManager instance
85
+ */
86
+ export declare function getSessionManager(): SessionManager;
87
+ //# sourceMappingURL=session-manager.d.ts.map