| name | pinchtab-dev |
| description | Develop and contribute to the PinchTab project. Use when working on PinchTab source code, adding features, fixing bugs, running tests, or preparing PRs. Triggers on "work on pinchtab", "pinchtab development", "contribute to pinchtab", "fix pinchtab bug", "add pinchtab feature". |
PinchTab Development
PinchTab is a browser control server for AI agents — Small Go binary with HTTP API.
Project Location
cd ~/dev/pinchtab
Dev Commands
All development commands run via ./dev:
| Command | Description |
|---|
./dev build | Build the application |
./dev dev | Build & run |
./dev dashboard | Hot-reload dashboard development (Vite + Go) |
./dev run | Run the application |
./dev check | All checks (Go + Dashboard + Plugin) |
./dev check go | Go checks only |
./dev check dashboard | Dashboard checks only |
./dev test unit | Go unit tests |
./dev test dashboard | Dashboard unit tests |
./dev e2e basic | Basic suite (api + cli + infra) |
./dev e2e extended | Extended suite (all extended) |
./dev e2e smoke | Smoke suite |
./dev e2e smoke-docker | Host Docker smoke checks only |
./dev e2e test "<name>" | Run a single E2E test by start_test name |
./dev all | check + test + e2e (pre-push gate) |
./dev binaries | Build the full release binary matrix into dist/ |
./dev doctor | Setup dev environment |
Architecture
cmd/pinchtab/ CLI entry point
internal/
bridge/ Chrome CDP communication
handlers/ HTTP API handlers
server/ HTTP server
dashboard/ Embedded React dashboard
config/ Configuration
assets/ Embedded assets (stealth.js)
dashboard/ React dashboard source (Vite + TypeScript)
tests/e2e/ E2E test suites
Workflow: New Feature or Bug Fix
-
Create branch from main:
git checkout main && git pull
git checkout -b feat/my-feature
-
Make changes — follow code patterns in existing files
-
Run checks locally:
./dev all
./dev check
./dev test unit
./dev e2e basic
-
Commit with conventional commits:
feat: new feature
fix: bug fix
refactor: code change without behavior change
test: adding tests
docs: documentation
chore: maintenance
-
Push and create PR
Definition of Done (PR Checklist)
Required — Code Quality
- Error handling explicit — all errors wrapped with
%w, no silent failures
- No regressions — verify stealth, token efficiency, session persistence
- SOLID principles — functions do one thing, testable
- No redundant comments — explain why, not what
Required — Testing
- New/changed functionality has tests
- Docker E2E tests pass locally:
./dev e2e basic (or ./dev all for the full chain)
- If npm wrapper touched:
npm pack and npm install work
Required — Documentation
- README.md updated if user-facing changes
- /docs/ updated if API/architecture changed
Required — Review
- PR description explains what + why
- Commits are atomic with good messages
Key Files
| File | Purpose |
|---|
internal/assets/stealth.js | Bot detection evasion (light/medium/full levels) |
internal/bridge/bridge.go | Chrome CDP bridge |
internal/handlers/*.go | HTTP API endpoints |
dashboard/src/ | React dashboard source |
tests/e2e/scenarios-api/ | API E2E tests |
tests/e2e/scenarios-cli/ | CLI E2E tests |
Testing
Unit Tests
./dev test unit
go test ./internal/handlers
E2E Tests (requires Docker)
./dev e2e basic
./dev e2e api
./dev e2e cli
./dev e2e infra
./dev e2e api-extended
./dev e2e cli-extended
./dev e2e infra-extended
./dev e2e extended
./dev e2e smoke-docker
./dev e2e api clipboard
./dev e2e api-extended "clipboard|console"
./dev e2e cli browser
./dev e2e test "humanClick: click input by ref"
./dev e2e test "scroll (down)"
./dev e2e test "low-level mouse"
The scenario filter is a substring matched against scenario filenames. Requires Docker daemon running.
Single-test mode (dev e2e test "<name>")
Use this when iterating on one specific E2E failure. The runner:
- Greps
tests/e2e/scenarios/**/*.sh for start_test "...<name substring>...".
- Auto-picks the suite (
api/cli/infra/plugin) and -extended variant from the matching scenario file's path.
- Builds fresh images (
compose ... up --build) and runs only the matching start_test...end_test block — the scenario preamble (helper sourcing, FIXTURES_URL, etc.) is preserved, every other test in the file is skipped.
Notes:
- The substring is literal (fgrep), so colons/parens/quotes in test names work without escaping.
- If multiple tests match, the runner uses the first and prints the others — pass a longer/more-specific substring to disambiguate.
- Logs stream to the terminal by default (unlike full suites which hide logs); helpful for debugging.
- Implemented by
scripts/dev-e2e.sh + E2E_TEST_FILTER plumbing through scripts/e2e.sh and tests/e2e/run.sh.
Dashboard Tests
./dev test dashboard
cd dashboard && npm test
Dashboard Development
Setup
Start hot-reload development:
./dev dashboard
This runs:
- Backend on
:9867
- Vite dev server on
:5173 with hot-reload
- Dashboard at
http://localhost:5173/dashboard/
Development Workflow (Use PinchTab to Develop PinchTab)
Do not assume changes worked. Use pinchtab itself to verify changes visually:
-
Start dev mode:
./dev dashboard
-
Make changes to files in dashboard/src/
-
Verify with pinchtab — use the pinchtab skill to inspect the dashboard:
curl -X POST http://localhost:9867/navigate \
-d '{"url":"http://localhost:5173/dashboard/settings"}'
curl -X POST http://localhost:9867/screenshot \
-d '{"path":"/tmp/dashboard-check.png"}'
curl -s http://localhost:9867/snapshot | jq .
-
Provide evidence — when reporting changes, include:
- Link to the page:
http://localhost:5173/dashboard/{page}
- Screenshot of the result
- Relevant snapshot data if inspecting specific elements
Example: Verifying a Settings Page Change
curl -X POST http://localhost:9867/navigate \
-d '{"url":"http://localhost:5173/dashboard/settings"}'
curl -X POST http://localhost:9867/screenshot \
-d '{"path":"./dashboard-settings.png","fullPage":true}'
curl -X POST http://localhost:9867/find \
-d '{"selector":"[data-testid=stealth-level]"}'
Key Dashboard Pages
| Page | URL | Purpose |
|---|
| Home | /dashboard/ | Instance overview |
| Settings | /dashboard/settings | Configuration |
| Profiles | /dashboard/profiles | Browser profiles |
| Tabs | /dashboard/tabs | Active tabs |
Dashboard Tech Stack
- React 19 + TypeScript
- Vite (build/dev)
- Tailwind CSS
- Zustand (state)
- Vitest (tests)
Stealth Module
The stealth module (internal/assets/stealth.js) has three levels:
| Level | Features | Trade-offs |
|---|
light | webdriver, CDP markers, plugins, hardware | None — safe |
medium | + userAgentData, chrome.runtime.connect, csi/loadTimes | May affect error monitoring |
full | + WebGL/canvas noise, WebRTC relay | May break WebRTC, canvas apps |
Configure in ~/.pinchtab/config.json:
{
"instanceDefaults": {
"stealthLevel": "medium"
}
}
Common Tasks
Add new API endpoint
- Create handler in
internal/handlers/
- Register route in
internal/server/routes.go
- Add tests in same package
- Add E2E test in
tests/e2e/scenarios-api/
Modify stealth behavior
- Edit
internal/assets/stealth.js
- Run
./dev build (embeds via go:embed)
- Test with
./dev e2e api-fast (includes stealth tests)
Update dashboard
- Run
./dev dashboard for hot-reload
- Edit files in
dashboard/src/
- Run
./dev check dashboard before commit