βββββββ βββββββ βββ ββββββββββ ββββββββββ ββββββ βββββββ
ββββββββββββββββ ββββββββββββββ βββββββββββββββββββββββββββ
βββββββββββββββββ ββββββ βββββββββββββββββββββββββββ βββ
βββββββ ββββββββββββββββ βββββββββββββββ βββββββββββ βββ
βββ ββββββ βββββββββββββββββ ββββββ βββ βββββββββββ
βββ ββββββ βββββ ββββββββββ ββββββ βββ ββββββββββ
Your Sovereign Scratchpad β where Humans and AI Lobsters collaborate to protect ideas.
Unfurl the Scroll π
PinchPad is a privacy-first, self-hostable note-taking app designed for the Human-Agent ecosystem. It protects your notes with client-side encryption while allowing delegated, granular access to autonomous agents. No passwords, no accounts, no servers watching β just cryptographic keys and sovereign data.
- π ClawKeysΒ©β’ β login with a decentralized identity key instead of passwords. Your
hu-key is your passport. - π ShellCryptionΒ©β’ β zero-knowledge AES-256-GCM encryption for all notes at rest. Only you can decrypt your thoughts.
- π¦ LobsterKeysΒ©β’ β issue granular, revocable API keys to AI agents. Let your Lobsters scuttle the reef securely.
- π€ Gemini AI Integration β native agent notepad with Google Gemini. Ask questions, get answers, save insights.
- ποΈ SQLite Bedrock β a fast, reliable, zero-dependency backend with WAL mode and cascade-delete integrity.
- π MoltTheme β View Transition-based theme engine. Watching the world shift colors.
graph TD
subgraph Client ["π Browser"]
UI[React / Tailwind UI]
Auth["Auth Module<br/>SetupWizard + LoginForm"]
Provider["DashboardContext<br/>useNotes() hook"]
REST[RestAdapter]
Theme[MoltTheme<br/>View Transition]
end
subgraph Server ["π₯οΈ server.ts (Express)"]
API["REST API<br/>Port 8383 dev<br/>Port 8282 prod"]
DB[(SQLite<br/>WAL Mode)]
end
UI --> Auth
UI --> Theme
UI --> Provider
Provider --> REST
REST -->|"fetch + Bearer token"| API
API --> DB
- Node.js v22+
- npm v10+
- Docker & Docker Compose (for containerized deployment)
Expand npm instructions
Install dependencies first:
npm installDevelopment Commands (The Coral Nursery):
- Start Frontend + Backend:
npm run scuttle:dev-start(Frontend :8282, Backend :8383 w/ HMR) - Stop All:
npm run scuttle:dev-stop - Reset DB:
npm run scuttle:reset-dev(Scuttles dev reef)
Production Commands (The Great Scuttle):
- Build & Start:
npm run scuttle:prod-start(API + Frontend on :8282) - Stop All:
npm run scuttle:prod-stop - Reset DB:
npm run scuttle:reset(DANGER: Deletes prod reef)
Utility Scripts:
- Frontend Only:
npm run dev(Vite :8282 with HMR) - Backend Only:
npm run dev:server(Express :8383 with watch) - Build Bundle:
npm run build - Preview Build:
npm run preview
Expand Docker instructions
Environment Variables:
# Default (edit in compose files if needed)
PORT=8282 # Server listen port (single container)
NODE_ENV=production # production or development
CORS_ORIGIN=http://yourdomain.com # restrict CORS origin, or leave unset for open LAN
GEMINI_API_KEY=your-key-here # For AI agent integrationOption A: Production (Pull from GHCR) β Use this for a stable, sovereign deployment. It pulls the latest pre-built image from the GitHub Container Registry.
docker compose up -dOption B: Development & Testing (Build Locally) π οΈ Use this if you are modifying the source code and want to test changes immediately.
docker compose -f docker-compose.dev.yml up -d --buildMonitoring & Maintenance:
- View Logs:
docker compose logs -f - Stop Stack:
docker compose down - Healthcheck:
curl http://localhost:8282/api/health
[!IMPORTANT] Data Sovereignty & Persistence: All notes and agent identities are stored in a local bind mount on your host system for maximum visibility and ease of backup.
- Path:
./data/clawstack.dbYou can directly copy or backup this file. If it doesn't exist, Docker will create it when the container starts.
PinchPad uses a prefix-based identity token system β no passwords, no usernames stored on a server. Your key file is your identity.
| Prefix | Type | Length | Usage |
|---|---|---|---|
hu- |
Human Key | 64 chars | Your personal identity. Hashed SHA-256, stored securely. |
lb- |
Lobster/Agent Key | 64 chars | For your AI agents. Granular permissions (canRead, canWrite, canDelete, canEdit). |
api- |
Session Token | 32 chars | Short-lived REST API bearer. 24h TTL. Issued via POST /api/auth/token. |
Caution
Your hu- key is the only way to access your PinchPad. Keep it safe. If you lose it, it cannot be recovered. Back it up somewhere secure.
All endpoints except
/api/healthand/api/auth/registerrequireAuthorization: Bearer <api-token>.
View full API endpoint table
| Method | Endpoint | Auth | Permission | Description |
|---|---|---|---|---|
POST |
/api/auth/register |
No | - | Create new identity key |
POST |
/api/auth/token |
No | - | Issue api- token from hu- or lb- key |
GET |
/api/auth/verify |
Yes | - | Verify current Bearer token |
POST |
/api/auth/logout |
Yes | - | Revoke current session token |
GET |
/api/notes |
Yes | canRead | List all notes |
POST |
/api/notes |
Yes | canWrite | Create note |
PUT |
/api/notes/:id |
Yes | canEdit | Update note |
DELETE |
/api/notes/:id |
Yes | canDelete | Delete note |
GET |
/api/agents |
Yes | human-only | List agent keys |
POST |
/api/agents |
Yes | human-only | Create agent key |
PUT |
/api/agents/:id/revoke |
Yes | human-only | Revoke agent key |
GET |
/api/health |
No | - | Health check |
See BLUEPRINT.md for the full ASCII construction diagram.
PinchPad/
βββ src/
β βββ server/ # Backend (Express + SQLite)
β β βββ db.ts # Schema & migrations
β β βββ middleware/ # Auth, permission gates
β β βββ routes/ # API endpoints
β β βββ utils/ # Crypto, token helpers
β βββ components/ # Feature-scoped UI
β β βββ auth/ # LoginForm + SetupWizard
β β βββ dashboard/ # Main note grid + sidebar
β β βββ notes/ # Note editor + viewer
β β βββ ui/ # shadcn/ui base components
β βββ services/ # Business logic
β β βββ authService.ts # Key generation, hashing
β β βββ noteService.ts # Note CRUD
β β βββ agentService.ts # Agent key management
β β βββ types/ # Shared TypeScript interfaces
β βββ lib/ # Utilities
β βββ crypto.ts # SHA-256, AES-256-GCM, UUID
β βββ utils.ts # Helpers
βββ test/ # Test suite (140 tests, Vitest)
β βββ server/ # Backend integration tests
β βββ services/ # Service unit tests
β βββ lib/ # Utility tests
β βββ shared/ # Test fixtures + setup
βββ Dockerfile # Single-container image
βββ docker-compose.yml # Prod: pull from GHCR
βββ docker-compose.dev.yml # Dev: build locally
βββ server.ts # Express entry point
βββ vite.config.ts # Bundler config
βββ tailwind.config.js # Design tokens
βββ package.json # Dependencies & scripts
| Script | Description |
|---|---|
npm run scuttle:dev-start |
π¦ Start both Frontend + Backend concurrently (dev mode) |
npm run scuttle:dev-stop |
Kill the frontend and backend dev servers |
npm run scuttle:prod-start |
Build + start production server (:8282) |
npm run scuttle:prod-stop |
Kill the production server |
npm run scuttle:reset |
Scuttle the production database (DANGER) |
npm run scuttle:reset-dev |
Scuttle the development database |
npm run dev |
Vite frontend dev server (:8282 with HMR) |
npm run dev:server |
Express backend dev server (:8383 with watch) |
npm run build |
Vite production build β dist/ |
npm run preview |
Serve the production dist/ locally |
npm run lint |
TypeScript type-check (tsc --noEmit) |
npm test |
Run all 140 tests (Vitest) |
npm run test:watch |
Watch mode for tests |
npm run test:coverage |
Coverage report (threshold: middleware 100%, routes >75%) |
PinchPad supports full SQLite database encryption at rest using SQLCipher (AES-256-CBC). This protects the entire database file on disk, preventing unauthorized access to users, tokens, notes, and agent keys even if the host filesystem is compromised.
Generate a 256-bit encryption key:
openssl rand -base64 32
# β K7fGh2mNpQrXvYzA1bCdEfJkLnOpStUw+Xy9012/3==For npm development:
Add the key to .env.local:
DB_ENCRYPTION_KEY=K7fGh2mNpQrXvYzA1bCdEfJkLnOpStUw+Xy9012/3==
npm run scuttle:dev-startFor Docker deployment:
Uncomment and set the key in docker-compose.yml or docker-compose.dev.yml:
environment:
- DB_ENCRYPTION_KEY=K7fGh2mNpQrXvYzA1bCdEfJkLnOpStUw+Xy9012/3==
docker compose up -d- Key is required in production. If
DB_ENCRYPTION_KEYis not set, the database is stored in plaintext. The app will log a warning on startup. - First-run migration: If you have an existing unencrypted database and set the key, PinchPad will automatically encrypt it on the next boot.
- Key rotation: There is no built-in key rotation mechanism. If you need to change the key, export the plaintext database, drop the old encrypted file, and re-import with the new key.
See CONTRIBUTING.md for the full guide.
See SECURITY.md for vulnerability reporting and key security practices.
_..._
.' '. HATCH YOUR PINCHPAD.
/ _ _ \ PROTECT YOUR IDEAS.
| (q) (p) | PUNCH THE CLOUD.
(_ Y _)
'.__W__.'
Maintained by CrustAgentΒ©β’