
Pinta
- 1 repo stars
- Updated August 3, 2026
- kevzlou7979/pinta
Annotate your running app visually and turn UI changes into source edits.
About
pinta is a Claude Code skill in the AI & Agent Building category. Annotate your running app visually and turn UI changes into source edits.
- pinta
- AI & Agent Building
- AI-coding skill
Pinta by the numbers
- Data as of Aug 4, 2026 (Skillselion catalog sync)
/plugin marketplace add kevzlou7979/pinta/plugin install pinta@pintaAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| repo stars | ★ 1 |
|---|---|
| Last updated | August 3, 2026 |
| Repository | kevzlou7979/pinta ↗ |
What it does
Annotate your running app visually and turn UI changes into source edits.
README.md
Pinta
Annotate your running web app. Let an AI agent do the edits.
Circle a button. Point at a heading. Type "make this tonal". Pinta captures the annotation, snapshots the page, and hands it to your coding agent — Claude Code, Cursor, or any MCP-compatible tool — which edits the matching source files for you.
Status: V1. End-to-end pipeline is shipped: Chrome extension, companion server, full-page screenshot composite, Claude Code reference adapter, and MCP server for Cursor / Cline / Continue / Zed. See
spec/SPEC.mdfor the design and Roadmap for what's next.
Website · Chrome Web Store · npm · Releases
What's new
Recent additions on top of the original V1 pipeline:
Report module — daily / weekly / sprint summaries (v0.6.0). A built-in Report tab merges git + GitHub activity with Pinta sessions into Read-mode day cards across a day, week, 10-day sprint, or custom window — multi-project aware, with one-click Markdown export (per-day or whole-range). See
spec/SPEC.md§8 Phase 16.AuditFlow fixes in place (v0.6.0). "Fix with agent" no longer bounces to Annotate — each finding fixes the source in place with a per-row loader, fixes run concurrently, and the category ⋮ gains Fix All.
Module board actions + free-form notes (v0.6.0). Board modules gain header actions (e.g. the Tasks module's "End Day"), client-side card ops (add-to-Test-Pilot), and
featuredSectioncolumns; the Annotate composer accepts a free-form note task with no DOM target — the agent finds the code itself.Backup / restore + header redesign (v0.5.0). Export / import the AuditFlow catalog and a global
pinta-settings.json; a redesigned header with a ⋮ menu, version badge, and live connection status dot.AuditFlow — Lighthouse-style audits (v0.4.0). Five built-in audits (security, performance, accessibility, mobile, cross-browser) plus custom markdown-defined checks, each one click from Fix-with-agent. Results persist per project and re-run on demand. See
spec/SPEC.md§8 Phase 15.Chat module — global + Just Ask + per-row (post-v0.3.1). Single Settings toggle lights up an "ask the agent" surface in three places: a global FAB at the bottom-right corner of the side panel, an Annotate Just Ask checkbox in the submit footer (each annotation gets its own bubble + focused reply, in sequence), and a chat icon on every Test Pilot catalog row. Threads persist per surface; the global bubble accepts pasted images. New module mode:
inquiry(cross-cutting; sits alongsideper-submitandinteractive). Seespec/SPEC.md§8 Phase 14.Tester sheet export (.md + .docx) with offline import (post-v0.3.1). Test Pilot Export is now a 3-item menu: results MD (sign-off artifact with marks + per-row chat threads), tester sheet MD (steps embedded per row, Result blank), or tester sheet .docx (opens directly in Word — no
pandocstep). Standalone testers (no companion / no agent) can import the .md file via the empty-state picker and walk through it offline; their results export back to MD for the developer to re-import. Seespec/SPEC.md§8 Phase 13b.Test Pilot — interactive UAT module in its own side-panel tab (post-v0.3.1). Import a hand-written markdown test spec (or let the agent generate one from project context), get a tested catalog of sections + rows to step through manually. Each row can be marked Pass / Fail / Untested; clicking the ? asks the agent for step-by-step instructions, rendered with light markdown (inline
code, fenced blocks with syntax highlighting,> Note:callouts) and per-block copy-to-clipboard. A Detailed help steps setting in the module config toggles between short tester-friendly steps (default, fewer tokens) and deeper technical context (curl, payloads, env vars). Export the whole catalog as a markdown report with pass/fail/total tallies (pipe throughpandoc results.md -o results.pdffor PDF). Wire-protocol-wise this is a new interactive module surface:kind: "query"annotations carry the JSON-encoded request via a newmodule.query.submitWS message; the agent answers viamark_session_donewith a structured payload that the extension routes back into the Test Pilot tab. UAT specs live in.pinta/test-docs/and are wiped when the catalog is cleared (specs often carry real credentials). Seespec/SPEC.md§8 Phase 12.Built-in modules — agent-side integrations triggered per submit (v0.3.0). Pinta now ships with built-in modules that ride along on a session and hand the agent extra work after the source edits land. The first one is GitLab Issues: enable it once in Settings, tick Create GitLab issues in the footer before submitting, and the agent files one issue per annotation via the user's
glabCLI — auth comes fromglab auth login, no tokens stored or transmitted. Issue body embeds the full-page screenshot (uploaded to the GitLab project's uploads endpoint), the selector, source file, and the annotated page URL. Before filing, the agent prompts in chat for batch metadata — domain (client/server/shared→ labeldomain:<choice>), extra tags, assignees, orlaterto defer entirely. The screenshot is auto-checked + locked when the module is ticked so issues never go out without visual context. Module spec lives inextension/src/lib/modules.ts; new modules just add an entry there plus matching agent instructions inskill/pinta/SKILL.md§7.9.Per-page annotations across navigation (v0.3.0). Reviews of a multi-route flow no longer fall apart on the first link click. Each annotation now carries its own
url; the side panel filters the list to the page you're currently looking at and surfaces a chip "N on M other pages" with Open buttons to jump between routes. Pin badges repaint automatically after navigation / hard reload via anoverlay.readyhandshake — open the page again, the halos come back. One Send-to-agent submits the whole multi-page batch as a single session; the skill keys offannotation.urlso the GitLab module files each issue against the right page, and route-scoped grep narrows source-file lookup. Stays connected when the user briefly visits a URL the project doesn't claim — drafts no longer silently wipe..pintashare files — collaboration without source access (v0.2.0). Export any session as a single self-contained.pintafile (manifest with title / author / description / accent color, plus the session JSON with screenshots inlined). A teammate, designer, or QA tester can drop the file into their Pinta extension and it lands in History → Imported (N), opens in a read-only viewer, and surfaces three actions: Send to agent (submits to their connected companion as a new session — your machine isn't in the loop), Copy (the markdown for claude.ai web / ChatGPT), and Fork (clone into their own editable draft, in standalone mode). The page itself shows a metadata pill in the top-right and accent-colored numbered halos at each annotation's target so a recipient sees at a glance whose marks are whose. In v0.3.0 the Import button also accepts the markdown the Copy button produces (.md/.markdown) — lossy compared to.pinta(no screenshot bitmap, no drawing geometry) but enough to view, Send to agent, or Fork. When viewing an imported session, an emerald/amber pill ("3 of 4 located") shows how many selectors actually resolved on the current page so a recipient knows whether they're on the matching route. Seespec/SPEC.md§8 Phase 11.Standalone mode — the side panel works fully without a companion. Designed for QA / testers hitting deployed URLs (no Node, no project on disk, no companion to start). Annotations live in the browser (IndexedDB, keyed by URL origin); Copy to clipboard is the primary action and a Download ▾ dropdown ships either pure Markdown / Plain text, or a
.zipof MD + per-section composited PNGs (one PNG per scroll position so fixed sidebars don't duplicate vertically). Hand the zip to Claude / Cursor / any agent that reads files — it picks up the screenshots automatically.Numbered annotation badges — every annotation (selects + draws + pins) gets a brand-pink numbered badge on the page, in the side panel, and baked into the screenshot. Numbering is unified across kinds (chronological by creation), so "annotation 3" means the same thing everywhere.
Drawings get an actionable target — freehand / arrow / circle / rect / pin annotations now resolve the element under the drawing's anchor and attach selector + outerHTML + nearbyText. The MD output is meaningful even without a screenshot.
Inline editing popover — pick an element, get a 7-tab editor (Comment / Content / Font / Sizing / Spacing / Grid / CSS). Live DOM preview as you type; the page accumulates a visual preview of every queued edit and rolls back per-card on Remove. Pickers emit framework-neutral
cssChanges; the agent translates to whatever the project actually uses (Tailwind / styled-components / vanilla-extract / plain CSS — no hardcoded assumptions).Image attachments — paste (Cmd/Ctrl+V) or drag-drop images into the popover; they attach as
[image1],[image2]tokens in the comment. Agent reads each as visual context.Multi-project mode —
npx pinta-companion .in each project root picks the next free port, registers in~/.pinta/registry.json, and the side panel auto-routes the active tab to the right one via URL patterns. Strict per-project scoping: annotations don't bleed across projects.SSE push delivery —
/pintadefaults to--push(one long-lived Monitor stream, no polling noise in the agent transcript). Long-poll fallback via/pinta --polling.Per-annotation status — each card flips to ✓ as the agent finishes it, live via WS broadcast.
First-claim-wins — when multiple Claude Code terminals subscribe to the same project (Claude Dock), one of them claims each session and the others silently skip. No double-edits.
Auto-apply toggle — opt-in fast-iteration mode that skips the agent's "reply 'go'" confirmation step.
HMR auto-reload — when a session lands and HMR isn't detected on the active tab, the side panel reloads it for you. Toggleable.
Dark mode — popup, side panel, landing page.
Auto-detect tool icons — replaced flaky Unicode glyphs with inline SVG paths that follow
currentColorin light + dark.Hotkeys —
Alt+S(Select) /Alt+P(Pen) /Alt+X(Exit) /Esc(Cancel) /Cmd+Enter(submit in popover). Avoid Ctrl+Shift+R hard-reload collision.
See spec/SPEC.md §7–9 for the full status of each.
What V1 includes
| Capability | Status |
|---|---|
| Chrome MV3 extension (Svelte 5, side panel + popup, Shadow-DOM overlay) | shipped |
| Element selection — selector + outerHTML + computedStyles + nearbyText | shipped |
| Drawing canvas — arrow / rect / pen / pin (page-relative coords) | shipped |
| Inline editing popover — Comment / Content / Font / Sizing / Spacing / Grid / CSS | shipped |
| Live DOM preview while editing (mutate inline styles, snapshot for rollback) | shipped |
| Cumulative preview — kept on the page as you Add; rolled back per-card on Remove | shipped |
Image attachments — paste / drop into the popover with [image1] tokens |
shipped |
| Numbered pin badges on annotated elements (per-page session breadcrumb) | shipped |
| Full-page screenshot composite — opt-in, auto-on for drawings | shipped |
| Per-annotation status — spinner / ✓ / ! per card, live via WS broadcast | shipped |
| Session history view + applied summary persisted | shipped |
| Auto-reload after edits — HMR detection (Vite / Webpack / Next.js / Parcel) | shipped |
| Dark mode — popup, side panel, landing page (system + localStorage) | shipped |
| Auto-apply toggle — skip the agent's "reply 'go'" gate, opt-in | shipped |
| Live submit-footer status — pending pill while submitted/applying, "Annotate again" once every card has settled | shipped |
| Companion server — HTTP + WebSocket + SSE push + JSON store + per-project registry | shipped |
| Multi-project mode — auto port allocation, URL-pattern routing, strict per-project scoping | shipped |
| First-claim-wins session claim (multi-terminal coordination, e.g. Claude Dock) | shipped |
| Claude Code adapter — push handoff (default) + polling fallback | shipped |
| MCP server for Cursor / Cline / Continue / Zed / Windsurf | shipped |
| Aider adapter (poll script) | shipped |
| Copy-to-clipboard fallback for claude.ai web / ChatGPT / etc. | shipped |
Import / Export .pinta share files (+ markdown import, "N of M located" indicator) — round-trippable session collaboration |
shipped |
| Per-page annotations across navigation — per-annotation URL, side-panel filter, halo replay | shipped |
Built-in modules — GitLab Issues via glab CLI (no tokens stored), screenshot embed, chat-based metadata prompt |
shipped |
| Test Pilot — interactive UAT module (import / agent-generate spec, Pass/Fail catalog, per-step copy, markdown export) | shipped |
| Test Pilot — tester sheet export (.md + .docx with embedded steps); standalone offline import | shipped |
Chat module — global FAB + Annotate Just Ask + Test Pilot per-row chat (new inquiry mode) |
shipped |
pinta-companion published to npm — npx pinta-companion . |
shipped |
vite-plugin-pinta for instant source mapping |
planned (Phase 6) |
| Drag-reorder annotations, group by file, undo last edit via git | planned (Phase 7) |
| Drag-to-resize handles, per-side spacing splits, design-token pickers | planned (Phase 8) |
| Cropped composite screenshot (5–10× smaller, only annotation bboxes) | planned |
Modules included
Pinta ships with five built-in modules — small agent-side
integrations that extend the core annotation loop. Enable in
Settings, opt in per submit (or per query for interactive modules).
The wire contract stays narrow: each module carries a stable id and a
small settings dict; the agent reads the id and routes to the matching
handler in skill/pinta/SKILL.md.
🏷️ GitLab Issues · per-submit
File one GitLab issue per annotation. Tick Create GitLab issues in
the footer before submitting, and the agent — after the source edits
land — uses your glab CLI to file the tickets.
- No tokens stored, transmitted, or written to disk by Pinta. Auth
comes from
glab auth loginon your own machine. - Issue body embeds: the full-page composited screenshot (uploaded to the GitLab project's uploads endpoint), the selector, source file path, and the annotated page URL.
- Chat-based metadata prompt: before filing, the agent asks for
domain (
client/server/shared→domain:<choice>label), extra tags, assignees, orlaterto defer entirely. - Screenshot auto-locks ON when this module is ticked so issues never go out without visual context.
Settings: project_id (optional override) and labels (default tags).
Leave both blank for the common case — glab auto-detects from your
repo's GitLab remote.
🧪 Test Pilot · interactive
A UAT module that lives in its own side-panel tab. Import a hand-written markdown test spec or let the agent generate one from project context, then step through the resulting catalog row-by-row.
- Pass / Fail / Untested marking per row, with per-section tallies in the catalog headers.
- Per-row "?" asks the agent for step-by-step instructions; the
inline Details checkbox flips between short tester-friendly
steps and deeper technical context (curl, payloads, env vars,
> Note:callouts) per Re-ask. - Markdown rendering in the step list — inline
`code, fenced code blocks with Prism syntax highlighting (bash + json), block-quote callouts. Each fenced block has a Copy button. - Markdown export of the whole catalog as a report with
pass/fail/total tallies. Pipe through
pandoc results.md -o results.pdffor a PDF version. - Tight retention: UAT specs live in
.pinta/test-docs/{docId}.mdand are wiped viaDELETE /v1/test-docswhen you clear the catalog (specs often carry real credentials, so the on-disk copy doesn't linger).
Wire-protocol-wise, Test Pilot is the first interactive module
surface: a new module.query.submit WS message carries a
kind: "query" annotation whose comment is a JSON-encoded request
(doc-parse, generate-doc, or detail-steps). The agent answers
via mark_session_done with a structured payload that the extension
routes back into the Test Pilot tab. See
spec/SPEC.md §8 Phase 12
for the full design.
🛡️ AuditFlow · interactive
Lighthouse-style audits in their own side-panel tab — five built-ins (security, performance, accessibility, mobile, cross-browser) plus custom checks you define with the same markdown format.
- Per-finding "Fix with agent" edits the source in place — a per-row loader, concurrent fixes, and Fix All on a category — instead of detouring through Annotate.
- Discuss (chat) and File issue (GitLab / local) per finding.
- Pass/fail summary per audit; results persist per project and re-run on
demand. See
spec/SPEC.md§8 Phase 15.
💬 Chat · inquiry
A three-tier "ask the agent" surface from one wire: a global tab,
Just Ask on any Annotate session, and per-row chat on Test Pilot.
Threads persist per surface and accept pasted images; inquiry sessions
never edit source. See spec/SPEC.md §8 Phase 14.
📅 Report · interactive
Merged git + GitHub activity and Pinta sessions as Read-mode day cards —
daily, weekly, 10-day sprint, or a custom range, multi-project aware.
One-click Markdown export, per-day or whole-range. See spec/SPEC.md
§8 Phase 16.
Writing your own
Beyond the five built-ins, Pinta can load importable modules — a
third party ships one as a single .pinta-module.json (manifest + agent
instructions) dropped into .pinta/modules/, gated behind a Settings
consent dialog and a default-deny capability check (sample at
examples/echo-notes.pinta-module.json). Adding a built-in module is
just as small:
- Add an entry to
extension/src/lib/modules.tswithid, settings schema, andmode: "per-submit" | "interactive". - Ship the matching agent instructions in
skill/pinta/SKILL.md(§7.9 for per-submit, §7.10 for interactive). - (Optional) Pick an icon for the Settings panel + landing page.
PRs welcome — see Contributing.
How it works
Annotate Capture Edit
──────── ─────── ────
┌────────┐ ┌────────┐ ┌────────┐
│ Chrome │ WebSocket │ Pinta │ HTTP / MCP │ Claude │
│ ext. │ ◄──────────► │ comp- │ ◄──────────► │ Code │
│ │ │ anion │ │ Cursor │
└────────┘ └────────┘ └────────┘
side panel :7878 edits files
+ overlay .pinta/sessions/ runs HMR
- Draw / point at things in your running app.
- Submit — the extension takes a full-page screenshot, bakes the annotations onto it, and sends the session to the companion.
- Agent picks up the session, presents a per-file edit plan, and (with your confirmation) applies the changes. HMR shows the result.
Quickstart
Prerequisites: Node 20+, Chrome (or any Chromium-based browser), and a coding agent. Steps 1–2 capture annotations; step 3 connects your agent so it can act on them.
1. Install the Chrome extension
Install Pinta for Chrome → (Chrome Web Store). Open the side panel from the toolbar.
2. Run the companion in your project
npx pinta-companion .
3. Connect your agent
There are two ways to wire an agent to the companion. Pick one.
Option A — MCP (recommended; no clone, works with every agent)
The companion ships an MCP server (pinta-mcp). The agent picks up sessions
through Pinta's MCP tools — there is no /pinta slash command on this
path.
Claude Code:
claude mcp add pinta -- npx -y -p pinta-companion pinta-mcp
Cursor / Cline / Continue / Zed — drop this into your agent's MCP config:
{
"mcpServers": {
"pinta": {
"command": "npx",
"args": ["-y", "-p", "pinta-companion", "pinta-mcp"]
}
}
}
Option B — the /pinta skill (Claude Code)
The slash command is a Claude Code skill — it is not installed by
npx pinta-companion. Install it once, no clone required, either way:
B1 — npm installer (one command):
npx pinta-companion@0.6.0 install-skill # writes ~/.claude/skills/pinta/
Then fully restart Claude Code (skills load at startup — /clear is not
enough), type /, and confirm pinta is in the list. Run /pinta.
B2 — Claude Code plugin (auto-updates):
/plugin marketplace add kevzlou7979/pinta
/plugin install pinta@pinta
Installs immediately (no restart). Note: plugin skills are namespaced, so the
command is /pinta:pinta rather than /pinta. Updates come through
/plugin when a new version is published.
Hacking on Pinta itself? Clone the repo and run
bash scripts/install-skill.sh(Git Bash on Windows) — it points the skill at your local companion sonode ~/.claude/skills/pinta/start-companion.js .runs your working tree instead of the published bundle.
Either way: annotate the page, hit Send to agent, and — from your
project root — run /pinta (Option B) or just ask your agent to pick up the
Pinta session (Option A). It edits the matching source files; HMR shows the
result.
Hacking on Pinta itself? See Development below for the source build (
git clone→npm install→npm run build, load unpacked in Chrome).
Daily workflow
1. Start the companion in your project root
npx pinta-companion .
No clone or build needed — pinta-companion is published to npm as a
self-contained bundle (~210 KB). Runs on Node 20+. Alternatives if you've
cloned the repo: node ~/.claude/skills/pinta/start-companion.js . or
npm run dev:companion -- --project /path/to/your/app.
The companion listens on http://127.0.0.1:7878 (auto-incrementing to
the next free port if 7878 is busy — useful when you're running Pinta
on multiple projects in parallel) and writes sessions to
{project}/.pinta/sessions/{id}.json (with the screenshot alongside as
{id}.png).
Each running companion registers itself in ~/.pinta/registry.json so
the side panel and the /pinta skill can find the right one for the
project / tab you're working on. See Multi-project mode.
2. Open your app in Chrome and the Pinta side panel
Toolbar icon → side panel. The side panel will say Connected when it finds the companion.
3. Annotate
- Press
Alt+Son the page to enter Select mode — hover an element, click to lock it, type a comment, hit Add. - Press
Alt+Pto enter Draw mode — pick a tool (arrow / rect / pen / pin), drag on the page, comment, Add. - Annotations appear as cards in the side panel. Edit, delete, reorder.
4. Submit
Hit Send to agent. The extension posts the session over the WS to the
companion. The screenshot is opt-in (off by default) and auto-locks-on
when there's a drawing in the batch — selectors + nearby text are usually
enough for select-kind annotations, and skipping the capture saves
~1.5–2k vision tokens per submit.
5. Hand off to your agent
Claude Code: type /pinta (push mode, default — wakes the moment the
companion has a session) or /pinta --polling (long-poll fallback for
sandboxed setups). The skill picks up your session, presents an edit plan
grouped by file, and waits for your confirmation before editing.
Cursor / Cline / Continue / Zed: see
adapters/cursor/README.md for the MCP
config. Then prompt: "Pick up the pending Pinta session and apply the
changes — show me the plan first."
Aider: see adapters/aider/pinta-poll.sh.
Anything else (claude.ai web, ChatGPT, etc.): the side panel has a Copy button that formats the session as markdown — paste into the agent's chat. Useful when you can't run a CLI.
Custom HTTP: speak /v1/sessions/poll and /v1/sessions/:id/status —
that's the universal lowest-common-denominator.
6. Watch the result
After the agent applies the edits, the side panel detects HMR (Vite / Webpack / Parcel) on the active tab and offers to refresh automatically. Each annotation card flips to ✓ as it lands; the screenshot, plan, and applied summary stay in History for later.
Multi-project mode
Run Pinta on more than one project at once — each npx pinta-companion .
picks the next free port (7878 → 7879 → 7880 …). All running companions
register themselves in ~/.pinta/registry.json, which lets:
- The side panel show a project picker in the header. The active tab
is auto-routed to the right project via URL patterns (e.g.
http://localhost:5173/*→claims-forms). Click a tab once and use the Associate this URL button — the pattern is committed to that project's.pinta.jsonso teammates inherit it. - The
/pintaskill find the companion whoseprojectRootmatches the agent'spwd. No more "wrong project" submits when you forget to restart in a different repo.
Project-scoped .pinta.json (committed):
{
"urlPatterns": [
"http://localhost:5173/*",
"https://*.staging.example.com/*"
]
}
* matches one path segment, ** matches multiple. If a tab matches
zero or multiple companions, the picker stays open so you choose
explicitly — no silent mis-routing.
Architecture
pinta/
├── spec/SPEC.md full design spec
├── shared/ @pinta/shared — TypeScript types
├── companion/ @pinta/companion — Node 20+ HTTP / WS / MCP server
├── extension/ @pinta/extension — Chrome MV3 (Svelte 5 + CRXJS)
├── skill/pinta/ Claude Code reference adapter (skill + installer)
├── adapters/
│ ├── cursor/ Cursor / Cline / Continue / Zed MCP setup
│ └── aider/ Aider poll script
├── scripts/ install + smoke-test scripts
└── docs/ GitHub Pages landing page
Boundaries that matter:
- The extension knows nothing about agents.
- The companion knows nothing about specific agents — it exposes a generic HTTP API and an MCP server.
- Agents know nothing about the extension — they consume sessions from the companion.
That separation is the whole point. It's why "works with any coding agent" is real and not aspirational.
Hotkeys
| Key | Action |
|---|---|
Alt+S |
Toggle Select mode |
Alt+P |
Toggle Draw mode |
Alt+X |
Exit to idle (alternative to Esc) |
Esc |
Cancel in-progress stroke → pending comment → exit mode |
HTTP API
Versioned at /v1/. Used by every non-MCP adapter.
GET /v1/health → 200 OK
GET /v1/sessions/active → current session or null
GET /v1/sessions/:id → full session
GET /v1/sessions/poll → long-poll for next submitted session (25s)
POST /v1/sessions/:id/status → { status, summary?, errorMessage? }
Full WebSocket protocol and MCP tool list are in
spec/SPEC.md.
Development
npm install # install all workspaces
npm run dev:companion -- --project /some/app # run the companion against a target project
npm run dev --workspace @pinta/extension # vite dev for extension HMR
npm run build # build all workspaces
bash scripts/post-fake-session.sh # smoke-test the loop without a browser
The smoke-test script is the fastest way to verify a fresh install — it posts a fake session to the companion and confirms the agent-facing endpoints respond as specified.
Roadmap
V1 covers the core loop. What's next, in priority order:
- Phase 6 —
vite-plugin-pinta. Injectdata-source-file/data-source-linein dev so the agent doesn't have to grep. Targets >95% source-mapping accuracy. - Phase 7 — Polish. Drag-to-reorder annotations, group by file in the
side panel, undo last edit (rolls back via git), plan-then-execute
toggle. (Per-project
.pinta.jsonshipped alongside multi-project mode and is already wired up.) - Phase 13 — Test Pilot catalog editing. Delete / add / edit /
rename / reorder sections + tests from the side panel, with
on-disk
.pinta/test-docs/{docId}.mdkept in sync via a new companion endpoint. Lets you patch AI-generated catalogs in place instead of regenerating. - Phase 14 — Inquiry mode (chat module). Adds a third module verb
alongside act: a shared bottom-sheet chat with three entry points
— a global header icon for FAQ-style asks, a "Just Ask" checkbox
on Annotate (Submit becomes Ask), and a FAB on the Test Pilot tab
for per-row context. All three share one
op: "chat"wire and one sheet UI. Replaces the current Test Pilot per-row Notes. - Phase 15 — AuditFlow module. Lighthouse-style audit surface as
a Pinta module. Four built-in categories (security / perf / a11y /
mobile) plus user-defined custom audits — paste guidance or upload
a
.mdand the agent generates the rules for you. Per-check Fix with agent composes a Pinta annotation and routes through the standard source-edit loop; Discuss routes to the Phase 14 chat; File issue routes through GitLab Issues. Card + table views, deterministic scoring, cross-run continuity. The audit becomes a source of work the existing modules consume. - Phase 18 — Agent role routing.
/pinta --annotate/--test-pilot/--audit/--chatflags let multi-terminal users dedicate each Claude Code window to a workload. Agents silently skip sessions outside their role so a long audit run doesn't block the next annotation. Skill-only change — no wire changes, no companion changes. Roles stack; no-flag = current "claim everything" behavior. - Beyond. Conflict detection, multi-tab sessions, read-only sharing.
See
spec/SPEC.md§9 for the open design questions.
Contributing
Issues and PRs welcome. Before opening a PR:
- Read
spec/SPEC.md— the design's load-bearing pieces are documented there. - Run
npm run buildandbash scripts/post-fake-session.shto confirm the end-to-end loop still works. - Keep the boundaries clean. Agent-specific code lives under
adapters/orskill/, not incompanion/orextension/.
Creator
Mark Kevin Baldemor (@kevzlou7979) — designed and built Pinta because the gap between "I can see what's wrong on this page" and "the agent edits the right file" was bigger than it had to be.
If Pinta saved you time, the cheapest thank-you is a ⭐ on the GitHub repo. Issues and PRs welcome too — see Contributing above.
Usage, plans & Anthropic compliance
Pinta is bring-your-own-Claude. It runs as a skill inside your own
interactive Claude Code terminal — it never proxies, stores, or shares your
Anthropic credentials, never uses "Login with Claude.ai", and is not an
Agent-SDK / headless / claude -p / cron tool. You use Claude under your own
Anthropic plan and terms.
- Interactive, individual use of Claude Code (how Pinta runs) is the
supported lane under Anthropic's subscription plans. The
/pintaskill is event-driven and pauses itself after ~30 min idle — it is not an always-on automated agent. - Heavy or automated workloads belong on API billing, not a Pro/Max subscription.
- One user = their own Claude account/key. Pinta never routes multiple users through one subscription; a hosted/team setup would require each user to supply their own API key.
These boundaries keep Pinta within Anthropic's terms by design. In particular, the April 2026 "OpenClaw" restriction — Anthropic blocking Claude subscription credentials inside third-party harnesses — does not apply to Pinta: Pinta isn't a harness and never touches subscription OAuth; it hands work to the interactive Claude Code you run. The full breakdown (including a side-by-side of the banned pattern vs. how Pinta works) lives on the Compliance page.
If you deploy Pinta commercially or to a team, review the current Anthropic usage terms and Claude Code legal docs.
License
MIT — see LICENSE. Copyright (c) 2026 Mark Kevin Baldemor.