This is the canonical contributor and development guide for PinchTab.
| Requirement | Version | Purpose |
|---|---|---|
| Go | 1.25+ | Build language |
| golangci-lint | Latest | Linting (required for pre-commit hooks) |
| Chrome/Chromium | Latest | Browser automation |
| macOS, Linux, or WSL2 | Current | OS support |
For dashboard work, use Bun 1.2+.
Older Bun releases fail on the checked-in dashboard/bun.lock during clean installs with --frozen-lockfile.
- macOS: Homebrew for package management
- Linux: apt (Debian/Ubuntu) or yum (RHEL/CentOS)
- WSL2: Full Linux environment (not WSL1)
Fastest way to get started:
# 1. Clone
git clone https://github.com/pinchtab/pinchtab.git
cd pinchtab
# 2. Run doctor (verifies environment, prompts before installing anything)
./dev doctor
# 3. Build and run
go build ./cmd/pinchtab
./pinchtabExample output:
🦀 Pinchtab Doctor
Verifying and setting up development environment...
Go Backend
✓ Go 1.26.0
✗ golangci-lint
Required for pre-commit hooks and CI.
Install golangci-lint via brew? [y/N] y
✓ golangci-lint installed
✓ Git hooks
✓ Go dependencies
Dashboard (React/TypeScript)
✓ Node.js 22.15.1
· Bun not found
Optional — used for fast dashboard builds.
Install Bun? [y/N] n
curl -fsSL https://bun.sh/install | bash
Summary
· 1 warning(s)
The doctor asks for confirmation before installing anything. If you decline, it shows the manual install command instead.
macOS (Homebrew):
brew install go
go version # Verify: go version go1.25.0Linux (Ubuntu/Debian):
sudo apt update
sudo apt install -y golang-go git build-essential
go versionLinux (RHEL/CentOS):
sudo yum install -y golang git
go versionOr download from: https://go.dev/dl/
Required for pre-commit hooks:
macOS/Linux:
brew install golangci-lintOr via Go:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latestVerify:
golangci-lint --versionRecommended for the cleaner local unit test output used by ./dev test unit:
go install gotest.tools/gotestsum@latestmacOS (Homebrew):
brew install chromiumLinux (Ubuntu/Debian):
sudo apt install -y chromium-browserLinux (RHEL/CentOS):
sudo yum install -y chromiumAfter cloning, run doctor to verify and set up your environment:
git clone https://github.com/pinchtab/pinchtab.git
cd pinchtab
./dev doctorDoctor checks your environment and asks before installing anything:
- Go 1.25+ and golangci-lint (offers
brew installorgo install) - Git hooks (copies pre-commit hook)
- Go dependencies (
go mod download) - Node.js, Bun, and dashboard deps (optional, for dashboard development)
Run ./dev doctor anytime to verify or fix your environment.
go build -o pinchtab ./cmd/pinchtabWhat it does:
- Compiles Go source code
- Produces binary:
./pinchtab - Takes ~30-60 seconds
Note: This builds the Go server only. The dashboard will show a "not built" placeholder. To include the full React dashboard, use
./dev buildinstead — it builds the dashboard, compiles Go, and runs the server in one step. Or run./scripts/build-dashboard.shbeforego build.
Verify:
ls -la pinchtab
./pinchtab --version./pinchtabExpected output:
🦀 PINCH! PINCH! port=9867
auth disabled (set PINCHTAB_TOKEN to enable)
BRIDGE_HEADLESS=false ./pinchtabOpens Chrome in the foreground.
nohup ./pinchtab > pinchtab.log 2>&1 &
tail -f pinchtab.log # Watch logscurl http://localhost:9867/health./pinchtab quick https://pinchtab.com
./pinchtab nav https://pinchtab.com
./pinchtab snapgo test ./... # Unit tests only
go test ./... -v # Verbose
go test ./... -v -coverprofile=coverage.out
go tool cover -html=coverage.out # View coverage
./dev e2e # Run the default E2E release suite
./dev e2e docker # Build the local image and run Docker smoke
./dev e2e pr # Run API fast + CLI fast
./dev e2e api-full # Run the multi-instance API suite
./dev e2e cli-full # Run the single-instance CLI full suiteAll dev scripts are accessible through ./dev:
./dev # Interactive picker (uses gum if installed, numbered fallback)
./dev check # Run a command directly
./dev test unit # Subcommands supported
./dev --help # List all commandsAvailable commands:
| Command | Description |
|---|---|
check |
All checks (Go + Dashboard) |
check go |
Go checks only |
check dashboard |
Dashboard checks only |
check security |
Gosec security scan |
check docs |
Validate docs JSON |
format dashboard |
Run Prettier on dashboard sources |
test |
Run all tests |
test unit |
Unit tests only |
test dashboard |
Dashboard tests only |
e2e |
Run the default E2E release suite (api-full + cli-full) |
e2e docker |
Build the local image and run the Docker smoke test |
e2e pr |
Run the PR E2E suite (api-fast + cli-fast) |
e2e api-fast |
Run the fast API E2E suite on the single-instance stack |
e2e cli-fast |
Run the fast CLI E2E suite on the single-instance stack |
e2e api-full |
Run the full API E2E suite on the multi-instance stack |
e2e cli-full |
Run the full CLI E2E suite on the single-instance stack |
e2e release |
Run the release E2E meta-suite |
build |
Build the application |
dev |
Build and run the application |
run |
Run the application |
binary |
Build the local release-style binary |
doctor |
Setup dev environment |
For the fancy interactive picker, install gum: brew install gum
Tip: Add this to ~/.zshrc to use dev without ./:
dev() { if [ -x "./dev" ]; then ./dev "$@"; else echo "dev not found in current directory"; return 1; fi }./dev check # Full non-test checks (recommended)
./dev format dashboard # Fix dashboard formatting
gofmt -w . # Format code
golangci-lint run # Lint
./dev doctor # Verify environmentGit hooks are installed by ./dev doctor (or ./scripts/install-hooks.sh). They run on every commit:
gofmt— Format checkgolangci-lint— Lintingprettier— Dashboard formatting
To manually reinstall hooks:
./scripts/install-hooks.sh# 1. Setup (first time)
./dev doctor
# 2. Create feature branch
git checkout -b feat/my-feature
# 3. Make changes
# ... edit files ...
# 4. Run checks before pushing
./dev check
# 5. Commit (hooks run automatically)
git commit -m "feat: description"
# 6. Push
git push origin feat/my-featureNote: Git hooks will automatically format and lint your code on commit. If checks fail, the commit is blocked.
Workflows follow a naming convention:
| Prefix | Purpose | Example |
|---|---|---|
ci-* |
Automatic checks on PR/push | ci-go.yml → CI / Go |
reusable-* |
Building blocks (workflow_call only) |
reusable-e2e.yml → Reusable / E2E |
release-* |
Release pipeline | release.yml → Release |
Run automatically on pull requests and/or push to main:
| Workflow | Triggers | What it checks |
|---|---|---|
| CI / Go | PR + push | gofmt, vet, build, tests, coverage, lint, security |
| CI / Dashboard | PR + push (dashboard paths) | TypeScript, ESLint, Prettier, tests, build |
| CI / Docs | PR + push (docs paths) | docs.json reference validation |
| CI / npm | PR (npm paths) + tag push | npm package verification |
| CI / E2E | PR (fast suites) + manual (full suites) | Docker-based end-to-end tests |
| CI / Branch Naming | PR | Branch name convention enforcement |
| Workflow | Trigger | What it does |
|---|---|---|
| Release | Manual | Runs all checks + E2E → manual approval gate → creates tag → publishes binaries, npm, Docker, and skill |
| Release / Manual Publish | Manual | Publishes an existing tag as a recovery path |
In Release, E2E and Docker smoke failures are non-blocking — they surface in the approval summary so you can decide whether to proceed. Core checks (Go, Dashboard, Docs, npm, publish dry-run) must pass for the approval gate to appear.
go build -o ~/go/bin/pinchtab ./cmd/pinchtabThen use anywhere:
pinchtab help
pinchtab --versionnpm install -g pinchtab
pinchtab --version- GitHub Repository: https://github.com/pinchtab/pinchtab
- Go Documentation: https://golang.org/doc/
- Chrome DevTools Protocol: https://chromedevtools.github.io/devtools-protocol/
- Chromedp Library: https://github.com/chromedp/chromedp
First step: Run doctor to verify your setup:
./dev doctorThis will tell you exactly what's missing or misconfigured.
"Go version too old"
- Install Go 1.25+ from https://go.dev/dl/
- Verify:
go version
"golangci-lint: command not found"
- Install:
brew install golangci-lint - Or:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
"Git hooks not running on commit"
- Run:
./scripts/install-hooks.sh - Or:
./dev doctor(prompts to install)
"Chrome not found"
- Install Chromium:
brew install chromium(macOS) - Or:
sudo apt install chromium-browser(Linux)
"Port 9867 already in use"
- Check:
lsof -i :9867 - Stop other instance or use different port:
BRIDGE_PORT=9868 ./pinchtab
Build fails
- Verify dependencies:
go mod download - Clean cache:
go clean -cache - Rebuild:
go build ./cmd/pinchtab
Issues? Check:
- Run
./dev doctorfirst - All dependencies installed and correct versions?
- Port 9867 available?
- Check logs:
tail -f pinchtab.log
See docs/ for guides and examples.
