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.
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
@@ -1,46 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Test All Mode - Images, Headings, and Text</title>
7
- </head>
8
- <body>
9
- <header>
10
- <h1>Welcome to Our Website</h1>
11
- <img src="/images/logo.png" alt="Company Logo" />
12
- </header>
13
-
14
- <main>
15
- <section>
16
- <h2>About Us</h2>
17
- <p>We are a leading provider of innovative solutions for modern businesses. Our team has over 20 years of experience in delivering exceptional results.</p>
18
- <img src="/images/team.jpg" alt="Our dedicated team working together" title="Team collaboration" />
19
- </section>
20
-
21
- <section>
22
- <h2>Our Services</h2>
23
- <h3>Consulting</h3>
24
- <p>Expert consulting services to help your business grow and thrive in today's competitive market.</p>
25
-
26
- <h3>Development</h3>
27
- <p>Custom software development tailored to your specific needs and requirements.</p>
28
- <img src="/images/code.png" alt="Code editor showing programming" />
29
- </section>
30
-
31
- <section>
32
- <h2>Contact Us</h2>
33
- <form>
34
- <label for="email">Email:</label>
35
- <input type="email" id="email" name="email" />
36
- <button type="submit">Submit</button>
37
- </form>
38
- </section>
39
- </main>
40
-
41
- <footer>
42
- <p>Copyright 2025 - All rights reserved</p>
43
- <img src="footer-logo.png" alt="Footer brand logo" />
44
- </footer>
45
- </body>
46
- </html>
@@ -1,5 +0,0 @@
1
- PAGE: http://localhost/ | Test All Mode - Images, Headings, and Text | viewport=1024x768
2
- SNAPSHOT: elements=25 refs=2
3
-
4
- TEXTBOX "Email:" @ref:0 [type=email] /main/section[3]/form/input#email
5
- BUTTON "Submit" @ref:1 /main/section[3]/form/button
@@ -1,296 +0,0 @@
1
- /**
2
- * Validation tests for real-world HTML snapshots
3
- *
4
- * Tests snapshot structure and smart label selection against real-world websites
5
- */
6
-
7
- import { describe, it, expect, beforeEach } from 'vitest';
8
- import { readFileSync, readdirSync } from 'fs';
9
- import { join } from 'path';
10
- import { JSDOM, VirtualConsole } from 'jsdom';
11
- import { createSnapshot } from '../../packages/core/src/snapshot.js';
12
- import { createSimpleRefMap } from '../../packages/core/src/ref-map.js';
13
-
14
- const SNAPSHOTS_DIR = join(__dirname);
15
-
16
- // Helper to load HTML and generate snapshot
17
- function generateSnapshotFromHTML(htmlPath: string) {
18
- const html = readFileSync(htmlPath, 'utf-8');
19
-
20
- const virtualConsole = new VirtualConsole();
21
- virtualConsole.on('error', () => {});
22
- virtualConsole.on('warn', () => {});
23
-
24
- const dom = new JSDOM(html, {
25
- url: 'http://localhost',
26
- contentType: 'text/html',
27
- pretendToBeVisual: true,
28
- virtualConsole,
29
- });
30
-
31
- const { document } = dom.window;
32
- const refMap = createSimpleRefMap();
33
-
34
- return createSnapshot(document, refMap, {
35
- interactive: true,
36
- compact: true,
37
- maxDepth: 10,
38
- includeHidden: false,
39
- });
40
- }
41
-
42
- // Find all HTML test files
43
- const htmlFiles = readdirSync(SNAPSHOTS_DIR)
44
- .filter(f => f.endsWith('.html'))
45
- .map(f => ({
46
- name: f.replace('.html', ''),
47
- path: join(SNAPSHOTS_DIR, f),
48
- }));
49
-
50
- describe('Real-World Snapshot Validation', () => {
51
- describe('Snapshot Structure', () => {
52
- htmlFiles.forEach(({ name, path }) => {
53
- describe(name, () => {
54
- let snapshot: ReturnType<typeof createSnapshot>;
55
-
56
- beforeEach(() => {
57
- try {
58
- snapshot = generateSnapshotFromHTML(path);
59
- } catch (error) {
60
- // Skip files that fail to load (like amazon-com.html with invalid selectors)
61
- snapshot = { tree: '', refs: {} };
62
- }
63
- });
64
-
65
- it('should generate snapshot without errors', () => {
66
- expect(snapshot).toBeDefined();
67
- expect(typeof snapshot).toBe('string');
68
- expect(snapshot.length).toBeGreaterThan(0);
69
- });
70
-
71
- it('should include PAGE header with URL, title, and viewport', () => {
72
- const lines = snapshot.split('\n');
73
- const pageHeader = lines[0];
74
-
75
- if (pageHeader && pageHeader.startsWith('PAGE:')) {
76
- expect(pageHeader).toMatch(/^PAGE: .+ \| .+ \| viewport=\d+x\d+$/);
77
- }
78
- });
79
-
80
- it('should include SNAPSHOT header with statistics', () => {
81
- const lines = snapshot.split('\n');
82
- const snapshotHeader = lines.find(l => l.startsWith('SNAPSHOT:'));
83
-
84
- if (snapshotHeader) {
85
- expect(snapshotHeader).toMatch(/SNAPSHOT: elements=\d+/);
86
- expect(snapshotHeader).toMatch(/depth=\d+\/\d+/);
87
- expect(snapshotHeader).toMatch(/mode=/);
88
- }
89
- });
90
-
91
- it('should format heading levels correctly', () => {
92
- const lines = snapshot.split('\n');
93
- const headings = lines.filter(l => l.includes('HEADING LEVEL='));
94
-
95
- headings.forEach(heading => {
96
- expect(heading).toMatch(/HEADING LEVEL=[1-6]/);
97
- });
98
- });
99
-
100
- it('should show form boundaries where present', () => {
101
- const lines = snapshot.split('\n');
102
- const forms = lines.filter(l => l.trim().startsWith('FORM'));
103
-
104
- forms.forEach(form => {
105
- // Forms should have id or action attributes
106
- const hasAttributes = form.includes('id=') || form.includes('action=');
107
- if (hasAttributes) {
108
- expect(form).toMatch(/FORM/);
109
- }
110
- });
111
- });
112
-
113
- it('should show input types and validation attributes', () => {
114
- const lines = snapshot.split('\n');
115
- const inputs = lines.filter(l => l.includes('TEXTBOX') || l.includes('CHECKBOX'));
116
-
117
- inputs.forEach(input => {
118
- // Check if input has attribute notation
119
- if (input.includes('[')) {
120
- expect(input).toMatch(/\[.*\]/);
121
- // Common attributes: type, required, invalid
122
- }
123
- });
124
- });
125
-
126
- it('should show children indicators for large elements', () => {
127
- const lines = snapshot.split('\n');
128
- const withChildren = lines.filter(l => l.includes('children'));
129
-
130
- withChildren.forEach(line => {
131
- // Should show one of: "N children:", "N shown", "hidden by"
132
- const hasIndicator =
133
- line.includes('children:') ||
134
- line.includes('shown') ||
135
- line.includes('hidden by') ||
136
- line.includes('filtered');
137
- expect(hasIndicator).toBe(true);
138
- });
139
- });
140
- });
141
- });
142
- });
143
-
144
- describe('Smart Label Selection', () => {
145
- htmlFiles.forEach(({ name, path }) => {
146
- describe(name, () => {
147
- let snapshot: ReturnType<typeof createSnapshot>;
148
-
149
- beforeEach(() => {
150
- try {
151
- snapshot = generateSnapshotFromHTML(path);
152
- } catch (error) {
153
- snapshot = { tree: '', refs: {} };
154
- }
155
- });
156
-
157
- it('should have meaningful labels for buttons', () => {
158
- const lines = snapshot.split('\n');
159
- const buttons = lines.filter(l => l.includes('BUTTON'));
160
-
161
- buttons.forEach(button => {
162
- // Extract label (text between BUTTON and @ref or end)
163
- const match = button.match(/BUTTON "([^"]+)"/);
164
- if (match) {
165
- const label = match[1];
166
- expect(label.length).toBeGreaterThan(0);
167
- // Should not be just whitespace
168
- expect(label.trim()).toBe(label);
169
- }
170
- });
171
- });
172
-
173
- it('should show link destinations', () => {
174
- const lines = snapshot.split('\n');
175
- const links = lines.filter(l => l.includes('LINK'));
176
-
177
- const linksWithHref = links.filter(l => l.includes('href='));
178
-
179
- // At least some links should have href
180
- if (links.length > 0) {
181
- expect(linksWithHref.length).toBeGreaterThan(0);
182
- }
183
- });
184
-
185
- it('should have meaningful labels for links', () => {
186
- const lines = snapshot.split('\n');
187
- const links = lines.filter(l => l.includes('LINK'));
188
-
189
- links.forEach(link => {
190
- // Extract label
191
- const match = link.match(/LINK "([^"]+)"/);
192
- if (match) {
193
- const label = match[1];
194
- expect(label.length).toBeGreaterThan(0);
195
- expect(label.trim()).toBe(label);
196
- }
197
- });
198
- });
199
-
200
- it('should not use placeholders as input labels', () => {
201
- const lines = snapshot.split('\n');
202
- const inputs = lines.filter(l =>
203
- l.includes('TEXTBOX') ||
204
- l.includes('TEXTAREA') ||
205
- l.includes('COMBOBOX')
206
- );
207
-
208
- // This is a negative test - we can't easily check what WASN'T used
209
- // But we can verify inputs have labels (from label elements, aria-label, or title)
210
- inputs.forEach(input => {
211
- // Should have a label in quotes
212
- const hasLabel = input.match(/"([^"]+)"/);
213
- if (hasLabel) {
214
- const label = hasLabel[1];
215
- // Label should not be common placeholder text
216
- const isPlaceholder =
217
- label.toLowerCase().includes('enter ') ||
218
- label.toLowerCase().includes('type ') ||
219
- label.toLowerCase().startsWith('e.g.');
220
-
221
- // Most inputs should not have placeholder-style labels
222
- // (This is a soft check since some sites do use these as actual labels)
223
- }
224
- });
225
- });
226
-
227
- it('should generate refs for interactive elements', () => {
228
- // Refs are now internal, just count @ref: in output
229
- const lines = snapshot.split('\n');
230
- const interactiveLines = lines.filter(l =>
231
- l.includes('@ref:') ||
232
- l.includes('BUTTON') ||
233
- l.includes('LINK') ||
234
- l.includes('TEXTBOX')
235
- );
236
-
237
- // Should have refs for interactive elements
238
- if (interactiveLines.length > 0) {
239
- expect(refCount).toBeGreaterThan(0);
240
- }
241
- });
242
-
243
- it.skip('should have bounding boxes in refs', () => {
244
- // Refs are now internal - this test is skipped
245
- // The highlight feature still works using internal refs
246
- expect(true).toBe(true);
247
-
248
- // Should have bounding box info
249
- if (ref.bbox) {
250
- expect(ref.bbox.x).toBeDefined();
251
- expect(ref.bbox.y).toBeDefined();
252
- expect(ref.bbox.width).toBeDefined();
253
- expect(ref.bbox.height).toBeDefined();
254
- }
255
-
256
- // Should have viewport detection
257
- expect(typeof ref.inViewport).toBe('boolean');
258
- });
259
- });
260
- });
261
- });
262
- });
263
-
264
- describe('Performance', () => {
265
- htmlFiles.forEach(({ name, path }) => {
266
- it(`${name}: should generate snapshot in reasonable time`, () => {
267
- const start = performance.now();
268
-
269
- try {
270
- generateSnapshotFromHTML(path);
271
- } catch (error) {
272
- // Skip invalid files
273
- }
274
-
275
- const duration = performance.now() - start;
276
-
277
- // Should complete in under 5 seconds (generous limit for large pages)
278
- expect(duration).toBeLessThan(5000);
279
- });
280
-
281
- it(`${name}: should generate manageable output size`, () => {
282
- let snapshot;
283
- try {
284
- snapshot = generateSnapshotFromHTML(path);
285
- } catch (error) {
286
- snapshot = { tree: '', refs: {} };
287
- }
288
-
289
- const sizeKB = snapshot.length / 1024;
290
-
291
- // Should be under 50KB (adaptive depth should prevent excessive output)
292
- expect(sizeKB).toBeLessThan(50);
293
- });
294
- });
295
- });
296
- });
@@ -1,42 +0,0 @@
1
- {
2
- "name": "@btcp/cli",
3
- "version": "0.1.0",
4
- "description": "Browser-based CLI for browser automation - runs in Chrome extension",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
12
- },
13
- "./terminal": {
14
- "types": "./dist/terminal/index.d.ts",
15
- "import": "./dist/terminal/index.js"
16
- }
17
- },
18
- "scripts": {
19
- "build": "tsc",
20
- "clean": "rm -rf dist",
21
- "test": "vitest run",
22
- "test:watch": "vitest"
23
- },
24
- "files": [
25
- "dist",
26
- "src"
27
- ],
28
- "keywords": [
29
- "browser",
30
- "automation",
31
- "cli",
32
- "chrome-extension"
33
- ],
34
- "license": "Apache-2.0",
35
- "dependencies": {
36
- "@btcp/extension": "file:../extension"
37
- },
38
- "devDependencies": {
39
- "@types/chrome": "^0.0.268",
40
- "typescript": "^5.3.0"
41
- }
42
- }