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 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
- # barebrowse
2
-
3
- **URL in, agent-ready snapshot out.** Zero dependencies. Uses your own browser.
1
+ ```
2
+ ~~~~~~~~~~~~~~~~~~~~
3
+ ~~~ .---------. ~~~
4
+ ~~~ | · clear | ~~~
5
+ ~~~ | · focus | ~~~
6
+ ~~~ '---------' ~~~
7
+ ~~~~~~~~~~~~~~~~~~~~
8
+
9
+ barebrowse
10
+ ```
4
11
 
5
- barebrowse gives autonomous agents eyes and hands on the web. It launches your installed Chromium, navigates to any page, and returns a pruned ARIA snapshot — a compact, semantic representation of what's on screen. The agent reads the snapshot, picks an element by ref, acts, and reads the next snapshot. Observe, think, act.
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
- No Playwright. No bundled browser. No 200MB download. Just CDP over a WebSocket to whatever Chromium you already have.
15
+ ---
8
16
 
9
- ## The idea
17
+ ## What this is
10
18
 
11
- LLMs don't need DOM. They need to know what's on the page and what they can interact with. That's exactly what the browser's accessibility tree provides every heading, button, link, input, and landmark, structured semantically.
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
- But raw ARIA trees are noisy. A typical page produces 50-100KB of ARIA data. Most of it is decorative wrappers, hidden elements, and structural noise. barebrowse includes a 9-step pruning pipeline (ported from [mcprune](https://github.com/nickvdyck/mcprune)) that strips 47-95% of tokens while keeping every interactive element and meaningful label. A page that costs $0.15 in tokens raw costs $0.02-0.08 pruned.
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
- The snapshot format uses `[ref=N]` markers on interactive elements. The agent says "click ref 8" and barebrowse scrolls the element into view, calculates coordinates, and dispatches real mouse events. No CSS selectors. No XPath. Just semantic refs from the ARIA tree.
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 (Chrome, Chromium, Brave, Edge, Vivaldi).
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. As a library (framework mode)
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 Claude Desktop, Cursor, and Claude Code, and writes the MCP config for you. No manual JSON editing.
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
- This exposes 7 tools: `browse`, `goto`, `snapshot`, `click`, `type`, `press`, `scroll`. The LLM calls `goto` to navigate, `snapshot` to observe, and action tools to interact. Action tools return `'ok'` -- the LLM calls `snapshot` explicitly to see what changed.
44
+ ### 2. Framework -- for agentic automation
112
45
 
113
- **Same package, two entry points.** `npm install barebrowse` gives you both the library (`import { browse } from 'barebrowse'`) and the MCP server (`npx barebrowse mcp`). Pick whichever fits your setup.
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
- ## Three modes
48
+ For code examples, API reference, and wiring instructions, see **[barebrowse.context.md](barebrowse.context.md)** -- the full integration guide.
116
49
 
117
- | Mode | Flag | What happens | Use for |
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
- Headed mode requires your browser running with `--remote-debugging-port=9222`.
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
- You don't need to write code for any of this:
128
-
129
- - **Cookie consent dialogs** ARIA scan + jsClick across 7 languages (EN, NL, DE, FR, ES, IT, PT). Tested on 16+ sites.
130
- - **Permission prompts** — notifications, geolocation, camera, mic all auto-denied via CDP
131
- - **Login walls** cookies extracted from your Firefox or Chromium profile, injected via CDP
132
- - **Off-screen elements** scrolled into view before every click
133
- - **Bot detection** stealth patches in headless (navigator.webdriver, plugins, chrome object)
134
- - **Profile locking** unique temp dir per headless instance
135
- - **ARIA noise** 9-step pruning pipeline strips decorative wrappers, hidden nodes, structural noise
136
-
137
- ## connect() API reference
138
-
139
- | Method | Description |
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
- | `goto(url)` | Navigate + wait for load + dismiss consent |
142
- | `snapshot()` | Pruned ARIA tree with `[ref=N]` markers |
143
- | `click(ref)` | Scroll into view + mouse click at element center |
144
- | `type(ref, text, opts?)` | Focus + insert text. `{ clear: true }` replaces existing. |
145
- | `press(key)` | Special key: Enter, Tab, Escape, Backspace, Delete, arrows, Space |
146
- | `scroll(deltaY)` | Mouse wheel. Positive = down, negative = up. |
147
- | `hover(ref)` | Move mouse to element center |
148
- | `select(ref, value)` | Set `<select>` value or click custom dropdown option |
149
- | `screenshot(opts?)` | Returns base64 PNG/JPEG/WebP |
150
- | `waitForNavigation()` | Wait for page load (SPA-aware) |
151
- | `waitForNetworkIdle()` | Wait until no pending requests for 500ms |
152
- | `injectCookies(url)` | Extract + inject cookies from your browser |
153
- | `cdp` | Raw CDP session escape hatch |
154
- | `close()` | Clean up everything |
155
-
156
- ## bareagent integration
157
-
158
- barebrowse ships a tool adapter for [bareagent](https://github.com/nickvdyck/bareagent):
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
- `createBrowseTools(opts)` returns 9 tools: browse, goto, snapshot, click, type, press, scroll, select, screenshot. Action tools auto-return a fresh snapshot after each action so the LLM always sees the result.
120
+ ## Context file
181
121
 
182
- You can pass any `connect()` options to `createBrowseTools()` mode, port, cookies, consent.
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 -> chromium.js find/launch browser, permission-suppressing flags
188
- -> cdp.js WebSocket CDP client, flattened sessions
189
- -> stealth.js navigator.webdriver patches (headless only)
190
- -> Browser.setPermission suppress all prompts
191
- -> auth.js extract cookies from Firefox/Chromium -> inject via CDP
192
- -> Page.navigate go to URL, wait for load
193
- -> consent.js detect + dismiss cookie consent dialogs
194
- -> aria.js Accessibility.getFullAXTree -> nested tree
195
- -> prune.js 9-step pruning: wrappers, noise, landmarks
196
- -> interact.js click/type/scroll/hover/select via CDP Input domain
197
- -> snapshot agent-ready ARIA text with [ref=N] markers
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.0' },
152
+ serverInfo: { name: 'barebrowse', version: '0.2.2' },
153
153
  });
154
154
  }
155
155
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "barebrowse",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Authenticated web browsing for autonomous agents via CDP. URL in, pruned ARIA snapshot out.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -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
- }