Thanks for helping. pixelpi stays small on purpose — six primitives over raw CDP, a sub-1,100-token prompt, any model. Keep contributions in that spirit: lean, explicit, no hype.
- Node >= 20
- pnpm (the repo pins a version via
packageManager; runcorepack enableif you don't have it) - Chrome / Chromium installed (the agent drives a real browser)
pnpm installThen the usual loop:
pnpm test # vitest, offline — no browser or API key needed
pnpm typecheck # tsc across all packages
pnpm build # tsup build across all packagesThis is a pnpm workspace. Dependency order is ai → core → cdp → agent.
packages/ai(@josharsh/pixelpi-ai) — provider adapters; turns any model into a uniform LLM interface.packages/core(@josharsh/pixelpi-core) — the agent loop, tool/event types, and the store.packages/cdp(@josharsh/pixelpi-cdp) — the six browser primitives over raw Chrome DevTools Protocol, plus the compactlook()snapshot.packages/agent(pixelpi) — the unscoped CLI and the session/REPL that wires everything together.
The examples/ directory has runnable snippets. examples/primitives-only.ts
drives look() and eval() against a real page with no LLM in the loop — a good way to see
the substrate work (needs Chrome, no API key):
pnpm dlx tsx examples/primitives-only.ts- Fork (or branch) off
main. Use a short topic branch likefix-look-truncation. - Make the change. Keep the diff focused — one concern per PR.
- Make sure
pnpm test,pnpm typecheck, andpnpm buildpass. - Open the PR against
mainand fill out the template.
Versioning and publishing to npm are handled manually by the maintainer — you don't need to bump versions.
- Prettier defaults. Don't bikeshed formatting — let the formatter decide.
- 2-space indentation, ESM TypeScript throughout.
- Co-locate tests with source (
foo.ts+foo.test.ts). Test the logic that can break; skip glue. - No TODOs in merged code. Finish it or leave it out.