@ytspar/sweetlink 0.0.1 → 1.0.0-canary.e1f65d0
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/LICENSE +21 -0
- package/README.md +586 -29
- package/dist/browser/SweetlinkBridge.d.ts +70 -0
- package/dist/browser/SweetlinkBridge.d.ts.map +1 -0
- package/dist/browser/SweetlinkBridge.js +370 -0
- package/dist/browser/SweetlinkBridge.js.map +1 -0
- package/dist/browser/commands/dom.d.ts +11 -0
- package/dist/browser/commands/dom.d.ts.map +1 -0
- package/dist/browser/commands/dom.js +79 -0
- package/dist/browser/commands/dom.js.map +1 -0
- package/dist/browser/commands/exec.d.ts +14 -0
- package/dist/browser/commands/exec.d.ts.map +1 -0
- package/dist/browser/commands/exec.js +47 -0
- package/dist/browser/commands/exec.js.map +1 -0
- package/dist/browser/commands/index.d.ts +10 -0
- package/dist/browser/commands/index.d.ts.map +1 -0
- package/dist/browser/commands/index.js +10 -0
- package/dist/browser/commands/index.js.map +1 -0
- package/dist/browser/commands/logs.d.ts +11 -0
- package/dist/browser/commands/logs.d.ts.map +1 -0
- package/dist/browser/commands/logs.js +26 -0
- package/dist/browser/commands/logs.js.map +1 -0
- package/dist/browser/commands/screenshot.d.ts +16 -0
- package/dist/browser/commands/screenshot.d.ts.map +1 -0
- package/dist/browser/commands/screenshot.js +122 -0
- package/dist/browser/commands/screenshot.js.map +1 -0
- package/dist/browser/consoleCapture.d.ts +107 -0
- package/dist/browser/consoleCapture.d.ts.map +1 -0
- package/dist/browser/consoleCapture.js +223 -0
- package/dist/browser/consoleCapture.js.map +1 -0
- package/dist/browser/hmr.d.ts +25 -0
- package/dist/browser/hmr.d.ts.map +1 -0
- package/dist/browser/hmr.js +94 -0
- package/dist/browser/hmr.js.map +1 -0
- package/dist/browser/screenshotUtils.d.ts +102 -0
- package/dist/browser/screenshotUtils.d.ts.map +1 -0
- package/dist/browser/screenshotUtils.js +145 -0
- package/dist/browser/screenshotUtils.js.map +1 -0
- package/dist/browser.d.ts +2 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +5 -0
- package/dist/browser.js.map +1 -0
- package/dist/cdp.d.ts +99 -0
- package/dist/cdp.d.ts.map +1 -0
- package/dist/cdp.js +341 -0
- package/dist/cdp.js.map +1 -0
- package/dist/cli/sweetlink-dev.d.ts +14 -0
- package/dist/cli/sweetlink-dev.d.ts.map +1 -0
- package/dist/cli/sweetlink-dev.js +36 -0
- package/dist/cli/sweetlink-dev.js.map +1 -0
- package/dist/cli/sweetlink.d.ts +9 -0
- package/dist/cli/sweetlink.d.ts.map +1 -0
- package/dist/cli/sweetlink.js +1003 -0
- package/dist/cli/sweetlink.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/playwright.d.ts +29 -0
- package/dist/playwright.d.ts.map +1 -0
- package/dist/playwright.js +172 -0
- package/dist/playwright.js.map +1 -0
- package/dist/ruler.d.ts +82 -0
- package/dist/ruler.d.ts.map +1 -0
- package/dist/ruler.js +296 -0
- package/dist/ruler.js.map +1 -0
- package/dist/server/anthropic.d.ts +19 -0
- package/dist/server/anthropic.d.ts.map +1 -0
- package/dist/server/anthropic.js +26 -0
- package/dist/server/anthropic.js.map +1 -0
- package/dist/server/constants.d.ts +17 -0
- package/dist/server/constants.d.ts.map +1 -0
- package/dist/server/constants.js +17 -0
- package/dist/server/constants.js.map +1 -0
- package/dist/server/handlers/designReview.d.ts +27 -0
- package/dist/server/handlers/designReview.d.ts.map +1 -0
- package/dist/server/handlers/designReview.js +165 -0
- package/dist/server/handlers/designReview.js.map +1 -0
- package/dist/server/handlers/hmr.d.ts +21 -0
- package/dist/server/handlers/hmr.d.ts.map +1 -0
- package/dist/server/handlers/hmr.js +81 -0
- package/dist/server/handlers/hmr.js.map +1 -0
- package/dist/server/handlers/index.d.ts +11 -0
- package/dist/server/handlers/index.d.ts.map +1 -0
- package/dist/server/handlers/index.js +11 -0
- package/dist/server/handlers/index.js.map +1 -0
- package/dist/server/handlers/outline.d.ts +19 -0
- package/dist/server/handlers/outline.d.ts.map +1 -0
- package/dist/server/handlers/outline.js +41 -0
- package/dist/server/handlers/outline.js.map +1 -0
- package/dist/server/handlers/schema.d.ts +19 -0
- package/dist/server/handlers/schema.d.ts.map +1 -0
- package/dist/server/handlers/schema.js +49 -0
- package/dist/server/handlers/schema.js.map +1 -0
- package/dist/server/handlers/screenshot.d.ts +22 -0
- package/dist/server/handlers/screenshot.d.ts.map +1 -0
- package/dist/server/handlers/screenshot.js +72 -0
- package/dist/server/handlers/screenshot.js.map +1 -0
- package/dist/server/index.d.ts +33 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +507 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/subscriptions.d.ts +26 -0
- package/dist/server/subscriptions.d.ts.map +1 -0
- package/dist/server/subscriptions.js +35 -0
- package/dist/server/subscriptions.js.map +1 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +8 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +130 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/urlUtils.d.ts +75 -0
- package/dist/urlUtils.d.ts.map +1 -0
- package/dist/urlUtils.js +121 -0
- package/dist/urlUtils.js.map +1 -0
- package/dist/viewportUtils.d.ts +51 -0
- package/dist/viewportUtils.d.ts.map +1 -0
- package/dist/viewportUtils.js +58 -0
- package/dist/viewportUtils.js.map +1 -0
- package/package.json +98 -6
- package/scripts/setup-claude-context.mjs +101 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 ytspar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,45 +1,602 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @sweetlink/dev-toolkit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Autonomous development toolkit for Claude AI agents - screenshots, DOM queries, console logs, and JavaScript execution via WebSocket and Chrome DevTools Protocol
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Sweetlink enables Claude AI agents to autonomously debug, test, and iterate on web applications through real-time browser interaction. It provides a WebSocket bridge between your development server and CLI tools, allowing AI assistants to take screenshots, inspect DOM, capture console logs, and execute JavaScript - all without human intervention.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**Inspired by**: [Peter Steinberger's autonomous debugging implementation](https://x.com/steipete/status/1981998733736001727) - "Now my agent can debug everything completely autonomous e2e."
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
1. Configure OIDC trusted publishing for the package name `@ytspar/sweetlink`
|
|
13
|
-
2. Enable secure, token-less publishing from CI/CD workflows
|
|
14
|
-
3. Establish provenance for packages published under this name
|
|
11
|
+
## Features
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
- **📸 Screenshots** - Capture full page or element-specific screenshots (html2canvas + CDP)
|
|
14
|
+
- **🖱️ Screenshot Button** - One-click screenshot capture with console logs from browser UI
|
|
15
|
+
- **🔍 DOM Queries** - Query and inspect DOM elements with CSS selectors
|
|
16
|
+
- **📊 Console Logs** - Capture and filter browser console output with JSON/summary formats
|
|
17
|
+
- **⚡ JavaScript Execution** - Run arbitrary JavaScript in browser context
|
|
18
|
+
- **🖱️ Click Elements** - Click elements by selector, text content, or both
|
|
19
|
+
- **🌐 Network Inspection** - Monitor network requests (CDP only)
|
|
20
|
+
- **🔄 Page Refresh** - Soft or hard refresh the browser from CLI
|
|
21
|
+
- **🔄 Auto Reconnection** - Browser client automatically reconnects on disconnect
|
|
22
|
+
- **🎯 Token Efficient** - ~1000 tokens/screenshot vs ~5000 for MCP tools
|
|
23
|
+
- **📝 LLM-Optimized Output** - Summary format with deduplication for context efficiency
|
|
24
|
+
- **🚀 Zero Setup** - Works immediately with any web app
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
## Screenshot Button
|
|
19
27
|
|
|
20
|
-
|
|
28
|
+
The browser UI includes a convenient screenshot button (📸) that allows developers and AI agents to instantly capture the current page state along with console logs. When clicked:
|
|
21
29
|
|
|
22
|
-
|
|
30
|
+
1. **Captures full page screenshot** using html2canvas
|
|
31
|
+
2. **Saves screenshot** to `.tmp/sweetlink-screenshots/screenshot-[timestamp].png`
|
|
32
|
+
3. **Saves console logs** to `.tmp/sweetlink-screenshots/screenshot-[timestamp]-logs.txt`
|
|
33
|
+
4. **Logs include**: timestamp, URL, dimensions, and all console messages
|
|
23
34
|
|
|
24
|
-
|
|
25
|
-
2. Configure the trusted publisher (e.g., GitHub Actions)
|
|
26
|
-
3. Specify the repository and workflow that should be allowed to publish
|
|
27
|
-
4. Use the configured workflow to publish your actual package
|
|
35
|
+
This provides AI agents with easy access to visual state and debugging information without requiring CLI commands.
|
|
28
36
|
|
|
29
|
-
|
|
37
|
+
**File Location Rationale**: Files are saved to `.tmp/sweetlink-screenshots/` (relative to project root) for easy agent access - keeps screenshots with the project and is typically gitignored via `.tmp/` patterns.
|
|
30
38
|
|
|
31
|
-
|
|
32
|
-
- Contains no executable code
|
|
33
|
-
- Provides no functionality
|
|
34
|
-
- Should not be installed as a dependency
|
|
35
|
-
- Exists only for administrative purposes
|
|
39
|
+
## Installation
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
```bash
|
|
42
|
+
npm install @sweetlink/dev-toolkit
|
|
43
|
+
# or
|
|
44
|
+
pnpm add @sweetlink/dev-toolkit
|
|
45
|
+
# or
|
|
46
|
+
yarn add @sweetlink/dev-toolkit
|
|
47
|
+
```
|
|
38
48
|
|
|
39
|
-
|
|
40
|
-
- [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
|
|
41
|
-
- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
|
49
|
+
## Quick Start
|
|
42
50
|
|
|
43
|
-
|
|
51
|
+
### 1. Add Sweetlink Server to Your Dev Setup
|
|
44
52
|
|
|
45
|
-
|
|
53
|
+
#### For Remix Apps
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
// server.ts or entry.server.tsx
|
|
57
|
+
import { initSweetlink } from '@sweetlink/dev-toolkit';
|
|
58
|
+
|
|
59
|
+
if (process.env.NODE_ENV === 'development') {
|
|
60
|
+
const port = parseInt(process.env.SWEETLINK_WS_PORT || '9223', 10);
|
|
61
|
+
initSweetlink({ port });
|
|
62
|
+
console.log(`[Sweetlink] WebSocket server started on ws://localhost:${port}`);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### For Next.js Apps
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// next.config.js
|
|
70
|
+
const { initSweetlink } = require('@sweetlink/dev-toolkit');
|
|
71
|
+
|
|
72
|
+
if (process.env.NODE_ENV === 'development') {
|
|
73
|
+
initSweetlink({ port: 9223 });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = {
|
|
77
|
+
// your next config...
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### For Vite Apps
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// vite.config.ts
|
|
85
|
+
import { defineConfig } from 'vite';
|
|
86
|
+
import { initSweetlink } from '@sweetlink/dev-toolkit';
|
|
87
|
+
|
|
88
|
+
if (process.env.NODE_ENV === 'development') {
|
|
89
|
+
initSweetlink({ port: 9223 });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export default defineConfig({
|
|
93
|
+
// your vite config...
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 2. Add Browser Bridge Component
|
|
98
|
+
|
|
99
|
+
#### Basic Usage (Standard Tailwind Colors)
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
// app/root.tsx (Remix) or _app.tsx (Next.js) or App.tsx (React)
|
|
103
|
+
import { SweetlinkBridge } from '@sweetlink/dev-toolkit/browser';
|
|
104
|
+
|
|
105
|
+
export default function App() {
|
|
106
|
+
return (
|
|
107
|
+
<>
|
|
108
|
+
{/* Your app content */}
|
|
109
|
+
{process.env.NODE_ENV === 'development' && <SweetlinkBridge />}
|
|
110
|
+
</>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Custom Theme Colors
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { SweetlinkBridge } from '@sweetlink/dev-toolkit/browser';
|
|
119
|
+
|
|
120
|
+
export default function App() {
|
|
121
|
+
return (
|
|
122
|
+
<>
|
|
123
|
+
{/* Your app content */}
|
|
124
|
+
{process.env.NODE_ENV === 'development' && (
|
|
125
|
+
<SweetlinkBridge
|
|
126
|
+
connectedStyles="bg-terminal-green/20 border-terminal-green text-terminal-green"
|
|
127
|
+
disconnectedStyles="bg-gray-700/20 border-gray-600 text-gray-400"
|
|
128
|
+
/>
|
|
129
|
+
)}
|
|
130
|
+
</>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 3. Add CLI Scripts to package.json
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"scripts": {
|
|
140
|
+
"dev": "run-p dev:app sweetlink:dev",
|
|
141
|
+
"dev:app": "remix dev",
|
|
142
|
+
"sweetlink:dev": "sweetlink-dev",
|
|
143
|
+
"sweetlink": "sweetlink"
|
|
144
|
+
},
|
|
145
|
+
"devDependencies": {
|
|
146
|
+
"npm-run-all": "^4.1.5"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 4. Start Development
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pnpm dev
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
You should see:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
[Sweetlink] WebSocket server started on ws://localhost:9223
|
|
161
|
+
💿 Remix App Server started at http://localhost:3000
|
|
162
|
+
[Sweetlink] Connected to server
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## CLI Usage
|
|
166
|
+
|
|
167
|
+
### Screenshots
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Full page screenshot
|
|
171
|
+
pnpm sweetlink screenshot
|
|
172
|
+
|
|
173
|
+
# Element screenshot
|
|
174
|
+
pnpm sweetlink screenshot --selector ".company-card"
|
|
175
|
+
|
|
176
|
+
# Full page with custom output
|
|
177
|
+
pnpm sweetlink screenshot --full-page --output page.png
|
|
178
|
+
|
|
179
|
+
# Force CDP method (requires Chrome debugging)
|
|
180
|
+
pnpm sweetlink screenshot --force-cdp
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### DOM Queries
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# Query elements
|
|
187
|
+
pnpm sweetlink query --selector "h1"
|
|
188
|
+
|
|
189
|
+
# Get element property
|
|
190
|
+
pnpm sweetlink query --selector ".card" --property "offsetWidth"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Console Logs
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Get all logs
|
|
197
|
+
pnpm sweetlink logs
|
|
198
|
+
|
|
199
|
+
# Filter by error
|
|
200
|
+
pnpm sweetlink logs --filter "error"
|
|
201
|
+
|
|
202
|
+
# JSON output (full array)
|
|
203
|
+
pnpm sweetlink logs --format json
|
|
204
|
+
|
|
205
|
+
# LLM-optimized summary (deduplicated, sorted by severity)
|
|
206
|
+
pnpm sweetlink logs --format summary
|
|
207
|
+
|
|
208
|
+
# Text format with deduplication
|
|
209
|
+
pnpm sweetlink logs --dedupe
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
#### Log Output Formats
|
|
213
|
+
|
|
214
|
+
| Format | Description | Best For |
|
|
215
|
+
|--------|-------------|----------|
|
|
216
|
+
| `text` (default) | Human-readable timestamped lines | Manual debugging |
|
|
217
|
+
| `json` | Full JSON array with all entries | Programmatic access |
|
|
218
|
+
| `summary` | Compact JSON with deduplication | LLM context optimization |
|
|
219
|
+
|
|
220
|
+
**Summary format example:**
|
|
221
|
+
```json
|
|
222
|
+
{
|
|
223
|
+
"url": "http://localhost:3000",
|
|
224
|
+
"capturedAt": "2025-01-27T...",
|
|
225
|
+
"totalLogs": 47,
|
|
226
|
+
"uniqueLogs": 3,
|
|
227
|
+
"byLevel": { "error": 2, "warn": 0, "log": 1 },
|
|
228
|
+
"logs": [
|
|
229
|
+
{ "level": "error", "message": "...", "count": 25 },
|
|
230
|
+
{ "level": "log", "message": "...", "count": 22 }
|
|
231
|
+
]
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Page Refresh
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
# Soft refresh (reload page)
|
|
239
|
+
pnpm sweetlink refresh
|
|
240
|
+
|
|
241
|
+
# Hard refresh (clear cache and reload)
|
|
242
|
+
pnpm sweetlink refresh --hard
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### JavaScript Execution
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Execute JavaScript
|
|
249
|
+
pnpm sweetlink exec --code "document.title"
|
|
250
|
+
|
|
251
|
+
# Count elements
|
|
252
|
+
pnpm sweetlink exec --code "document.querySelectorAll('.card').length"
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Click Elements
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Click by CSS selector
|
|
259
|
+
pnpm sweetlink click --selector "button.submit"
|
|
260
|
+
|
|
261
|
+
# Click by text content
|
|
262
|
+
pnpm sweetlink click --text "Submit"
|
|
263
|
+
|
|
264
|
+
# Combine selector + text for precise matching
|
|
265
|
+
pnpm sweetlink click --selector "th" --text "Rank"
|
|
266
|
+
pnpm sweetlink click --selector "a" --text "BACK TO LIST"
|
|
267
|
+
|
|
268
|
+
# Select nth match (0-based index)
|
|
269
|
+
pnpm sweetlink click --selector ".tab" --index 2
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Options:**
|
|
273
|
+
| Option | Description |
|
|
274
|
+
|--------|-------------|
|
|
275
|
+
| `--selector` | CSS selector to find elements |
|
|
276
|
+
| `--text` | Find element by text content |
|
|
277
|
+
| `--index` | Select nth match when multiple found (default: 0) |
|
|
278
|
+
|
|
279
|
+
**Debugging:** Use `DEBUG=1 pnpm sweetlink click ...` to see generated JavaScript.
|
|
280
|
+
|
|
281
|
+
### Network Requests (CDP Required)
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# Get all network requests
|
|
285
|
+
pnpm sweetlink network
|
|
286
|
+
|
|
287
|
+
# Filter by URL
|
|
288
|
+
pnpm sweetlink network --filter "/api/"
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Chrome DevTools Protocol (CDP) Setup
|
|
292
|
+
|
|
293
|
+
For native Chrome rendering and network inspection:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
# macOS
|
|
297
|
+
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
|
|
298
|
+
|
|
299
|
+
# Linux
|
|
300
|
+
google-chrome --remote-debugging-port=9222
|
|
301
|
+
|
|
302
|
+
# Windows
|
|
303
|
+
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Set environment variable (optional):
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
export CHROME_CDP_PORT=9222
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Programmatic API
|
|
313
|
+
|
|
314
|
+
### Server
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
import { initSweetlink, closeSweetlink } from '@sweetlink/dev-toolkit';
|
|
318
|
+
|
|
319
|
+
// Start server
|
|
320
|
+
const wss = initSweetlink({ port: 9223 });
|
|
321
|
+
|
|
322
|
+
// Close server
|
|
323
|
+
closeSweetlink();
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### CDP Integration
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
import {
|
|
330
|
+
detectCDP,
|
|
331
|
+
getCDPBrowser,
|
|
332
|
+
screenshotViaCDP,
|
|
333
|
+
getNetworkRequestsViaCDP
|
|
334
|
+
} from '@sweetlink/dev-toolkit/cdp';
|
|
335
|
+
|
|
336
|
+
// Check if CDP is available
|
|
337
|
+
const hasCDP = await detectCDP();
|
|
338
|
+
|
|
339
|
+
// Take screenshot via CDP
|
|
340
|
+
const result = await screenshotViaCDP({
|
|
341
|
+
output: 'screenshot.png',
|
|
342
|
+
fullPage: true
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// Get network requests
|
|
346
|
+
const requests = await getNetworkRequestsViaCDP({
|
|
347
|
+
filter: '/api/'
|
|
348
|
+
});
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Browser Component
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import { SweetlinkBridge } from '@sweetlink/dev-toolkit/browser';
|
|
355
|
+
import type { SweetlinkBridgeProps } from '@sweetlink/dev-toolkit/browser';
|
|
356
|
+
|
|
357
|
+
// Default usage (connects to ws://localhost:9223, standard colors)
|
|
358
|
+
<SweetlinkBridge />
|
|
359
|
+
|
|
360
|
+
// Custom theme colors (terminal green)
|
|
361
|
+
<SweetlinkBridge
|
|
362
|
+
connectedStyles="bg-terminal-green/20 border-terminal-green text-terminal-green"
|
|
363
|
+
disconnectedStyles="bg-gray-700/20 border-gray-600 text-gray-400"
|
|
364
|
+
/>
|
|
365
|
+
|
|
366
|
+
// Custom WebSocket URL
|
|
367
|
+
<SweetlinkBridge wsUrl="ws://localhost:9224" />
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
#### SweetlinkBridgeProps
|
|
371
|
+
|
|
372
|
+
| Prop | Type | Default | Description |
|
|
373
|
+
|------|------|---------|-------------|
|
|
374
|
+
| `connectedStyles` | `string` | `'bg-green-500/20 border-green-500 text-green-500'` | Tailwind classes for connected state |
|
|
375
|
+
| `disconnectedStyles` | `string` | `'bg-gray-700/20 border-gray-600 text-gray-400'` | Tailwind classes for disconnected state |
|
|
376
|
+
| `wsUrl` | `string` | `'ws://localhost:9223'` | WebSocket server URL |
|
|
377
|
+
|
|
378
|
+
## Environment Variables
|
|
379
|
+
|
|
380
|
+
| Variable | Default | Description |
|
|
381
|
+
|----------|---------|-------------|
|
|
382
|
+
| `SWEETLINK_WS_PORT` | `9223` | WebSocket server port |
|
|
383
|
+
| `SWEETLINK_WS_URL` | `ws://localhost:9223` | WebSocket URL (CLI) |
|
|
384
|
+
| `CHROME_CDP_PORT` | `9222` | Chrome DevTools Protocol port |
|
|
385
|
+
| `CHROME_CDP_URL` | `http://127.0.0.1:9222` | CDP URL |
|
|
386
|
+
|
|
387
|
+
## Architecture
|
|
388
|
+
|
|
389
|
+
```
|
|
390
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
391
|
+
│ Claude AI Agent (via CLI) │
|
|
392
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
393
|
+
│ │Screenshot│ │ DOM Query│ │ Logs │ │ Exec JS │ │
|
|
394
|
+
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
|
|
395
|
+
│ │ │ │ │ │
|
|
396
|
+
│ └─────────────┴──────────────┴─────────────┘ │
|
|
397
|
+
│ │ │
|
|
398
|
+
└─────────────────────────┼────────────────────────────────────┘
|
|
399
|
+
│
|
|
400
|
+
WebSocket (port 9223)
|
|
401
|
+
│
|
|
402
|
+
┌─────────────────────────┼────────────────────────────────────┐
|
|
403
|
+
│ Sweetlink Server │ │
|
|
404
|
+
│ ┌──────────────────────▼─────────────────────────┐ │
|
|
405
|
+
│ │ WebSocket Server (Multiplexer) │ │
|
|
406
|
+
│ │ - Routes CLI commands to browser │ │
|
|
407
|
+
│ │ - Routes browser responses to CLI │ │
|
|
408
|
+
│ └──────────────────────┬─────────────────────────┘ │
|
|
409
|
+
└─────────────────────────┼────────────────────────────────────┘
|
|
410
|
+
│
|
|
411
|
+
WebSocket (port 9223)
|
|
412
|
+
│
|
|
413
|
+
┌─────────────────────────┼────────────────────────────────────┐
|
|
414
|
+
│ Browser (Your App) │ │
|
|
415
|
+
│ ┌──────────────────────▼─────────────────────────┐ │
|
|
416
|
+
│ │ SweetlinkBridge Component │ │
|
|
417
|
+
│ │ - Captures console logs │ │
|
|
418
|
+
│ │ - Executes commands (screenshot, query, exec) │ │
|
|
419
|
+
│ │ - Auto-reconnects on disconnect │ │
|
|
420
|
+
│ └────────────────────────────────────────────────┘ │
|
|
421
|
+
│ │
|
|
422
|
+
│ ┌────────────────────────────────────────────────┐ │
|
|
423
|
+
│ │ html2canvas (screenshots) │ │
|
|
424
|
+
│ └────────────────────────────────────────────────┘ │
|
|
425
|
+
└───────────────────────────────────────────────────────────────┘
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## Use Cases
|
|
429
|
+
|
|
430
|
+
### Autonomous UI Development
|
|
431
|
+
|
|
432
|
+
```typescript
|
|
433
|
+
while (!designPerfect) {
|
|
434
|
+
// Make UI changes
|
|
435
|
+
await editComponent();
|
|
436
|
+
|
|
437
|
+
// Take screenshot
|
|
438
|
+
await exec('pnpm sweetlink screenshot --selector ".component"');
|
|
439
|
+
|
|
440
|
+
// Check for console errors
|
|
441
|
+
const logs = await exec('pnpm sweetlink logs --filter error');
|
|
442
|
+
|
|
443
|
+
// Iterate until perfect!
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Automated Testing
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
# Take baseline screenshot
|
|
451
|
+
pnpm sweetlink screenshot --output baseline.png
|
|
452
|
+
|
|
453
|
+
# Make changes...
|
|
454
|
+
|
|
455
|
+
# Take comparison screenshot
|
|
456
|
+
pnpm sweetlink screenshot --output comparison.png
|
|
457
|
+
|
|
458
|
+
# Compare screenshots with image diff tool
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Debugging Production Issues
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
# Get console errors
|
|
465
|
+
pnpm sweetlink logs --filter error
|
|
466
|
+
|
|
467
|
+
# Inspect element state
|
|
468
|
+
pnpm sweetlink query --selector ".error-component"
|
|
469
|
+
|
|
470
|
+
# Execute debug code
|
|
471
|
+
pnpm sweetlink exec --code "localStorage.getItem('debug')"
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
## Token Efficiency
|
|
475
|
+
|
|
476
|
+
Sweetlink is designed for token-efficient autonomous loops:
|
|
477
|
+
|
|
478
|
+
- **html2canvas screenshots**: ~131KB (~1,000 tokens)
|
|
479
|
+
- **CDP screenshots**: ~2.0MB (~15,000 tokens)
|
|
480
|
+
- **Default strategy**: Use html2canvas first, escalate to CDP only when needed
|
|
481
|
+
|
|
482
|
+
This 15x token savings enables 10+ autonomous iterations within Claude's budget.
|
|
483
|
+
|
|
484
|
+
## Comparison with Alternatives
|
|
485
|
+
|
|
486
|
+
| Feature | Sweetlink | Playwright MCP | Manual Screenshots |
|
|
487
|
+
|---------|-----------|----------------|-------------------|
|
|
488
|
+
| Setup Time | < 1 min | 5-10 min | N/A |
|
|
489
|
+
| Token Cost | ~1,000 | ~5,000 | N/A |
|
|
490
|
+
| Auto Reconnect | ✅ | ❌ | N/A |
|
|
491
|
+
| Console Logs | ✅ | ✅ | ❌ |
|
|
492
|
+
| Network Requests | ✅ (CDP) | ✅ | ❌ |
|
|
493
|
+
| DOM Queries | ✅ | ✅ | ❌ |
|
|
494
|
+
| JS Execution | ✅ | ✅ | ❌ |
|
|
495
|
+
| Click Elements | ✅ | ✅ | ❌ |
|
|
496
|
+
| Element Screenshots | ✅ | ✅ | ❌ |
|
|
497
|
+
| Full Page Screenshots | ✅ | ✅ | ✅ |
|
|
498
|
+
| Autonomous Loops | ✅ (10+) | Limited (2-3) | ❌ |
|
|
499
|
+
|
|
500
|
+
## When to Use Alternatives
|
|
501
|
+
|
|
502
|
+
### Sweetlink vs Agent Browser vs Playwright
|
|
503
|
+
|
|
504
|
+
**Use Sweetlink when:**
|
|
505
|
+
- You're debugging/iterating on a running dev server
|
|
506
|
+
- You need lightweight, token-efficient screenshots (~1000 tokens vs ~5000)
|
|
507
|
+
- You want real-time console log capture
|
|
508
|
+
- Your app is already running and you just need to inspect it
|
|
509
|
+
- You're doing autonomous UI development loops (10+ iterations)
|
|
510
|
+
|
|
511
|
+
**Use [Agent Browser](https://github.com/vercel-labs/agent-browser) when:**
|
|
512
|
+
- You need full browser automation (navigation, form filling, multi-page flows)
|
|
513
|
+
- You're testing production sites or external URLs
|
|
514
|
+
- Sweetlink isn't integrated into the target application
|
|
515
|
+
- You need Stagehand's AI-powered element selection
|
|
516
|
+
- You're building autonomous agents that interact with arbitrary websites
|
|
517
|
+
|
|
518
|
+
**Use Playwright MCP when:**
|
|
519
|
+
- You need precise, programmatic browser control
|
|
520
|
+
- You're running E2E tests with assertions
|
|
521
|
+
- You need browser contexts, multiple tabs, or complex scenarios
|
|
522
|
+
- You require network interception or request mocking
|
|
523
|
+
|
|
524
|
+
### Agent Browser Quick Start
|
|
525
|
+
|
|
526
|
+
Agent Browser is Vercel's Stagehand-based browser automation tool. It's ideal as a Sweetlink backup for scenarios requiring full browser control.
|
|
527
|
+
|
|
528
|
+
```bash
|
|
529
|
+
# Install globally
|
|
530
|
+
npm install -g @anthropic-ai/agent-browser
|
|
531
|
+
|
|
532
|
+
# Or use npx
|
|
533
|
+
npx @anthropic-ai/agent-browser
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
**Basic usage with Claude:**
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
# Take screenshot of any URL
|
|
540
|
+
agent-browser screenshot https://example.com
|
|
541
|
+
|
|
542
|
+
# Navigate and interact
|
|
543
|
+
agent-browser navigate https://example.com
|
|
544
|
+
agent-browser click "Sign In"
|
|
545
|
+
agent-browser type "username" --into "Email field"
|
|
546
|
+
|
|
547
|
+
# Extract page content
|
|
548
|
+
agent-browser extract "main article content"
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
**Key differences from Sweetlink:**
|
|
552
|
+
|
|
553
|
+
| Aspect | Sweetlink | Agent Browser |
|
|
554
|
+
|--------|-----------|---------------|
|
|
555
|
+
| Setup | Requires app integration | Works with any URL |
|
|
556
|
+
| Token cost | ~1,000/screenshot | ~3,000-5,000/screenshot |
|
|
557
|
+
| Best for | Dev iteration loops | Full browser automation |
|
|
558
|
+
| AI element selection | No (CSS selectors) | Yes (Stagehand AI) |
|
|
559
|
+
| Console logs | Real-time capture | Not available |
|
|
560
|
+
| Requires dev server | Yes | No |
|
|
561
|
+
|
|
562
|
+
**Recommended workflow:**
|
|
563
|
+
1. **During development**: Use Sweetlink for fast, token-efficient iteration
|
|
564
|
+
2. **For external sites or full automation**: Fall back to Agent Browser
|
|
565
|
+
3. **For E2E testing with assertions**: Use Playwright directly
|
|
566
|
+
|
|
567
|
+
## Troubleshooting
|
|
568
|
+
|
|
569
|
+
### WebSocket Connection Fails
|
|
570
|
+
|
|
571
|
+
```bash
|
|
572
|
+
# Check if port is in use
|
|
573
|
+
lsof -i :9223
|
|
574
|
+
|
|
575
|
+
# Try different port
|
|
576
|
+
SWEETLINK_WS_PORT=9224 pnpm dev
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### Browser Not Connected
|
|
580
|
+
|
|
581
|
+
1. Ensure `<SweetlinkBridge />` is rendered in your app
|
|
582
|
+
2. Check browser console for connection errors
|
|
583
|
+
3. Verify WebSocket server is running (`[Sweetlink] WebSocket server started...`)
|
|
584
|
+
|
|
585
|
+
### CDP Not Available
|
|
586
|
+
|
|
587
|
+
1. Start Chrome with debugging: `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222`
|
|
588
|
+
2. Verify CDP endpoint: `curl http://127.0.0.1:9222/json/version`
|
|
589
|
+
3. Check firewall settings
|
|
590
|
+
|
|
591
|
+
## Contributing
|
|
592
|
+
|
|
593
|
+
Contributions welcome! Please open an issue or PR at https://github.com/ytspar/devtools
|
|
594
|
+
|
|
595
|
+
## License
|
|
596
|
+
|
|
597
|
+
MIT
|
|
598
|
+
|
|
599
|
+
## Credits
|
|
600
|
+
|
|
601
|
+
- Inspired by [Peter Steinberger's autonomous debugging](https://x.com/steipete/status/1981998733736001727)
|
|
602
|
+
- Powered by html2canvas, Puppeteer, and WebSocket
|