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
@@ -1,189 +0,0 @@
1
- # Quick Test: Session Debugging
2
-
3
- ## 1. Load Extension (Fresh Start)
4
-
5
- ```bash
6
- # Location: chrome://extensions
7
- # 1. Remove old version if exists
8
- # 2. Click "Load unpacked"
9
- # 3. Select: /Users/minh/Documents/btcp/btcp-browser-agent/examples/chrome-extension/dist
10
- ```
11
-
12
- ## 2. Open Background Console
13
-
14
- 1. In `chrome://extensions`, find **BTCP Browser Agent**
15
- 2. Click **service worker** (under "Inspect views")
16
- 3. This opens the background script DevTools
17
-
18
- ## 3. Run This Test in Background Console
19
-
20
- Copy and paste this entire block:
21
-
22
- ```javascript
23
- console.log('=== BTCP Session Debug Test ===');
24
-
25
- // Test 1: Check API availability
26
- console.log('1. Chrome APIs:');
27
- console.log(' - chrome.tabs:', typeof chrome.tabs);
28
- console.log(' - chrome.tabGroups:', typeof chrome.tabGroups);
29
- console.log(' - chrome.windows:', typeof chrome.windows);
30
-
31
- // Test 2: Check SessionManager
32
- console.log('\n2. SessionManager:');
33
- console.log(' - SessionManager class:', typeof SessionManager);
34
-
35
- // Test 3: Check BackgroundAgent
36
- console.log('\n3. BackgroundAgent:');
37
- const agent = getBackgroundAgent();
38
- console.log(' - Agent exists:', !!agent);
39
- console.log(' - Has sessionManager:', !!agent?.sessionManager);
40
-
41
- // Test 4: Check tabs
42
- console.log('\n4. Current tabs:');
43
- chrome.tabs.query({}, (tabs) => {
44
- console.log(' - Total tabs:', tabs.length);
45
- console.log(' - Active tabs:', tabs.filter(t => t.active).length);
46
- const activeTab = tabs.find(t => t.active);
47
- if (activeTab) {
48
- console.log(' - Active tab ID:', activeTab.id);
49
- console.log(' - Active tab URL:', activeTab.url);
50
- }
51
- });
52
-
53
- // Test 5: Try creating session
54
- console.log('\n5. Attempting to create session...');
55
- if (agent?.sessionManager) {
56
- agent.sessionManager.createGroup({ title: 'Test Session' })
57
- .then(group => {
58
- console.log('✅ SUCCESS! Group created:');
59
- console.log(' - ID:', group.id);
60
- console.log(' - Title:', group.title);
61
- console.log(' - Color:', group.color);
62
- return chrome.tabs.query({ groupId: group.id });
63
- })
64
- .then(tabs => {
65
- console.log(' - Tabs in group:', tabs.length);
66
- console.log('\n🎉 Session working! Check your tabs for a blue group.');
67
- })
68
- .catch(err => {
69
- console.error('❌ FAILED! Error:', err.message);
70
- console.error(' Stack:', err.stack);
71
- });
72
- } else {
73
- console.error('❌ SessionManager not available!');
74
- }
75
- ```
76
-
77
- ## 4. What to Look For
78
-
79
- ### SUCCESS looks like:
80
- ```
81
- === BTCP Session Debug Test ===
82
- 1. Chrome APIs:
83
- - chrome.tabs: object
84
- - chrome.tabGroups: object
85
- - chrome.windows: object
86
-
87
- 2. SessionManager:
88
- - SessionManager class: function
89
-
90
- 3. BackgroundAgent:
91
- - Agent exists: true
92
- - Has sessionManager: true
93
-
94
- 4. Current tabs:
95
- - Total tabs: 3
96
- - Active tabs: 1
97
- - Active tab ID: 123
98
- - Active tab URL: https://example.com/
99
-
100
- 5. Attempting to create session...
101
- [SessionManager] createGroup called with options: {title: "Test Session"}
102
- [SessionManager] No tabIds provided, getting active tab...
103
- [SessionManager] Active tab: {id: 123, ...}
104
- [SessionManager] Creating group with tabs: [123]
105
- [SessionManager] Group created with ID: 456
106
- [SessionManager] Group updated with title: Test Session
107
- [SessionManager] Group info: {id: 456, title: "Test Session", ...}
108
- ✅ SUCCESS! Group created:
109
- - ID: 456
110
- - Title: Test Session
111
- - Color: blue
112
- - Tabs in group: 1
113
-
114
- 🎉 Session working! Check your tabs for a blue group.
115
- ```
116
-
117
- ### FAILURE might show:
118
- ```
119
- ❌ FAILED! Error: No active tab available to create session
120
- ```
121
- **Fix:** Open a regular webpage (not chrome:// page)
122
-
123
- ```
124
- - chrome.tabGroups: undefined
125
- ```
126
- **Fix:** Update Chrome to version 89+
127
-
128
- ```
129
- ❌ SessionManager not available!
130
- ```
131
- **Fix:** Extension not built correctly, run: `npm run build`
132
-
133
- ## 5. Test from Popup
134
-
135
- If background test works, test the popup:
136
-
137
- 1. Click extension icon
138
- 2. Right-click in popup → Inspect
139
- 3. In popup console, run:
140
-
141
- ```javascript
142
- // Quick popup test
143
- const client = createClient();
144
- client.groupCreate({ title: 'Popup Test' })
145
- .then(result => console.log('✅ Popup works:', result))
146
- .catch(err => console.error('❌ Popup failed:', err));
147
- ```
148
-
149
- ## 6. Common Issues Found
150
-
151
- ### Issue: "Cannot group extension page tabs"
152
- **Symptom:** Error when popup tries to group itself
153
- **Solution:** Make sure the ACTIVE tab is a regular webpage, not the popup or chrome:// page
154
-
155
- ### Issue: "activeTab is undefined"
156
- **Symptom:** No tab found to add to group
157
- **Solution:**
158
- 1. Click on a regular webpage tab FIRST
159
- 2. THEN open the extension popup
160
- 3. Try creating session
161
-
162
- ### Issue: "chrome.tabGroups is not defined"
163
- **Symptom:** API not available
164
- **Solution:**
165
- 1. Check Chrome version: `chrome://version`
166
- 2. Needs Chrome 89 or higher
167
- 3. Update Chrome if needed
168
-
169
- ## 7. Next Steps Based on Results
170
-
171
- **If Test 5 succeeds but popup fails:**
172
- → Check popup console for errors
173
- → Verify popup.js has client.groupCreate method
174
- → Check communication between popup and background
175
-
176
- **If Test 5 fails with "No active tab":**
177
- → Open a website in a tab
178
- → Click on that tab (make it active)
179
- → Run test again
180
-
181
- **If SessionManager not found:**
182
- → Rebuild: `npm run build` in project root
183
- → Rebuild: `npm run build` in examples/chrome-extension
184
- → Reload extension
185
-
186
- **If everything works in test but not in UI:**
187
- → Check popup console for JavaScript errors
188
- → Verify button event listeners attached
189
- → Check if updateSessionUI() is being called
@@ -1,149 +0,0 @@
1
- # Chrome Extension Example
2
-
3
- Production-ready TypeScript example using `@btcp/browser-agent`.
4
-
5
- ## Project Structure
6
-
7
- ```
8
- examples/chrome-extension/
9
- ├── src/
10
- │ ├── content.ts # DOM agent + message listener
11
- │ ├── background.ts # routes messages
12
- │ └── popup.ts # UI using createClient
13
- ├── dist/ # Built output (gitignored)
14
- ├── manifest.json # Chrome extension manifest
15
- ├── popup.html # Popup UI
16
- ├── package.json # Build dependencies
17
- ├── tsconfig.json # TypeScript config
18
- └── build.js # esbuild script
19
- ```
20
-
21
- ## Source Files
22
-
23
- **src/content.ts** - registers DOM agent and message listener
24
- ```typescript
25
- import { createContentAgent } from '@btcp/browser-agent/extension';
26
-
27
- const agent = createContentAgent();
28
- chrome.runtime.onMessage.addListener(agent.handleMessage);
29
- ```
30
-
31
- **src/background.ts** - routes messages
32
- ```typescript
33
- import { setupMessageListener } from '@btcp/browser-agent/extension';
34
- setupMessageListener();
35
- ```
36
-
37
- **src/popup.ts** - sends commands
38
- ```typescript
39
- import { createClient } from '@btcp/browser-agent/extension';
40
-
41
- const client = createClient();
42
- await client.navigate('https://example.com');
43
- const { tree } = await client.snapshot();
44
- await client.click('@ref:5');
45
- ```
46
-
47
- ## Setup
48
-
49
- ```bash
50
- # Install dependencies
51
- npm install
52
-
53
- # Build the extension
54
- npm run build
55
-
56
- # Or watch for changes
57
- npm run watch
58
- ```
59
-
60
- ## Load Extension
61
-
62
- 1. Open `chrome://extensions`
63
- 2. Enable "Developer mode"
64
- 3. Click "Load unpacked"
65
- 4. Select this directory
66
-
67
- ## Architecture
68
-
69
- ```
70
- Popup ──chrome.runtime.sendMessage──► Background (setupMessageListener)
71
-
72
- chrome.tabs.sendMessage
73
-
74
- Content Script (auto-registered)
75
-
76
- ContentAgent → DOM
77
- ```
78
-
79
- ## API Usage
80
-
81
- ```typescript
82
- import { createClient } from '@btcp/browser-agent/extension';
83
-
84
- const client = createClient();
85
-
86
- // Navigation
87
- await client.navigate('https://example.com');
88
- await client.back();
89
- await client.forward();
90
- await client.reload();
91
-
92
- // DOM operations
93
- const { tree } = await client.snapshot();
94
- await client.click('@ref:5');
95
- await client.fill('@ref:3', 'hello@example.com');
96
- await client.type('@ref:3', 'typing slowly', { delay: 50 });
97
- const text = await client.getText('@ref:5');
98
- const visible = await client.isVisible('@ref:5');
99
-
100
- // Tab management
101
- const tabs = await client.tabList();
102
- const newTab = await client.tabNew({ url: 'https://github.com' });
103
- await client.tabSwitch(newTab.tabId);
104
- await client.tabClose(newTab.tabId);
105
-
106
- // Screenshot
107
- const base64 = await client.screenshot();
108
- ```
109
-
110
- ## Command Reference
111
-
112
- ### Browser Operations (BackgroundAgent)
113
-
114
- | Method | Description |
115
- |--------|-------------|
116
- | `navigate(url)` | Navigate to URL |
117
- | `back()` / `forward()` | History navigation |
118
- | `reload()` | Reload page |
119
- | `screenshot()` | Capture visible tab |
120
- | `tabNew()` / `tabClose()` | Tab management |
121
- | `tabSwitch()` / `tabList()` | Tab switching |
122
- | `getUrl()` / `getTitle()` | Get page info |
123
-
124
- ### DOM Operations (ContentAgent)
125
-
126
- | Method | Description |
127
- |--------|-------------|
128
- | `snapshot()` | Get accessibility tree with refs |
129
- | `click(selector)` | Click element |
130
- | `fill(selector, value)` | Set input value |
131
- | `type(selector, text)` | Type text with events |
132
- | `getText(selector)` | Get element text |
133
- | `isVisible(selector)` | Check visibility |
134
-
135
- ## Selectors
136
-
137
- ```typescript
138
- // Ref from snapshot (recommended)
139
- await client.click('@ref:5');
140
-
141
- // CSS selectors
142
- await client.click('#submit');
143
- await client.click('.btn-primary');
144
- await client.click('[data-testid="login"]');
145
- ```
146
-
147
- ## License
148
-
149
- Apache-2.0
@@ -1,305 +0,0 @@
1
- # Session-Only Mode
2
-
3
- ## Overview
4
-
5
- The BTCP Browser Agent **only manages tabs within its session/tab group**. No operations are allowed outside of a session.
6
-
7
- ## Key Principle
8
-
9
- **Session is Required** - All operations require an active session:
10
-
11
- - ❌ Cannot list tabs without a session
12
- - ❌ Cannot create tabs without a session
13
- - ❌ Cannot navigate without a session
14
- - ❌ Cannot perform DOM operations without a session
15
- - ✅ Must create session first, then all operations work within that session
16
-
17
- ## How It Works
18
-
19
- ### 1. Session Must Be Created First
20
-
21
- ```javascript
22
- // Create a session to start working
23
- await client.groupCreate({ title: "BTCP Session 1" });
24
-
25
- // Now all operations work (scoped to session)
26
- await client.tabNew({ url: "https://example.com" });
27
- await client.listTabs(); // Only session tabs
28
- ```
29
-
30
- ### 2. Without Session = Error
31
-
32
- ```javascript
33
- // Try to list tabs without session
34
- await client.listTabs();
35
- // ❌ Error: "No active session. Create a session first to manage tabs."
36
-
37
- // Try to create tab without session
38
- await client.tabNew({ url: "https://example.com" });
39
- // ❌ Error: "No active session. Create a session first to manage tabs."
40
- ```
41
-
42
- ### 3. Operations Are Session-Scoped
43
-
44
- Once a session exists, all operations only affect tabs in that session:
45
-
46
- ```javascript
47
- // Create session with tab A
48
- await client.groupCreate(); // Tab A joins session
49
-
50
- // Create new tabs (auto-added to session)
51
- await client.tabNew({ url: "https://example.com" }); // Tab B
52
- await client.tabNew({ url: "https://github.com" }); // Tab C
53
-
54
- // List tabs (only shows A, B, C)
55
- const tabs = await client.listTabs(); // [A, B, C]
56
-
57
- // User manually opens Tab D outside session
58
-
59
- // Try to list tabs (still only shows session tabs)
60
- const tabs2 = await client.listTabs(); // [A, B, C] - no Tab D
61
-
62
- // Try to access Tab D
63
- await client.switchTab(tabD.id);
64
- // ❌ Error: "Cannot switch to tab: tab is not in the active session"
65
- ```
66
-
67
- ## Implementation Details
68
-
69
- ### Session Requirement Check
70
-
71
- Every operation checks for active session:
72
-
73
- ```typescript
74
- async listTabs(): Promise<TabInfo[]> {
75
- const sessionGroupId = this.sessionManager.getActiveSessionGroupId();
76
-
77
- // Session is required
78
- if (sessionGroupId === null) {
79
- throw new Error('No active session. Create a session first.');
80
- }
81
-
82
- // Only query tabs in the session group
83
- const tabs = await chrome.tabs.query({ groupId: sessionGroupId });
84
- return tabs.map(mapToTabInfo);
85
- }
86
- ```
87
-
88
- ### Tab Validation
89
-
90
- Operations validate tab membership:
91
-
92
- ```typescript
93
- private async isTabInSession(tabId: number): Promise<boolean> {
94
- const sessionGroupId = this.sessionManager.getActiveSessionGroupId();
95
-
96
- // Session required
97
- if (sessionGroupId === null) {
98
- throw new Error('No active session.');
99
- }
100
-
101
- // Check if tab is in session
102
- const tab = await chrome.tabs.get(tabId);
103
- return tab.groupId === sessionGroupId;
104
- }
105
- ```
106
-
107
- ### New Tab Creation
108
-
109
- New tabs are automatically added to session:
110
-
111
- ```typescript
112
- async newTab(options?: { url?: string }): Promise<TabInfo> {
113
- // Check session exists
114
- if (!this.sessionManager.getActiveSessionGroupId()) {
115
- throw new Error('No active session.');
116
- }
117
-
118
- // Create tab
119
- const tab = await chrome.tabs.create({ url: options?.url });
120
-
121
- // Add to session
122
- const added = await this.sessionManager.addTabToActiveSession(tab.id);
123
- if (!added) {
124
- // Cleanup if failed
125
- await chrome.tabs.remove(tab.id);
126
- throw new Error('Failed to add tab to session');
127
- }
128
-
129
- return mapToTabInfo(tab);
130
- }
131
- ```
132
-
133
- ## Usage Example
134
-
135
- ### Complete Workflow
136
-
137
- ```javascript
138
- // 1. Create session (required first step)
139
- await client.groupCreate({ title: "Work Session" });
140
- // Current tab joins blue group "Work Session"
141
-
142
- // 2. Now can create tabs (auto-added to session)
143
- await client.tabNew({ url: "https://example.com" });
144
- await client.tabNew({ url: "https://github.com" });
145
-
146
- // 3. List tabs (only shows session tabs)
147
- const tabs = await client.listTabs();
148
- console.log(tabs.length); // 3 tabs
149
-
150
- // 4. Navigate, interact (only session tabs)
151
- await client.navigate("https://newsite.com");
152
- await client.click("#button");
153
- await client.fill("#input", "value");
154
-
155
- // 5. Close session (closes all tabs)
156
- const session = await client.sessionGetCurrent();
157
- await client.groupDelete(session.groupId);
158
- ```
159
-
160
- ### Error Handling
161
-
162
- ```javascript
163
- try {
164
- // Try operation without session
165
- await client.listTabs();
166
- } catch (err) {
167
- if (err.message.includes('No active session')) {
168
- // Create session first
169
- await client.groupCreate();
170
-
171
- // Now retry
172
- const tabs = await client.listTabs();
173
- }
174
- }
175
- ```
176
-
177
- ## Benefits
178
-
179
- ### 1. Security & Isolation
180
- - Extension cannot access tabs outside its scope
181
- - User's personal tabs are protected
182
- - Clear boundaries enforced by code
183
-
184
- ### 2. Explicit Consent
185
- - User must explicitly create session
186
- - Visual indicator (tab group color/label)
187
- - No accidental access to unrelated tabs
188
-
189
- ### 3. Clean Separation
190
- - Each session is independent
191
- - Easy to manage multiple workflows
192
- - Clear visual organization
193
-
194
- ### 4. Predictable Behavior
195
- - All operations scoped to one group
196
- - No ambiguity about which tabs are managed
197
- - Consistent error messages
198
-
199
- ## Visual Indicators
200
-
201
- ### Chrome Tab Groups
202
- - Session tabs have **colored border** (e.g., blue)
203
- - Group label shows session name (e.g., "BTCP Session 1")
204
- - Can collapse/expand the group
205
- - Easy to see which tabs are in scope
206
-
207
- ### Extension Popup
208
- - Shows session status (active/inactive)
209
- - Displays session name and tab count
210
- - Info: "Extension only manages tabs within the active session"
211
- - Buttons disabled when no session
212
-
213
- ## Comparison
214
-
215
- ### Before (Universal Access)
216
- ```javascript
217
- // Could access any tab
218
- const allTabs = await client.listTabs(); // All tabs in window
219
-
220
- // Could navigate any tab
221
- await client.switchTab(anyTabId); // Works
222
-
223
- // Could close any tab
224
- await client.tabClose(anyTabId); // Works
225
- ```
226
-
227
- ### After (Session-Only)
228
- ```javascript
229
- // Must create session first
230
- await client.groupCreate();
231
-
232
- // Only session tabs
233
- const sessionTabs = await client.listTabs(); // Only grouped tabs
234
-
235
- // Only session tabs accessible
236
- await client.switchTab(sessionTabId); // ✅ Works
237
- await client.switchTab(outsideTabId); // ❌ Error
238
-
239
- // Only session tabs closable
240
- await client.tabClose(sessionTabId); // ✅ Works
241
- await client.tabClose(outsideTabId); // ❌ Error
242
- ```
243
-
244
- ## FAQ
245
-
246
- **Q: Can I use the extension without creating a session?**
247
- A: No. Session creation is required for all operations.
248
-
249
- **Q: What if I manually move a tab out of the session group?**
250
- A: The extension immediately loses access to that tab.
251
-
252
- **Q: Can I manually add tabs to the session?**
253
- A: Yes! Drag any tab into the session group, and it becomes accessible.
254
-
255
- **Q: What happens if the session group is deleted?**
256
- A: All operations will fail until a new session is created.
257
-
258
- **Q: Can operations work across multiple sessions?**
259
- A: No. Only one active session at a time, and operations are scoped to it.
260
-
261
- **Q: Why is session required?**
262
- A: Security, isolation, and explicit user consent. The extension should only manage what the user explicitly adds to the session.
263
-
264
- ## Testing
265
-
266
- ### Test Session Requirement
267
-
268
- ```javascript
269
- // 1. Try without session (should fail)
270
- try {
271
- await client.listTabs();
272
- console.error('❌ Should have failed');
273
- } catch (err) {
274
- console.log('✅ Correctly requires session:', err.message);
275
- }
276
-
277
- // 2. Create session
278
- await client.groupCreate({ title: "Test" });
279
-
280
- // 3. Operations now work
281
- const tabs = await client.listTabs();
282
- console.log('✅ Session allows operations:', tabs.length);
283
-
284
- // 4. Try accessing outside tab (should fail)
285
- // (manually open tab outside session first)
286
- try {
287
- await client.switchTab(outsideTabId);
288
- console.error('❌ Should have blocked outside tab');
289
- } catch (err) {
290
- console.log('✅ Correctly blocks outside tab:', err.message);
291
- }
292
- ```
293
-
294
- ## Summary
295
-
296
- **Core Principle**: Session-first, session-only
297
-
298
- - ✅ Session required for all operations
299
- - ✅ All operations scoped to session tabs only
300
- - ✅ Clear errors when session missing
301
- - ✅ Visual boundaries via tab groups
302
- - ✅ Explicit user consent required
303
- - ✅ Maximum security and isolation
304
-
305
- The extension is now a **pure session manager** - it only works within the boundaries of its explicitly created session.