barebrowse 0.2.0 → 0.2.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/CHANGELOG.md +7 -0
- package/README.md +100 -179
- package/mcp-server.js +1 -1
- package/package.json +1 -1
- package/.claude/memory/AGENT_RULES.md +0 -251
- package/.claude/settings.local.json +0 -30
- package/.claude/stash/barebrowse-research-2026-02-22.md +0 -49
- package/.claude/stash/phase3-interactions-complete.md +0 -69
- package/.claude/stash/phase3-prep.md +0 -88
- package/docs/poc-plan.md +0 -230
- package/docs/prd.md +0 -284
- package/examples/headed-demo.js +0 -157
- package/examples/yt-demo.js +0 -137
- package/test/integration/browse.test.js +0 -108
- package/test/integration/interact.test.js +0 -514
- package/test/unit/auth.test.js +0 -66
- package/test/unit/cdp.test.js +0 -110
- package/test/unit/prune.test.js +0 -292
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
- README rewritten: no code blocks, full obstacle course table with mode column, two usage paths (MCP vs framework), mcprune credited, measured token savings, context.md as code reference
|
|
6
|
+
- MCP auto-installer: `npx barebrowse install` detects Claude Desktop, Cursor, Claude Code and writes config
|
|
7
|
+
- MCP config uses `npx barebrowse mcp` instead of local file paths (works for npm consumers)
|
|
8
|
+
- CLI help updated with install command
|
|
9
|
+
|
|
3
10
|
## 0.2.0
|
|
4
11
|
|
|
5
12
|
Agent integration release. MCP server, bareagent adapter, and interaction features that make barebrowse usable as a standalone tool or embedded browsing layer.
|
package/README.md
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
```
|
|
2
|
+
~~~~~~~~~~~~~~~~~~~~
|
|
3
|
+
~~~ .---------. ~~~
|
|
4
|
+
~~~ | · clear | ~~~
|
|
5
|
+
~~~ | · focus | ~~~
|
|
6
|
+
~~~ '---------' ~~~
|
|
7
|
+
~~~~~~~~~~~~~~~~~~~~
|
|
8
|
+
|
|
9
|
+
barebrowse
|
|
10
|
+
```
|
|
4
11
|
|
|
5
|
-
|
|
12
|
+
> Your agent browses like you do -- same browser, same logins, same cookies.
|
|
13
|
+
> Prunes pages down to what matters. 40-90% fewer tokens, zero wasted context.
|
|
6
14
|
|
|
7
|
-
|
|
15
|
+
---
|
|
8
16
|
|
|
9
|
-
##
|
|
17
|
+
## What this is
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
barebrowse is agentic browsing stripped to the bone. It gives your AI agent eyes and hands on the web -- navigate any page, see what's there, click buttons, fill forms, scroll, and move on. It uses your installed Chromium browser (Chrome, Brave, Edge -- whatever you have), reuses your existing login sessions, and handles all the friction automatically: cookie consent walls, permission prompts, bot detection, GDPR dialogs.
|
|
12
20
|
|
|
13
|
-
|
|
21
|
+
Instead of dumping raw DOM or taking screenshots, barebrowse returns a **pruned ARIA snapshot** -- a compact semantic view of what's on the page and what the agent can interact with. Buttons, links, inputs, headings -- labeled with `[ref=N]` markers the agent uses to act. The pruning pipeline is ported from [mcprune](https://github.com/hamr0/mcprune) and cuts 40-90% of tokens compared to raw page output. Every token your agent reads is meaningful.
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
No Playwright. No bundled browser. No 200MB download. No broken dependencies. Zero deps. Just CDP over a WebSocket to whatever Chromium you already have.
|
|
16
24
|
|
|
17
25
|
## Install
|
|
18
26
|
|
|
@@ -20,204 +28,117 @@ The snapshot format uses `[ref=N]` markers on interactive elements. The agent sa
|
|
|
20
28
|
npm install barebrowse
|
|
21
29
|
```
|
|
22
30
|
|
|
23
|
-
Requires Node.js >= 22 and any installed Chromium-based browser
|
|
24
|
-
|
|
25
|
-
## Quick start
|
|
26
|
-
|
|
27
|
-
```javascript
|
|
28
|
-
import { browse } from 'barebrowse';
|
|
29
|
-
|
|
30
|
-
// One line. That's it.
|
|
31
|
-
const snapshot = await browse('https://news.ycombinator.com');
|
|
32
|
-
console.log(snapshot);
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Output (pruned, ~50% smaller than raw):
|
|
36
|
-
```
|
|
37
|
-
- WebArea "Hacker News" [ref=1]
|
|
38
|
-
- link "Hacker News" [ref=4]
|
|
39
|
-
- link "new" [ref=7]
|
|
40
|
-
- link "past" [ref=9]
|
|
41
|
-
- link "comments" [ref=11]
|
|
42
|
-
...
|
|
43
|
-
- link "Show HN: I built a thing" [ref=42]
|
|
44
|
-
- link "197 comments" [ref=45]
|
|
45
|
-
```
|
|
31
|
+
Requires Node.js >= 22 and any installed Chromium-based browser.
|
|
46
32
|
|
|
47
33
|
## Two ways to use it
|
|
48
34
|
|
|
49
|
-
### 1.
|
|
35
|
+
### 1. MCP server -- for Claude Desktop, Cursor, Claude Code
|
|
50
36
|
|
|
51
|
-
Import and call directly. You control the loop.
|
|
52
|
-
|
|
53
|
-
**One-shot** — read a page and get the snapshot:
|
|
54
|
-
|
|
55
|
-
```javascript
|
|
56
|
-
import { browse } from 'barebrowse';
|
|
57
|
-
|
|
58
|
-
const snapshot = await browse('https://example.com', {
|
|
59
|
-
mode: 'headless', // 'headless' | 'headed' | 'hybrid'
|
|
60
|
-
cookies: true, // inject cookies from your browser
|
|
61
|
-
prune: true, // ARIA pruning (47-95% token reduction)
|
|
62
|
-
consent: true, // auto-dismiss cookie consent dialogs
|
|
63
|
-
});
|
|
64
37
|
```
|
|
65
|
-
|
|
66
|
-
**Session** — navigate and interact across multiple pages:
|
|
67
|
-
|
|
68
|
-
```javascript
|
|
69
|
-
import { connect } from 'barebrowse';
|
|
70
|
-
|
|
71
|
-
const page = await connect();
|
|
72
|
-
await page.goto('https://duckduckgo.com');
|
|
73
|
-
|
|
74
|
-
let snap = await page.snapshot();
|
|
75
|
-
// Agent sees: combobox "Search" [ref=5]
|
|
76
|
-
|
|
77
|
-
await page.type('5', 'barebrowse github');
|
|
78
|
-
await page.press('Enter');
|
|
79
|
-
await page.waitForNavigation();
|
|
80
|
-
|
|
81
|
-
snap = await page.snapshot();
|
|
82
|
-
// Agent sees search results with clickable refs
|
|
83
|
-
|
|
84
|
-
await page.click('12'); // click first result
|
|
85
|
-
await page.close();
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### 2. As an MCP server
|
|
89
|
-
|
|
90
|
-
For Claude Desktop, Cursor, Windsurf, or any MCP client.
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
38
|
npm install -g barebrowse
|
|
94
39
|
npx barebrowse install
|
|
95
40
|
```
|
|
96
41
|
|
|
97
|
-
That's it. `install` auto-detects
|
|
98
|
-
|
|
99
|
-
If you prefer manual setup, add this to your MCP config:
|
|
100
|
-
```json
|
|
101
|
-
{
|
|
102
|
-
"mcpServers": {
|
|
103
|
-
"barebrowse": {
|
|
104
|
-
"command": "npx",
|
|
105
|
-
"args": ["barebrowse", "mcp"]
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
```
|
|
42
|
+
That's it. `install` auto-detects your MCP client and writes the config. No manual JSON editing. Restart your client and you have 7 browsing tools: `browse`, `goto`, `snapshot`, `click`, `type`, `press`, `scroll`.
|
|
110
43
|
|
|
111
|
-
|
|
44
|
+
### 2. Framework -- for agentic automation
|
|
112
45
|
|
|
113
|
-
|
|
46
|
+
Import barebrowse in your agent code. One-shot reads, interactive sessions, full observe-think-act loops. Works with any LLM orchestration library. Ships with a ready-made adapter for [bareagent](https://www.npmjs.com/package/bare-agent) (9 tools, auto-snapshot after every action).
|
|
114
47
|
|
|
115
|
-
|
|
48
|
+
For code examples, API reference, and wiring instructions, see **[barebrowse.context.md](barebrowse.context.md)** -- the full integration guide.
|
|
116
49
|
|
|
117
|
-
|
|
118
|
-
|------|------|-------------|---------|
|
|
119
|
-
| **Headless** | `mode: 'headless'` (default) | Launches a fresh Chromium, no UI | Scraping, reading, fast automation |
|
|
120
|
-
| **Headed** | `mode: 'headed'` | Connects to your running browser via CDP port | Bot-detected sites, visual debugging |
|
|
121
|
-
| **Hybrid** | `mode: 'hybrid'` | Tries headless first, falls back to headed if bot-blocked | General-purpose agent browsing |
|
|
50
|
+
## Three modes
|
|
122
51
|
|
|
123
|
-
|
|
52
|
+
| Mode | What happens | Best for |
|
|
53
|
+
|------|-------------|----------|
|
|
54
|
+
| **Headless** (default) | Launches a fresh Chromium, no UI | Fast automation, scraping, reading pages |
|
|
55
|
+
| **Headed** | Connects to your running browser on CDP port | Bot-detected sites, visual debugging, CAPTCHAs |
|
|
56
|
+
| **Hybrid** | Tries headless first, falls back to headed if blocked | General-purpose agent browsing |
|
|
124
57
|
|
|
125
58
|
## What it handles automatically
|
|
126
59
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
|
60
|
+
This is the obstacle course your agent doesn't have to think about:
|
|
61
|
+
|
|
62
|
+
| Obstacle | How it's handled | Mode |
|
|
63
|
+
|----------|-----------------|------|
|
|
64
|
+
| **Cookie consent walls** (GDPR) | ARIA tree scan + jsClick accept button, 7 languages (EN, NL, DE, FR, ES, IT, PT) | Both |
|
|
65
|
+
| **Consent in dialog role** | Detect `dialog`/`alertdialog` with consent hints, click accept inside | Both |
|
|
66
|
+
| **Consent outside dialog** (BBC SourcePoint) | Fallback global button scan when dialog has no accept button | Both |
|
|
67
|
+
| **Consent behind iframe overlay** | JS click via DOM.resolveNode bypasses z-index/overlay issues | Both |
|
|
68
|
+
| **Permission prompts** (location, camera, mic) | Launch flags + CDP Browser.setPermission auto-deny | Both |
|
|
69
|
+
| **Media autoplay blocked** | Autoplay policy flag on launch | Both |
|
|
70
|
+
| **Login walls** | Cookie extraction from Firefox/Chromium, injected via CDP | Both |
|
|
71
|
+
| **Pre-filled form inputs** | Select-all + delete before typing | Both |
|
|
72
|
+
| **Off-screen elements** | Scrolled into view before every click | Both |
|
|
73
|
+
| **Form submission** | Enter key triggers onsubmit | Both |
|
|
74
|
+
| **Tab between fields** | Tab key moves focus correctly | Both |
|
|
75
|
+
| **SPA navigation** (YouTube, GitHub) | SPA-aware wait: frameNavigated + loadEventFired | Both |
|
|
76
|
+
| **Bot detection** (Google, Reddit) | Stealth patches (headless) + headed fallback with real cookies | Both |
|
|
77
|
+
| **navigator.webdriver leak** | Patched before page scripts run: webdriver, plugins, languages, chrome object | Headless |
|
|
78
|
+
| **Profile locking** | Unique temp dir per headless instance | Headless |
|
|
79
|
+
| **ARIA noise** | 9-step pruning pipeline (ported from mcprune): wrapper collapse, noise removal, landmark promotion | Both |
|
|
80
|
+
|
|
81
|
+
## What the agent sees
|
|
82
|
+
|
|
83
|
+
Raw ARIA output from a page is noisy -- decorative wrappers, hidden elements, structural junk. The pruning pipeline (ported from [mcprune](https://github.com/hamr0/mcprune)) strips it down to what matters.
|
|
84
|
+
|
|
85
|
+
| Page | Raw | Pruned | Reduction |
|
|
86
|
+
|------|-----|--------|-----------|
|
|
87
|
+
| example.com | 377 chars | 45 chars | 88% |
|
|
88
|
+
| Hacker News | 51,726 chars | 27,197 chars | 47% |
|
|
89
|
+
| Wikipedia (article) | 109,479 chars | 40,566 chars | 63% |
|
|
90
|
+
| DuckDuckGo | 42,254 chars | 5,407 chars | 87% |
|
|
91
|
+
|
|
92
|
+
Two pruning modes: **act** (default) keeps interactive elements and visible labels -- for clicking, typing, navigating. **read** keeps all text content -- for reading articles and extracting information.
|
|
93
|
+
|
|
94
|
+
## Actions
|
|
95
|
+
|
|
96
|
+
Everything the agent can do through barebrowse:
|
|
97
|
+
|
|
98
|
+
| Action | What it does |
|
|
140
99
|
|--------|-------------|
|
|
141
|
-
|
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
|
|
|
148
|
-
|
|
|
149
|
-
|
|
|
150
|
-
|
|
|
151
|
-
|
|
|
152
|
-
|
|
|
153
|
-
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
```javascript
|
|
161
|
-
import { Loop } from 'bare-agent';
|
|
162
|
-
import { Anthropic } from 'bare-agent/providers';
|
|
163
|
-
import { createBrowseTools } from 'barebrowse/bareagent';
|
|
164
|
-
|
|
165
|
-
const provider = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
|
|
166
|
-
const loop = new Loop({ provider });
|
|
167
|
-
|
|
168
|
-
const { tools, close } = createBrowseTools();
|
|
169
|
-
try {
|
|
170
|
-
const result = await loop.run(
|
|
171
|
-
[{ role: 'user', content: 'Find the top story on Hacker News' }],
|
|
172
|
-
tools
|
|
173
|
-
);
|
|
174
|
-
console.log(result.text);
|
|
175
|
-
} finally {
|
|
176
|
-
await close();
|
|
177
|
-
}
|
|
178
|
-
```
|
|
100
|
+
| **Navigate** | Load a URL, wait for page load, auto-dismiss consent |
|
|
101
|
+
| **Snapshot** | Pruned ARIA tree with `[ref=N]` markers (40-90% token reduction) |
|
|
102
|
+
| **Click** | Scroll into view + mouse click at element center |
|
|
103
|
+
| **Type** | Focus + insert text, with option to clear existing content first |
|
|
104
|
+
| **Press** | Special keys: Enter, Tab, Escape, Backspace, Delete, arrows, Space |
|
|
105
|
+
| **Scroll** | Mouse wheel up or down |
|
|
106
|
+
| **Hover** | Move mouse to element center (triggers tooltips, hover states) |
|
|
107
|
+
| **Select** | Set dropdown value (native select or custom dropdown) |
|
|
108
|
+
| **Screenshot** | Page capture as base64 PNG/JPEG/WebP |
|
|
109
|
+
| **Wait for navigation** | SPA-aware: works for full page loads and pushState |
|
|
110
|
+
| **Wait for network idle** | Resolve when no pending requests for 500ms |
|
|
111
|
+
| **Inject cookies** | Extract from Firefox/Chromium and inject via CDP |
|
|
112
|
+
| **Raw CDP** | Escape hatch for any Chrome DevTools Protocol command |
|
|
113
|
+
|
|
114
|
+
## Tested against
|
|
115
|
+
|
|
116
|
+
16+ sites across 8 countries, all consent dialogs dismissed, all interactions working:
|
|
117
|
+
|
|
118
|
+
Google, YouTube, BBC, Wikipedia, GitHub, DuckDuckGo, Hacker News, Amazon DE, The Guardian, Spiegel, Le Monde, El Pais, Corriere, NOS, Bild, Nu.nl, Booking, NYT, Stack Overflow, CNN, Reddit
|
|
179
119
|
|
|
180
|
-
|
|
120
|
+
## Context file
|
|
181
121
|
|
|
182
|
-
|
|
122
|
+
**[barebrowse.context.md](barebrowse.context.md)** is the full integration guide. Feed it to an AI assistant or read it yourself -- it covers the complete API, snapshot format, interaction loop, auth options, bareagent wiring, MCP setup, and gotchas. Everything you need to wire barebrowse into a project.
|
|
183
123
|
|
|
184
124
|
## How it works
|
|
185
125
|
|
|
186
126
|
```
|
|
187
|
-
URL ->
|
|
188
|
-
->
|
|
189
|
-
-> stealth
|
|
190
|
-
->
|
|
191
|
-
->
|
|
192
|
-
->
|
|
193
|
-
->
|
|
194
|
-
->
|
|
195
|
-
->
|
|
196
|
-
->
|
|
197
|
-
->
|
|
127
|
+
URL -> find/launch browser (chromium.js)
|
|
128
|
+
-> WebSocket CDP connection (cdp.js)
|
|
129
|
+
-> stealth patches before page scripts (stealth.js, headless only)
|
|
130
|
+
-> suppress all permission prompts (Browser.setPermission)
|
|
131
|
+
-> extract + inject cookies from your browser (auth.js)
|
|
132
|
+
-> navigate to URL, wait for load
|
|
133
|
+
-> detect + dismiss cookie consent dialogs (consent.js)
|
|
134
|
+
-> get full ARIA accessibility tree (aria.js)
|
|
135
|
+
-> 9-step pruning pipeline from mcprune (prune.js)
|
|
136
|
+
-> dispatch real input events: click/type/scroll (interact.js)
|
|
137
|
+
-> agent-ready snapshot with [ref=N] markers
|
|
198
138
|
```
|
|
199
139
|
|
|
200
140
|
11 modules, 2,400 lines, zero dependencies.
|
|
201
141
|
|
|
202
|
-
## Token savings
|
|
203
|
-
|
|
204
|
-
Real-world measurements on the pruning pipeline:
|
|
205
|
-
|
|
206
|
-
| Page | Raw ARIA | Pruned (act) | Reduction | Est. cost saved |
|
|
207
|
-
|------|----------|-------------|-----------|----------------|
|
|
208
|
-
| Hacker News | 52K chars | 27K chars | 47% | ~$0.04/call |
|
|
209
|
-
| Wikipedia article | 180K chars | 12K chars | 93% | ~$0.25/call |
|
|
210
|
-
| Amazon product | 95K chars | 8K chars | 92% | ~$0.13/call |
|
|
211
|
-
| Google results | 45K chars | 5K chars | 89% | ~$0.06/call |
|
|
212
|
-
|
|
213
|
-
Two pruning modes:
|
|
214
|
-
- **act** (default) — keeps interactive elements + visible labels. For clicking, typing, navigating.
|
|
215
|
-
- **read** — keeps all text content. For reading articles, extracting information.
|
|
216
|
-
|
|
217
|
-
## Context file
|
|
218
|
-
|
|
219
|
-
`barebrowse.context.md` in the repo root is an LLM-consumable integration guide. Feed it to an AI assistant that needs to wire barebrowse into a project — it covers the full API, snapshot format, interaction loop, auth options, and gotchas.
|
|
220
|
-
|
|
221
142
|
## Requirements
|
|
222
143
|
|
|
223
144
|
- Node.js >= 22 (built-in WebSocket, built-in SQLite)
|
package/mcp-server.js
CHANGED
|
@@ -149,7 +149,7 @@ async function handleMessage(msg) {
|
|
|
149
149
|
return jsonrpcResponse(id, {
|
|
150
150
|
protocolVersion: '2024-11-05',
|
|
151
151
|
capabilities: { tools: {} },
|
|
152
|
-
serverInfo: { name: 'barebrowse', version: '0.2.
|
|
152
|
+
serverInfo: { name: 'barebrowse', version: '0.2.2' },
|
|
153
153
|
});
|
|
154
154
|
}
|
|
155
155
|
|
package/package.json
CHANGED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
# AI Agent Collaboration Guide
|
|
2
|
-
|
|
3
|
-
## Table of Contents
|
|
4
|
-
1. [Communication Protocol](#communication-protocol)
|
|
5
|
-
2. [Development Standards](#development-standards)
|
|
6
|
-
3. [Testing Standards](#testing-standards)
|
|
7
|
-
4. [Environment](#environment)
|
|
8
|
-
5. [Development Workflow](#development-workflow)
|
|
9
|
-
6. [Twelve-Factor Reference](#twelve-factor-reference)
|
|
10
|
-
7. [CLAUDE.md Stub](#claudemd-stub)
|
|
11
|
-
8. [AI Agent Instructions](#ai-agent-instructions)
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Communication Protocol
|
|
16
|
-
|
|
17
|
-
### Core Rules
|
|
18
|
-
- **Clarity First**: Always ask clarifying questions when requirements are ambiguous
|
|
19
|
-
- **Fact-Based**: Base all recommendations on verified, current information
|
|
20
|
-
- **Simplicity Advocate**: Call out overcomplications and suggest simpler alternatives
|
|
21
|
-
- **Safety First**: Never modify critical systems without explicit understanding and approval
|
|
22
|
-
|
|
23
|
-
### User Profile
|
|
24
|
-
- **Technical Level**: Non-coder but technically savvy
|
|
25
|
-
- **Learning Style**: Understands concepts, needs executable instructions
|
|
26
|
-
- **Expects**: Step-by-step guidance with clear explanations
|
|
27
|
-
- **Comfortable with**: Command-line operations and scripts
|
|
28
|
-
|
|
29
|
-
### Required Safeguards
|
|
30
|
-
- Always identify affected files before making changes
|
|
31
|
-
- Never modify authentication systems without explicit permission
|
|
32
|
-
- Never alter database schema without proper migration files
|
|
33
|
-
- Explain what changes will be made and why
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Development Standards
|
|
38
|
-
|
|
39
|
-
### Validate Before You Build
|
|
40
|
-
|
|
41
|
-
- **POC everything first.** Before committing to a design, build a quick proof-of-concept (~15 min) that validates the core logic. Keep it stupidly simple — manual steps are fine, hardcoded values are fine, no tests needed yet
|
|
42
|
-
- **POC scope:** Cover the happy path and 2-3 common edge cases. If those work, the idea is sound
|
|
43
|
-
- **Graduation criteria:** POC validates logic and covers most common scenarios → stop, design properly, then build with structure, tests, and error handling. Never ship the POC — rewrite it
|
|
44
|
-
- **Build incrementally.** After POC graduates, break the work into small, independent modules. Focus on one at a time. Each piece must work on its own before integrating with the next
|
|
45
|
-
|
|
46
|
-
### Dependency Hierarchy
|
|
47
|
-
|
|
48
|
-
Always exhaust the simpler option before reaching for the next:
|
|
49
|
-
|
|
50
|
-
1. **Vanilla language** — Write it yourself using only language primitives. If it's <50 lines and not security-critical, this is the answer
|
|
51
|
-
2. **Standard library** — Use built-in modules (`os`, `json`, `pathlib`, `http`, `fs`, `crypto`). The stdlib is tested, maintained, and has zero supply chain risk
|
|
52
|
-
3. **External library** — Only when both vanilla and stdlib are insufficient. Must pass the checklist below
|
|
53
|
-
|
|
54
|
-
### External Dependency Checklist
|
|
55
|
-
|
|
56
|
-
Before adding any external dependency, all of these must be true:
|
|
57
|
-
- **Necessity:** Can't reasonably implement this with stdlib in <100 lines
|
|
58
|
-
- **Maintained:** Active commits in the last 6 months, responsive maintainer
|
|
59
|
-
- **Lightweight:** Few transitive dependencies (check the dep tree, not just the top-level)
|
|
60
|
-
- **Established:** Widely used, not a single-maintainer hobby project for production-critical code
|
|
61
|
-
- **Security-aware:** For security-critical domains (crypto, auth, sanitization, parsing untrusted input), a vetted library is *required* — never roll your own
|
|
62
|
-
|
|
63
|
-
### Language Selection
|
|
64
|
-
|
|
65
|
-
- **Use widely-adopted languages only** — Python, JavaScript/TypeScript, Go, Rust. No niche languages unless the domain demands it
|
|
66
|
-
- **Pick the lightest language that fits the domain:** shell scripts for automation, Python for data/backend/CLI, TypeScript for web, Go for systems/infra, Rust for performance-critical
|
|
67
|
-
- **Minimize the polyglot tax.** Every language in the stack adds CI config, tooling, and onboarding friction. Do not add a new language for one microservice — use what's already in the stack unless there's a compelling reason
|
|
68
|
-
- **Vanilla over frameworks.** Express over NestJS, Flask over Django, unless the project genuinely needs the framework's structure. Structure can always be added later; removing a framework is painful
|
|
69
|
-
|
|
70
|
-
### Build Rules
|
|
71
|
-
|
|
72
|
-
- **Open-source only.** Always use open-source solutions. No vendor lock-in
|
|
73
|
-
- **Lightweight over complex.** If two solutions solve the same problem, use the one with fewer moving parts, fewer dependencies, and less configuration
|
|
74
|
-
- **Every line must have a purpose.** No speculative code, no "might need this later", no abstractions for one use case
|
|
75
|
-
- **Simple > clever.** Readable code that a junior can follow beats elegant code that requires a PhD to debug
|
|
76
|
-
- **Containerize only when necessary.** Start with a virtualenv or bare metal. Docker adds value for deployment parity and isolation — not for running a script
|
|
77
|
-
|
|
78
|
-
### Red Flags — Stop and Flag These
|
|
79
|
-
- Over-engineering simple problems
|
|
80
|
-
- Adding external dependencies for trivial operations
|
|
81
|
-
- Frameworks where a library or stdlib would suffice
|
|
82
|
-
- Vendor-specific implementations when open alternatives exist
|
|
83
|
-
- Skipping POC validation for unproven ideas
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## Testing Standards
|
|
88
|
-
|
|
89
|
-
### Rules
|
|
90
|
-
|
|
91
|
-
**Test behavior, not implementation.** A test suite must give you confidence to refactor freely. If changing internal code (without changing behavior) breaks tests, those tests are liabilities, not assets.
|
|
92
|
-
|
|
93
|
-
**Follow the Testing Trophy** (not the Testing Pyramid):
|
|
94
|
-
- Few unit tests — only for pure logic, algorithms, and complex calculations
|
|
95
|
-
- Many integration tests — the sweet spot; test real components working together
|
|
96
|
-
- Some E2E tests — cover critical user journeys end-to-end
|
|
97
|
-
- Static analysis — types and linters catch bugs cheaper than tests
|
|
98
|
-
|
|
99
|
-
### When to Write Tests
|
|
100
|
-
|
|
101
|
-
- **After the design stabilizes, not during exploration.** Do not TDD a prototype — you'll write 500 tests for code you delete tomorrow. First make it work (POC), then make it right (refactor + tests), then make it fast
|
|
102
|
-
- **Write tests when the code has users.** If a function is called by other modules or exposed to users, it needs tests. Internal helpers that only serve one caller don't need their own test file
|
|
103
|
-
- **Write tests for bugs.** Every bug fix must include a regression test that fails before the fix and passes after. This is the highest-value test you can write
|
|
104
|
-
- **Write tests before refactoring.** Before changing working code, write characterization tests first to lock in current behavior, then refactor with confidence
|
|
105
|
-
- **Do not write tests for glue code.** Code that just wires components together (calls A then B then C) is tested at the integration level, not unit level
|
|
106
|
-
|
|
107
|
-
### TDD: When It Works and When It Doesn't
|
|
108
|
-
|
|
109
|
-
- **TDD works for:** Pure functions, algorithms, parsers, validators, data transformations — anything with clear inputs and outputs
|
|
110
|
-
- **TDD does not work for:** Exploring a design, building a POC, or unstable interfaces. Writing tests for unstable APIs creates churn and false confidence
|
|
111
|
-
- **The rule:** You must understand what you're building before you TDD it. TDD is a design tool for known problems, not a discovery tool for unknown ones
|
|
112
|
-
- **Red-green-refactor discipline:** If you do TDD, follow the cycle strictly. Write a failing test, write minimal code to pass, refactor. Do not write 20 tests then implement — that's front-loading waste
|
|
113
|
-
|
|
114
|
-
### What Makes a Good Test
|
|
115
|
-
|
|
116
|
-
- **Tests real behavior.** Call the public API, assert on observable output. Do not reach into internals
|
|
117
|
-
- **Fails for the right reason.** A good test fails when the feature is broken, not when the implementation changes
|
|
118
|
-
- **Reads like a spec.** Someone unfamiliar with the code must understand what the feature does by reading the test
|
|
119
|
-
- **Self-contained.** Each test sets up its own state, runs, and cleans up. No ordering dependencies between tests
|
|
120
|
-
- **Fast and deterministic.** Flaky tests erode trust. If a test depends on timing, network, or global state, fix that dependency
|
|
121
|
-
|
|
122
|
-
### Anti-Patterns — Do Not Do These
|
|
123
|
-
|
|
124
|
-
- **Mocking more than 60% of the test.** If most of the test is mock setup, you're testing mocks, not code. Use real implementations with `tmp_path`, `:memory:` SQLite, or test containers
|
|
125
|
-
- **Smoke tests.** `assert result is not None` proves nothing. Assert on specific values, structure, or side effects
|
|
126
|
-
- **Testing private methods.** If you need to test a private method, either it should be public or the public method's tests should cover it
|
|
127
|
-
- **Mirroring implementation.** Tests that replicate the source code line-by-line break on every refactor and catch zero bugs
|
|
128
|
-
- **Test-only production code.** Never add methods, flags, or branches to production code solely for testing. Use dependency injection instead
|
|
129
|
-
|
|
130
|
-
### Test Organization
|
|
131
|
-
|
|
132
|
-
- **Co-locate tests with packages:** `packages/<pkg>/tests/` not a root `tests/` directory. Each package owns its tests
|
|
133
|
-
- **Separate by type:**
|
|
134
|
-
```
|
|
135
|
-
packages/<pkg>/tests/
|
|
136
|
-
unit/ # Fast, isolated, mocked deps, <1s each
|
|
137
|
-
integration/ # Real DB, filesystem, multi-component, <10s each
|
|
138
|
-
e2e/ # Full workflows, subprocess calls, <60s each
|
|
139
|
-
conftest.py # Shared fixtures for this package
|
|
140
|
-
```
|
|
141
|
-
- **One test file per module** (not per function). `test_auth.py` tests the auth module, not `test_login.py` + `test_logout.py` + `test_session.py`
|
|
142
|
-
- **No duplicate test files.** Before creating a new test file, check if one already exists for that module
|
|
143
|
-
|
|
144
|
-
### Markers and Signals
|
|
145
|
-
|
|
146
|
-
| Marker | Purpose | CI Behavior |
|
|
147
|
-
|--------|---------|-------------|
|
|
148
|
-
| `@pytest.mark.slow` | Runtime > 5s | Run in full suite, skip in quick checks |
|
|
149
|
-
| `@pytest.mark.ml` | Requires ML deps (torch, etc.) | Skip if deps not installed |
|
|
150
|
-
| `@pytest.mark.real_api` | Calls external APIs | Skip in CI — run manually before release |
|
|
151
|
-
|
|
152
|
-
**CI runs for fast signals:**
|
|
153
|
-
- `pytest -m "not slow and not ml and not real_api"` — fast gate on every push (~30s)
|
|
154
|
-
- `pytest` — full suite on PR merge or nightly
|
|
155
|
-
- Package-level runs for targeted debugging: `pytest packages/core/tests/`
|
|
156
|
-
|
|
157
|
-
### Coverage and Ratios
|
|
158
|
-
|
|
159
|
-
- **Do not chase a coverage number.** 80% coverage with meaningless tests is worse than 40% with behavior-testing integration tests
|
|
160
|
-
- **Cover the critical path first.** Data layer, auth, payment, core business logic — before helper utilities
|
|
161
|
-
- **Coverage tells you what's NOT tested, not what IS tested.** High coverage with bad assertions is false confidence
|
|
162
|
-
- **Delete tests that don't catch bugs.** If a test has never failed (or only fails on refactors), it's not providing value
|
|
163
|
-
|
|
164
|
-
**Target ratio:** ~20% unit, ~60% integration, ~15% E2E, ~5% manual/exploratory
|
|
165
|
-
|
|
166
|
-
### Test Tooling Standards
|
|
167
|
-
|
|
168
|
-
- Use `tmp_path` for filesystem tests, `:memory:` or `tmp_path` SQLite for DB tests
|
|
169
|
-
- Use dependency injection over `@patch` — it's more readable and survives refactors
|
|
170
|
-
- Tests must be self-sufficient — no dependency on project directories, user config, or environment state
|
|
171
|
-
- Use factories or builders for test data, not raw constructors with 15 arguments
|
|
172
|
-
- Keep test fixtures close to where they're used. Shared fixtures in `conftest.py`, not a global test utilities package
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## Environment
|
|
177
|
-
|
|
178
|
-
- **OS**: Fedora Linux (use `dnf` for packages, `systemctl` for services)
|
|
179
|
-
- **Testing**: pytest (Python), Jest/Vitest (JS/TS), Playwright (browser automation)
|
|
180
|
-
|
|
181
|
-
---
|
|
182
|
-
|
|
183
|
-
## Development Workflow
|
|
184
|
-
|
|
185
|
-
### Environments
|
|
186
|
-
- **Development**: Local machines
|
|
187
|
-
- **Staging**: VPS with isolated database
|
|
188
|
-
- **Production**: VPS with containerized setup
|
|
189
|
-
|
|
190
|
-
### Deployment Strategy
|
|
191
|
-
|
|
192
|
-
**Simple Projects:** `Local → GitHub → VPS (direct deployment)`
|
|
193
|
-
|
|
194
|
-
**Complex Projects:** `Local → GitHub → GHCR → VPS (containerized)`
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
## Twelve-Factor Reference
|
|
199
|
-
|
|
200
|
-
The [Twelve-Factor App](https://12factor.net) methodology for modern, scalable applications:
|
|
201
|
-
|
|
202
|
-
| # | Factor | Rule |
|
|
203
|
-
|---|--------|------|
|
|
204
|
-
| 1 | Codebase | One repo per app, multiple deploys from same codebase |
|
|
205
|
-
| 2 | Dependencies | Explicitly declare and isolate all dependencies |
|
|
206
|
-
| 3 | Config | Store config in environment variables, never in code |
|
|
207
|
-
| 4 | Backing Services | Treat databases, caches, queues as attached resources |
|
|
208
|
-
| 5 | Build, Release, Run | Strict separation between build, release, and run stages |
|
|
209
|
-
| 6 | Processes | Run as stateless processes, persist state externally |
|
|
210
|
-
| 7 | Port Binding | Apps are self-contained, export services via port binding |
|
|
211
|
-
| 8 | Concurrency | Scale out via the process model, not bigger instances |
|
|
212
|
-
| 9 | Disposability | Fast startup, graceful shutdown, idempotent operations |
|
|
213
|
-
| 10 | Dev/Prod Parity | Keep dev, staging, and production as similar as possible |
|
|
214
|
-
| 11 | Logs | Treat logs as event streams to stdout |
|
|
215
|
-
| 12 | Admin Processes | Run admin/maintenance tasks as one-off processes |
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## CLAUDE.md Stub
|
|
220
|
-
|
|
221
|
-
Copy this to any project's CLAUDE.md. These are mandatory rules, not suggestions.
|
|
222
|
-
|
|
223
|
-
```markdown
|
|
224
|
-
## Dev Rules
|
|
225
|
-
|
|
226
|
-
**POC first.** Always validate logic with a ~15min proof-of-concept before building. Cover happy path + common edges. POC works → design properly → build with tests. Never ship the POC.
|
|
227
|
-
|
|
228
|
-
**Build incrementally.** Break work into small independent modules. One piece at a time, each must work on its own before integrating.
|
|
229
|
-
|
|
230
|
-
**Dependency hierarchy — follow strictly:** vanilla language → standard library → external (only when stdlib can't do it in <100 lines). External deps must be maintained, lightweight, and widely adopted. Exception: always use vetted libraries for security-critical code (crypto, auth, sanitization).
|
|
231
|
-
|
|
232
|
-
**Lightweight over complex.** Fewer moving parts, fewer deps, less config. Express over NestJS, Flask over Django, unless the project genuinely needs the framework. Simple > clever. Readable > elegant.
|
|
233
|
-
|
|
234
|
-
**Open-source only.** No vendor lock-in. Every line of code must have a purpose — no speculative code, no premature abstractions.
|
|
235
|
-
|
|
236
|
-
For full development and testing standards, see `.claude/memory/AGENT_RULES.md`.
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
## AI Agent Instructions
|
|
242
|
-
|
|
243
|
-
When working with this user:
|
|
244
|
-
1. **Always verify** you understand the requirements before proceeding
|
|
245
|
-
2. **Provide step-by-step** instructions with clear explanations
|
|
246
|
-
3. **Include ready-to-run** scripts and commands
|
|
247
|
-
4. **Explain the "why"** behind technical recommendations
|
|
248
|
-
5. **Flag potential issues** before they become problems
|
|
249
|
-
6. **Suggest simpler alternatives** when appropriate
|
|
250
|
-
7. **Never modify** authentication or database schema without explicit permission
|
|
251
|
-
8. **Always identify** which files will be affected by changes
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"permissions": {
|
|
3
|
-
"allow": [
|
|
4
|
-
"Bash(wc:*)",
|
|
5
|
-
"Bash(flatpak list)",
|
|
6
|
-
"WebSearch",
|
|
7
|
-
"Bash(tail:*)",
|
|
8
|
-
"Bash(grep:*)",
|
|
9
|
-
"Bash(rpm -qa)",
|
|
10
|
-
"Bash(node:*)",
|
|
11
|
-
"Bash(cp:*)",
|
|
12
|
-
"Bash(ls:*)",
|
|
13
|
-
"Bash(head:*)",
|
|
14
|
-
"Bash(which kwalletcli:*)",
|
|
15
|
-
"Bash(kwallet-query:*)",
|
|
16
|
-
"WebFetch(domain:github.com)",
|
|
17
|
-
"WebFetch(domain:raw.githubusercontent.com)",
|
|
18
|
-
"Bash(npm view:*)",
|
|
19
|
-
"Bash(git add:*)",
|
|
20
|
-
"Bash(git commit:*)",
|
|
21
|
-
"Bash(npm whoami:*)",
|
|
22
|
-
"Bash(npm pack:*)",
|
|
23
|
-
"Bash(npm publish:*)",
|
|
24
|
-
"Skill(git-commit)",
|
|
25
|
-
"Bash(python3:*)",
|
|
26
|
-
"Bash(printf '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{}}\\\\n{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\",\"params\":{}}\\\\n' | timeout 5 node /home/hamr/PycharmProjects/barebrowse/mcp-server.js 2>/dev/null)",
|
|
27
|
-
"Bash(chmod +x:*)"
|
|
28
|
-
]
|
|
29
|
-
}
|
|
30
|
-
}
|