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
package/USAGE.md
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
# Usage Guide
|
|
2
|
-
|
|
3
|
-
## Installation
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npm install @btcp/browser-agent
|
|
7
|
-
# or from git
|
|
8
|
-
npm install git+https://github.com/browser-tool-calling-protocol/btcp-browser-agent.git
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Chrome Extension Setup
|
|
12
|
-
|
|
13
|
-
Three files, minimal setup:
|
|
14
|
-
|
|
15
|
-
### 1. Content Script (registers DOM agent)
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
// content.ts
|
|
19
|
-
import { createContentAgent } from '@btcp/browser-agent/extension';
|
|
20
|
-
|
|
21
|
-
const agent = createContentAgent();
|
|
22
|
-
chrome.runtime.onMessage.addListener(agent.handleMessage);
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### 2. Background Script (routes messages)
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
// background.ts
|
|
29
|
-
import { setupMessageListener } from '@btcp/browser-agent/extension';
|
|
30
|
-
|
|
31
|
-
setupMessageListener();
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 3. Popup (sends commands)
|
|
35
|
-
|
|
36
|
-
```typescript
|
|
37
|
-
// popup.ts
|
|
38
|
-
import { createClient } from '@btcp/browser-agent/extension';
|
|
39
|
-
|
|
40
|
-
const client = createClient();
|
|
41
|
-
|
|
42
|
-
// Navigate and interact
|
|
43
|
-
await client.navigate('https://example.com');
|
|
44
|
-
const { tree } = await client.snapshot();
|
|
45
|
-
console.log(tree);
|
|
46
|
-
// - button 'Submit' [ref=5]
|
|
47
|
-
// - textbox 'Email' [ref=3]
|
|
48
|
-
|
|
49
|
-
await client.fill('@ref:3', 'user@example.com');
|
|
50
|
-
await client.click('@ref:5');
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
**Flow:** Popup → Background → Content → DOM
|
|
54
|
-
|
|
55
|
-
## Standalone Usage (No Extension)
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
import { createContentAgent } from '@btcp/browser-agent';
|
|
59
|
-
|
|
60
|
-
const agent = createContentAgent();
|
|
61
|
-
|
|
62
|
-
// Take snapshot
|
|
63
|
-
const { data } = await agent.execute({ id: '1', action: 'snapshot' });
|
|
64
|
-
|
|
65
|
-
// Interact with elements using refs from snapshot
|
|
66
|
-
await agent.execute({ id: '2', action: 'click', selector: '@ref:5' });
|
|
67
|
-
await agent.execute({ id: '3', action: 'fill', selector: '@ref:3', value: 'text' });
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## Available Actions
|
|
71
|
-
|
|
72
|
-
### DOM Operations (ContentAgent)
|
|
73
|
-
|
|
74
|
-
| Action | Description |
|
|
75
|
-
|--------|-------------|
|
|
76
|
-
| `snapshot` | Get accessibility tree with element refs |
|
|
77
|
-
| `click` | Click element |
|
|
78
|
-
| `dblclick` | Double-click element |
|
|
79
|
-
| `type` | Type text keystroke by keystroke |
|
|
80
|
-
| `fill` | Fill input instantly |
|
|
81
|
-
| `clear` | Clear input value |
|
|
82
|
-
| `check` | Check a checkbox |
|
|
83
|
-
| `uncheck` | Uncheck a checkbox |
|
|
84
|
-
| `select` | Select option(s) in a dropdown |
|
|
85
|
-
| `focus` | Focus an element |
|
|
86
|
-
| `blur` | Remove focus from element |
|
|
87
|
-
| `hover` | Hover over element |
|
|
88
|
-
| `scroll` | Scroll page or element |
|
|
89
|
-
| `scrollIntoView` | Scroll element into view |
|
|
90
|
-
| `querySelector` | Find element by selector |
|
|
91
|
-
| `querySelectorAll` | Find all matching elements |
|
|
92
|
-
| `getText` | Get element text |
|
|
93
|
-
| `getAttribute` | Get element attribute value |
|
|
94
|
-
| `getProperty` | Get element property value |
|
|
95
|
-
| `getBoundingBox` | Get element dimensions and position |
|
|
96
|
-
| `isVisible` | Check visibility |
|
|
97
|
-
| `isEnabled` | Check if element is enabled |
|
|
98
|
-
| `isChecked` | Check if checkbox/radio is checked |
|
|
99
|
-
| `press` | Press a keyboard key |
|
|
100
|
-
| `keyDown` | Key down event |
|
|
101
|
-
| `keyUp` | Key up event |
|
|
102
|
-
| `wait` | Wait for element state |
|
|
103
|
-
| `evaluate` | Execute JavaScript in page context |
|
|
104
|
-
|
|
105
|
-
### Browser Operations (BackgroundAgent)
|
|
106
|
-
|
|
107
|
-
| Action | Description |
|
|
108
|
-
|--------|-------------|
|
|
109
|
-
| `navigate` | Go to URL |
|
|
110
|
-
| `back` / `forward` | History navigation |
|
|
111
|
-
| `reload` | Reload the page |
|
|
112
|
-
| `getUrl` | Get current page URL |
|
|
113
|
-
| `getTitle` | Get current page title |
|
|
114
|
-
| `screenshot` | Capture visible tab |
|
|
115
|
-
| `tabNew` / `tabClose` | Tab management |
|
|
116
|
-
| `tabSwitch` / `tabList` | Tab switching |
|
|
117
|
-
|
|
118
|
-
## Element Selection
|
|
119
|
-
|
|
120
|
-
Use refs from snapshot for stable element selection:
|
|
121
|
-
|
|
122
|
-
```typescript
|
|
123
|
-
// Get snapshot with refs
|
|
124
|
-
const { data } = await agent.execute({ id: '1', action: 'snapshot' });
|
|
125
|
-
// data.tree: "- button 'Submit' [ref=5]\n- textbox 'Email' [ref=3]"
|
|
126
|
-
|
|
127
|
-
// Use ref in commands
|
|
128
|
-
await agent.execute({ id: '2', action: 'click', selector: '@ref:5' });
|
|
129
|
-
|
|
130
|
-
// Or use CSS selectors
|
|
131
|
-
await agent.execute({ id: '3', action: 'click', selector: '#submit-btn' });
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
## Message Protocol
|
|
135
|
-
|
|
136
|
-
Commands use a simple JSON protocol:
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
// Request
|
|
140
|
-
{ id: string, action: string, ...params }
|
|
141
|
-
|
|
142
|
-
// Response
|
|
143
|
-
{ id: string, success: boolean, data?: any, error?: string }
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
Extension messages use `btcp:command` and `btcp:response` types.
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,EACL,kBAAkB,EAClB,KAAK,YAAY,EACjB,UAAU,EACV,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,MAAM,EACX,KAAK,QAAQ,GACd,MAAM,gCAAgC,CAAC;AAGxC,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,OAAO,EACP,SAAS,EACT,gBAAgB,GACjB,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,KAAK,MAAM,GACZ,MAAM,qCAAqC,CAAC"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,wDAAwD;AACxD,OAAO,EACL,kBAAkB,EAElB,UAAU,EACV,cAAc,EACd,YAAY,EACZ,kBAAkB,GAOnB,MAAM,gCAAgC,CAAC;AAWxC,gCAAgC;AAChC,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,GAEb,MAAM,qCAAqC,CAAC"}
|
|
@@ -1,500 +0,0 @@
|
|
|
1
|
-
# Browser-Based CLI Design Document
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
This document proposes an approach to implement a browser-based CLI for btcp-browser-agent, inspired by [vercel-labs/agent-browser](https://github.com/vercel-labs/agent-browser).
|
|
6
|
-
|
|
7
|
-
## Goals
|
|
8
|
-
|
|
9
|
-
1. Provide a command-line interface for browser automation within the browser context
|
|
10
|
-
2. Enable AI agents to control browsers using simple text commands
|
|
11
|
-
3. Maintain compatibility with existing @btcp/core and @btcp/extension packages
|
|
12
|
-
4. Support both interactive and programmatic usage
|
|
13
|
-
|
|
14
|
-
## Reference: agent-browser CLI
|
|
15
|
-
|
|
16
|
-
The agent-browser project provides these command patterns:
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
agent-browser open example.com # Navigate to URL
|
|
20
|
-
agent-browser click @e2 # Click element by ref
|
|
21
|
-
agent-browser type @e3 "hello" # Type into element
|
|
22
|
-
agent-browser snapshot # Get accessibility tree
|
|
23
|
-
agent-browser screenshot page.png # Capture screenshot
|
|
24
|
-
agent-browser fill @e5 "value" # Fill form field
|
|
25
|
-
agent-browser scroll down 200 # Scroll page
|
|
26
|
-
agent-browser press Enter # Press key
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Architecture
|
|
30
|
-
|
|
31
|
-
### In-Browser CLI (Chrome Extension Only)
|
|
32
|
-
|
|
33
|
-
Commands are sent directly from the Chrome extension - no external processes or WebSocket bridges needed.
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
37
|
-
│ Chrome Extension │
|
|
38
|
-
│ │
|
|
39
|
-
│ ┌─────────────────────────────────────────────────────────┐│
|
|
40
|
-
│ │ Terminal UI (Popup/Panel) ││
|
|
41
|
-
│ │ $ snapshot ││
|
|
42
|
-
│ │ - button 'Submit' [@ref:1] ││
|
|
43
|
-
│ │ - textbox 'Email' [@ref:2] ││
|
|
44
|
-
│ │ ││
|
|
45
|
-
│ │ $ click @ref:1 ││
|
|
46
|
-
│ │ ✓ Clicked element: button 'Submit' ││
|
|
47
|
-
│ └─────────────────────────────────────────────────────────┘│
|
|
48
|
-
│ │ │
|
|
49
|
-
│ ▼ │
|
|
50
|
-
│ ┌─────────────────────────────────────────────────────────┐│
|
|
51
|
-
│ │ CLI Parser & Executor (@btcp/cli) ││
|
|
52
|
-
│ │ parseCommand() → executeCommand() ││
|
|
53
|
-
│ └─────────────────────────────────────────────────────────┘│
|
|
54
|
-
│ │ │
|
|
55
|
-
│ ▼ │
|
|
56
|
-
│ ┌─────────────────────────────────────────────────────────┐│
|
|
57
|
-
│ │ BackgroundAgent (@btcp/extension) ││
|
|
58
|
-
│ │ Tab management, navigation, routing ││
|
|
59
|
-
│ └─────────────────────────────────────────────────────────┘│
|
|
60
|
-
│ │ │
|
|
61
|
-
│ chrome.tabs.sendMessage() │
|
|
62
|
-
│ ▼ │
|
|
63
|
-
│ ┌─────────────────────────────────────────────────────────┐│
|
|
64
|
-
│ │ ContentAgent (@btcp/core) ││
|
|
65
|
-
│ │ DOM operations, snapshots, interactions ││
|
|
66
|
-
│ └─────────────────────────────────────────────────────────┘│
|
|
67
|
-
└─────────────────────────────────────────────────────────────┘
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**Benefits:**
|
|
71
|
-
- Pure browser-native approach
|
|
72
|
-
- No external dependencies
|
|
73
|
-
- Direct integration with existing @btcp packages
|
|
74
|
-
- Real-time command execution
|
|
75
|
-
- Works entirely within extension context
|
|
76
|
-
|
|
77
|
-
## Implementation Plan
|
|
78
|
-
|
|
79
|
-
### Phase 1: Command Parser & Executor
|
|
80
|
-
|
|
81
|
-
Create a new package `@btcp/cli` that provides command parsing and execution.
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
packages/
|
|
85
|
-
cli/
|
|
86
|
-
src/
|
|
87
|
-
index.ts # Main exports
|
|
88
|
-
parser.ts # Command line parser
|
|
89
|
-
executor.ts # Command executor
|
|
90
|
-
commands/ # Individual command implementations
|
|
91
|
-
goto.ts
|
|
92
|
-
click.ts
|
|
93
|
-
type.ts
|
|
94
|
-
snapshot.ts
|
|
95
|
-
screenshot.ts
|
|
96
|
-
...
|
|
97
|
-
formatter.ts # Output formatting
|
|
98
|
-
types.ts # TypeScript types
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
#### Command Syntax
|
|
102
|
-
|
|
103
|
-
```typescript
|
|
104
|
-
// Command structure
|
|
105
|
-
interface CLICommand {
|
|
106
|
-
name: string;
|
|
107
|
-
args: string[];
|
|
108
|
-
flags: Record<string, string | boolean>;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Examples:
|
|
112
|
-
// "goto https://example.com" → { name: 'goto', args: ['https://example.com'], flags: {} }
|
|
113
|
-
// "click @ref:5 --wait 1000" → { name: 'click', args: ['@ref:5'], flags: { wait: '1000' } }
|
|
114
|
-
// "screenshot --full" → { name: 'screenshot', args: [], flags: { full: true } }
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
#### Supported Commands
|
|
118
|
-
|
|
119
|
-
| Command | Syntax | Description |
|
|
120
|
-
|---------|--------|-------------|
|
|
121
|
-
| `goto` | `goto <url>` | Navigate to URL |
|
|
122
|
-
| `back` | `back` | Go back in history |
|
|
123
|
-
| `forward` | `forward` | Go forward in history |
|
|
124
|
-
| `reload` | `reload` | Reload current page |
|
|
125
|
-
| `snapshot` | `snapshot` | Get accessibility tree |
|
|
126
|
-
| `screenshot` | `screenshot [filename]` | Capture screenshot |
|
|
127
|
-
| `click` | `click <selector>` | Click element |
|
|
128
|
-
| `dblclick` | `dblclick <selector>` | Double-click element |
|
|
129
|
-
| `type` | `type <selector> <text>` | Type text into element |
|
|
130
|
-
| `fill` | `fill <selector> <value>` | Fill input field |
|
|
131
|
-
| `clear` | `clear <selector>` | Clear input field |
|
|
132
|
-
| `check` | `check <selector>` | Check checkbox |
|
|
133
|
-
| `uncheck` | `uncheck <selector>` | Uncheck checkbox |
|
|
134
|
-
| `select` | `select <selector> <value>` | Select dropdown option |
|
|
135
|
-
| `hover` | `hover <selector>` | Hover over element |
|
|
136
|
-
| `scroll` | `scroll <direction> [amount]` | Scroll page |
|
|
137
|
-
| `press` | `press <key>` | Press keyboard key |
|
|
138
|
-
| `wait` | `wait <ms>` | Wait for duration |
|
|
139
|
-
| `eval` | `eval <code>` | Execute JavaScript |
|
|
140
|
-
| `tabs` | `tabs` | List all tabs |
|
|
141
|
-
| `tab` | `tab <id>` | Switch to tab |
|
|
142
|
-
| `newtab` | `newtab [url]` | Open new tab |
|
|
143
|
-
| `closetab` | `closetab [id]` | Close tab |
|
|
144
|
-
| `help` | `help [command]` | Show help |
|
|
145
|
-
|
|
146
|
-
### Phase 2: In-Browser Terminal UI
|
|
147
|
-
|
|
148
|
-
Create a terminal component for the extension popup or a dedicated panel.
|
|
149
|
-
|
|
150
|
-
#### Terminal Component
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
// packages/cli/src/terminal/
|
|
154
|
-
interface TerminalConfig {
|
|
155
|
-
theme: 'dark' | 'light';
|
|
156
|
-
fontSize: number;
|
|
157
|
-
historySize: number;
|
|
158
|
-
prompt: string;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
interface TerminalState {
|
|
162
|
-
history: HistoryEntry[];
|
|
163
|
-
inputBuffer: string;
|
|
164
|
-
cursorPosition: number;
|
|
165
|
-
commandHistory: string[];
|
|
166
|
-
historyIndex: number;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
interface HistoryEntry {
|
|
170
|
-
type: 'input' | 'output' | 'error';
|
|
171
|
-
content: string;
|
|
172
|
-
timestamp: number;
|
|
173
|
-
}
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
#### UI Features
|
|
177
|
-
|
|
178
|
-
1. **Command input** with cursor and editing
|
|
179
|
-
2. **Command history** (up/down arrows)
|
|
180
|
-
3. **Tab completion** for commands and refs
|
|
181
|
-
4. **Syntax highlighting** for commands
|
|
182
|
-
5. **Output formatting** (success/error/info)
|
|
183
|
-
6. **Scrollable history**
|
|
184
|
-
7. **Copy/paste support**
|
|
185
|
-
|
|
186
|
-
### Phase 3: Integration with BackgroundAgent
|
|
187
|
-
|
|
188
|
-
Connect the CLI to the existing BackgroundAgent for execution.
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
// Example integration
|
|
192
|
-
import { BackgroundAgent } from '@btcp/extension';
|
|
193
|
-
import { parseCommand, executeCommand } from '@btcp/cli';
|
|
194
|
-
|
|
195
|
-
const agent = new BackgroundAgent();
|
|
196
|
-
|
|
197
|
-
async function handleCommand(input: string): Promise<string> {
|
|
198
|
-
const command = parseCommand(input);
|
|
199
|
-
const result = await executeCommand(agent, command);
|
|
200
|
-
return formatResult(result);
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
## Detailed Component Design
|
|
205
|
-
|
|
206
|
-
### 1. Command Parser (`parser.ts`)
|
|
207
|
-
|
|
208
|
-
```typescript
|
|
209
|
-
export function parseCommand(input: string): CLICommand {
|
|
210
|
-
const tokens = tokenize(input);
|
|
211
|
-
const name = tokens[0];
|
|
212
|
-
const { args, flags } = parseArgs(tokens.slice(1));
|
|
213
|
-
return { name, args, flags };
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
function tokenize(input: string): string[] {
|
|
217
|
-
// Handle quoted strings, escape characters
|
|
218
|
-
// "type @ref:1 \"hello world\"" → ['type', '@ref:1', 'hello world']
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
function parseArgs(tokens: string[]): { args: string[], flags: Record<string, string | boolean> } {
|
|
222
|
-
// Parse --flag and --flag=value patterns
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### 2. Command Executor (`executor.ts`)
|
|
227
|
-
|
|
228
|
-
```typescript
|
|
229
|
-
export async function executeCommand(
|
|
230
|
-
agent: BackgroundAgent,
|
|
231
|
-
command: CLICommand
|
|
232
|
-
): Promise<CommandResult> {
|
|
233
|
-
const handler = commands[command.name];
|
|
234
|
-
if (!handler) {
|
|
235
|
-
throw new CLIError(`Unknown command: ${command.name}`);
|
|
236
|
-
}
|
|
237
|
-
return handler.execute(agent, command.args, command.flags);
|
|
238
|
-
}
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### 3. Individual Commands (`commands/*.ts`)
|
|
242
|
-
|
|
243
|
-
```typescript
|
|
244
|
-
// commands/goto.ts
|
|
245
|
-
export const gotoCommand: CommandHandler = {
|
|
246
|
-
name: 'goto',
|
|
247
|
-
description: 'Navigate to a URL',
|
|
248
|
-
usage: 'goto <url>',
|
|
249
|
-
examples: [
|
|
250
|
-
'goto https://example.com',
|
|
251
|
-
'goto github.com',
|
|
252
|
-
],
|
|
253
|
-
async execute(agent, args, flags) {
|
|
254
|
-
const url = args[0];
|
|
255
|
-
if (!url) {
|
|
256
|
-
throw new CLIError('URL required');
|
|
257
|
-
}
|
|
258
|
-
await agent.navigate(url);
|
|
259
|
-
return { success: true, message: `Navigated to ${url}` };
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
// commands/snapshot.ts
|
|
264
|
-
export const snapshotCommand: CommandHandler = {
|
|
265
|
-
name: 'snapshot',
|
|
266
|
-
description: 'Get page accessibility tree',
|
|
267
|
-
usage: 'snapshot [--refs-only]',
|
|
268
|
-
async execute(agent, args, flags) {
|
|
269
|
-
const result = await agent.execute({
|
|
270
|
-
id: generateId(),
|
|
271
|
-
action: 'snapshot'
|
|
272
|
-
});
|
|
273
|
-
return {
|
|
274
|
-
success: true,
|
|
275
|
-
data: result.data.tree
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
};
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### 4. Output Formatter (`formatter.ts`)
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
export function formatResult(result: CommandResult): FormattedOutput {
|
|
285
|
-
if (result.success) {
|
|
286
|
-
return {
|
|
287
|
-
type: 'success',
|
|
288
|
-
content: result.message || formatData(result.data)
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
return {
|
|
292
|
-
type: 'error',
|
|
293
|
-
content: `Error: ${result.error}`
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
function formatData(data: unknown): string {
|
|
298
|
-
// Format snapshots, screenshots, etc.
|
|
299
|
-
if (typeof data === 'string') return data;
|
|
300
|
-
return JSON.stringify(data, null, 2);
|
|
301
|
-
}
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
### 5. Terminal UI (`terminal/Terminal.ts`)
|
|
305
|
-
|
|
306
|
-
```typescript
|
|
307
|
-
export class Terminal {
|
|
308
|
-
private state: TerminalState;
|
|
309
|
-
private config: TerminalConfig;
|
|
310
|
-
private onExecute: (command: string) => Promise<string>;
|
|
311
|
-
|
|
312
|
-
constructor(container: HTMLElement, config: Partial<TerminalConfig>) {
|
|
313
|
-
this.config = { ...defaultConfig, ...config };
|
|
314
|
-
this.state = initialState();
|
|
315
|
-
this.render(container);
|
|
316
|
-
this.bindEvents();
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
async handleInput(input: string): Promise<void> {
|
|
320
|
-
this.appendHistory({ type: 'input', content: `$ ${input}` });
|
|
321
|
-
try {
|
|
322
|
-
const output = await this.onExecute(input);
|
|
323
|
-
this.appendHistory({ type: 'output', content: output });
|
|
324
|
-
} catch (error) {
|
|
325
|
-
this.appendHistory({ type: 'error', content: error.message });
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
private bindEvents(): void {
|
|
330
|
-
// Keyboard handling: Enter, Up, Down, Tab, etc.
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
private render(container: HTMLElement): void {
|
|
334
|
-
// Create terminal UI elements
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
## File Structure
|
|
340
|
-
|
|
341
|
-
```
|
|
342
|
-
packages/
|
|
343
|
-
cli/
|
|
344
|
-
package.json
|
|
345
|
-
tsconfig.json
|
|
346
|
-
src/
|
|
347
|
-
index.ts # Main exports
|
|
348
|
-
types.ts # TypeScript types
|
|
349
|
-
parser.ts # Command parser
|
|
350
|
-
executor.ts # Command executor
|
|
351
|
-
formatter.ts # Output formatting
|
|
352
|
-
errors.ts # CLI errors
|
|
353
|
-
commands/
|
|
354
|
-
index.ts # Command registry
|
|
355
|
-
goto.ts
|
|
356
|
-
back.ts
|
|
357
|
-
forward.ts
|
|
358
|
-
reload.ts
|
|
359
|
-
snapshot.ts
|
|
360
|
-
screenshot.ts
|
|
361
|
-
click.ts
|
|
362
|
-
dblclick.ts
|
|
363
|
-
type.ts
|
|
364
|
-
fill.ts
|
|
365
|
-
clear.ts
|
|
366
|
-
check.ts
|
|
367
|
-
uncheck.ts
|
|
368
|
-
select.ts
|
|
369
|
-
hover.ts
|
|
370
|
-
scroll.ts
|
|
371
|
-
press.ts
|
|
372
|
-
wait.ts
|
|
373
|
-
eval.ts
|
|
374
|
-
tabs.ts
|
|
375
|
-
tab.ts
|
|
376
|
-
newtab.ts
|
|
377
|
-
closetab.ts
|
|
378
|
-
help.ts
|
|
379
|
-
terminal/
|
|
380
|
-
index.ts # Terminal exports
|
|
381
|
-
Terminal.ts # Terminal class
|
|
382
|
-
renderer.ts # DOM rendering
|
|
383
|
-
history.ts # Command history
|
|
384
|
-
completion.ts # Tab completion
|
|
385
|
-
styles.css # Terminal styles
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
## Example Usage
|
|
389
|
-
|
|
390
|
-
### Interactive Session
|
|
391
|
-
|
|
392
|
-
```
|
|
393
|
-
$ goto https://github.com
|
|
394
|
-
✓ Navigated to https://github.com
|
|
395
|
-
|
|
396
|
-
$ snapshot
|
|
397
|
-
- banner
|
|
398
|
-
- link 'Homepage' [@ref:1]
|
|
399
|
-
- navigation
|
|
400
|
-
- link 'Product' [@ref:2]
|
|
401
|
-
- link 'Solutions' [@ref:3]
|
|
402
|
-
- link 'Resources' [@ref:4]
|
|
403
|
-
- textbox 'Search or jump to...' [@ref:5]
|
|
404
|
-
- link 'Sign in' [@ref:6]
|
|
405
|
-
- link 'Sign up' [@ref:7]
|
|
406
|
-
- main
|
|
407
|
-
- heading 'Let's build from here' level=1
|
|
408
|
-
- textbox 'Search code...' [@ref:8]
|
|
409
|
-
|
|
410
|
-
$ click @ref:6
|
|
411
|
-
✓ Clicked: link 'Sign in'
|
|
412
|
-
|
|
413
|
-
$ snapshot
|
|
414
|
-
- main
|
|
415
|
-
- heading 'Sign in to GitHub' level=1
|
|
416
|
-
- textbox 'Username or email' [@ref:1]
|
|
417
|
-
- textbox 'Password' [@ref:2]
|
|
418
|
-
- button 'Sign in' [@ref:3]
|
|
419
|
-
- link 'Forgot password?' [@ref:4]
|
|
420
|
-
|
|
421
|
-
$ type @ref:1 myusername
|
|
422
|
-
✓ Typed "myusername" into: textbox 'Username or email'
|
|
423
|
-
|
|
424
|
-
$ fill @ref:2 mypassword
|
|
425
|
-
✓ Filled: textbox 'Password'
|
|
426
|
-
|
|
427
|
-
$ click @ref:3
|
|
428
|
-
✓ Clicked: button 'Sign in'
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
### Programmatic API (within extension)
|
|
432
|
-
|
|
433
|
-
```typescript
|
|
434
|
-
// In popup.ts or background.ts
|
|
435
|
-
import { createCLI } from '@btcp/cli';
|
|
436
|
-
import { BackgroundAgent } from '@btcp/extension';
|
|
437
|
-
|
|
438
|
-
const agent = new BackgroundAgent();
|
|
439
|
-
const cli = createCLI(agent);
|
|
440
|
-
|
|
441
|
-
// Execute commands programmatically from extension code
|
|
442
|
-
await cli.execute('goto https://example.com');
|
|
443
|
-
const snapshot = await cli.execute('snapshot');
|
|
444
|
-
await cli.execute('click @ref:1');
|
|
445
|
-
|
|
446
|
-
// Or use the Client API for structured access
|
|
447
|
-
import { createClient } from '@btcp/extension';
|
|
448
|
-
const client = createClient();
|
|
449
|
-
await client.navigate('https://example.com');
|
|
450
|
-
const result = await client.snapshot();
|
|
451
|
-
await client.click('@ref:1');
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
## Implementation Timeline
|
|
455
|
-
|
|
456
|
-
### Milestone 1: Core CLI Package
|
|
457
|
-
- [ ] Set up @btcp/cli package structure
|
|
458
|
-
- [ ] Implement command parser
|
|
459
|
-
- [ ] Implement command executor
|
|
460
|
-
- [ ] Implement core navigation commands (goto, back, forward, reload)
|
|
461
|
-
- [ ] Implement snapshot command
|
|
462
|
-
- [ ] Add basic output formatting
|
|
463
|
-
|
|
464
|
-
### Milestone 2: DOM Commands
|
|
465
|
-
- [ ] Implement click, dblclick
|
|
466
|
-
- [ ] Implement type, fill, clear
|
|
467
|
-
- [ ] Implement check, uncheck, select
|
|
468
|
-
- [ ] Implement hover, scroll
|
|
469
|
-
- [ ] Implement press (keyboard)
|
|
470
|
-
- [ ] Implement wait, eval
|
|
471
|
-
|
|
472
|
-
### Milestone 3: Tab Management
|
|
473
|
-
- [ ] Implement tabs, tab, newtab, closetab
|
|
474
|
-
- [ ] Add multi-tab command support
|
|
475
|
-
|
|
476
|
-
### Milestone 4: Terminal UI
|
|
477
|
-
- [ ] Create terminal component
|
|
478
|
-
- [ ] Implement command input handling
|
|
479
|
-
- [ ] Add command history (up/down)
|
|
480
|
-
- [ ] Add tab completion
|
|
481
|
-
- [ ] Style terminal UI
|
|
482
|
-
- [ ] Integrate with extension popup
|
|
483
|
-
|
|
484
|
-
### Milestone 5: Polish & Documentation
|
|
485
|
-
- [ ] Add help command with usage info
|
|
486
|
-
- [ ] Add command validation and helpful errors
|
|
487
|
-
- [ ] Write documentation
|
|
488
|
-
- [ ] Add tests
|
|
489
|
-
|
|
490
|
-
## Conclusion
|
|
491
|
-
|
|
492
|
-
This design provides a pure in-browser CLI implementation that:
|
|
493
|
-
|
|
494
|
-
1. **Mimics agent-browser** with similar command syntax
|
|
495
|
-
2. **Runs entirely within Chrome extension** - no external processes
|
|
496
|
-
3. **Integrates seamlessly** with existing @btcp/core and @btcp/extension packages
|
|
497
|
-
4. **Provides terminal UI** in extension popup/panel for interactive use
|
|
498
|
-
5. **Supports programmatic API** for AI agents within the browser
|
|
499
|
-
|
|
500
|
-
The implementation starts with the core CLI package (parser, executor, commands), then adds the terminal UI component for the extension.
|