stikfix
v1.3.2
Published
Pin sticky notes on any page — your AI reads them.
Maintainers
Readme
stikfix
Stick a note on any web page. Your AI coding agent reads it and fixes it. That's the whole loop.
The problem you already know too well
You spot something off in your UI — a button that's 4px too low, a heading that wraps weird, a modal that scrolls when it shouldn't. So you screenshot it. Paste it into a chat. Type a paragraph explaining which button, on which page, and what "right" looks like. Your agent guesses. You screenshot again. Round and round.
That ping-pong is slow, lossy, and maddening — and it throws away everything the browser already knows about the element you're pointing at.
stikfix kills the ping-pong. You drop a note directly on the thing, and it lands on disk as a precise, context-rich markdown file in your project's notes/ folder — which your AI agent can just read, fix, and mark done. A durable, file-based review loop instead of ephemeral chat.
No cloud. No accounts. No sign-up. Everything stays on 127.0.0.1 — your code and your notes never leave your machine.
How it feels to use
- Click Enter Review Mode on any page.
- Drop a sticky note — free-floating, or click an element to anchor it. Anchored notes auto-capture the CSS selector, computed styles,
outerHTML, the bounding box, an auto-highlighted screenshot, and the React component name. No describing required. - Tell your agent "read my notes." It reads the fresh
.mdfiles, makes the fixes, and writes a reply back into each note — so the pin turns green ✓ right on the page with a one-line "here's what I changed" (no fix is lost in a chat log). Anything ambiguous turns amber with the agent's clarifying question. - Glance at the pins (or open the notes panel to filter/search/jump), drop a few more, repeat. Pins update live as the agent works — no refresh. Your UI gets tighter every loop.
Quick start
1. Install the host (one command)
npx stikfix init --root /path/to/your/projectThis turnkey installer:
- registers the secure native-messaging host for Chrome and Edge (user-level, no admin rights),
- writes a small config pointing at your project,
- creates a "Stikfix Host" launcher on your Desktop so you can start the backend with a double-click — no terminal babysitting,
- prints your stable extension ID (you never copy-paste a token).
Keep it current: re-run
npx --yes stikfix@latest init --root /path/to/your/projectanytime to update the host.
2. Load the extension
For v1.0 the extension is loaded unpacked (a Chrome Web Store listing is coming next):
- Open
chrome://extensions(oredge://extensions). - Turn on Developer mode.
- Click Load unpacked and pick the
.output/chrome-mv3/folder from this repo.
The loaded ID matches what the installer printed — nothing to type. (Building .output/chrome-mv3/ from source is covered under Development.)
3. Start the backend
Double-click the Stikfix Host launcher on your Desktop. That's it — no commands, and double-clicking again is safe (it won't launch a second copy). The host listens on a port in the 39240–39260 range; the extension discovers it automatically.
4. Pair in one click
Open the stikfix popup in your toolbar and hit Pair with host. The token is handed over automatically through the OS native-messaging channel — you never see it, never paste it. Pair once and it stays paired, even after restarts.
5. Drop a note
Open your app, click Enter Review Mode, and start dropping notes. The first note on a new site opens an OS folder picker so you can choose where that origin's notes live; it's remembered after that. When you're ready, tell your AI agent "read my notes."
Features
- Free notes — a draggable post-it you can drop anywhere on the page. Captures URL, title, timestamp, viewport, and a screenshot.
- Element notes — click any element and the note auto-captures a robust unique CSS selector (
@medv/finder), curated computed styles, truncatedouterHTML, bounding box,data-*, accessibility role/label, the best-effort React component name, and an auto element-highlight screenshot showing exactly which element you meant. - Region / marquee capture — the camera tool dims the page, gives you a crosshair, and lets you drag a rectangle. stikfix hides its own UI, captures, and crops the screenshot DPR-correctly. Stack multiple per note; each is a deletable thumbnail.
- Persistent on-page pins — notes stay visible as pins on the page across reloads. View, edit, and delete them in place — backed by host-side CRUD over the localhost relay. Overlapping pins fan out automatically so dense pages stay readable.
- Two-way status, on the page — pins reflect the loop: unread (yellow), flagged (amber — the agent needs you to clarify, with its question on hover), resolved (green ✓ — fixed, with the agent's reply on hover). Resolved notes stay visible so you can verify the fix; archived (
read) notes disappear. - Notes panel — a chip-toggled list of every note: counts by status, filter chips, text search, and click-to-jump that scrolls right to the pin. Flip All pages to browse every note across the project, not just the current page.
- Live updates — while Review Mode is on, pins and the panel refresh on their own (~4s, only when the tab is visible) as the agent writes replies and resolves notes. No manual reload.
- Per-origin project routing — the first note on a new site opens an OS folder picker; after that, every tab routes to the right project's
notes/folder automatically. No per-note picking. - Cross-browser host — one
npx stikfix initregisters Chrome and Edge in a single pass. - The
review-notesAI skill — the portable agent half of the loop (see below).
How notes reach your AI
Every note becomes a markdown file in your project's notes/ folder, named <serial>-<YYYYMMDD-HHmmss>.md (e.g. 0007-20260531-143022.md), with any screenshots written alongside it as <base>+<N>.png. Element notes embed a full Element context section — selector, computed styles, outerHTML, React component — so an agent can locate the exact code without guessing.
The review-notes skill is the agent half of the loop. It works through your unread notes in serial order, applies each fix, then writes a short reply into the note and marks it resolved (the pin turns green ✓ on the page). Re-running is always idempotent — resolved, flagged, and archived notes are skipped.
Claude Code (project-local):
mkdir -p .claude/skills/review-notes
cp /path/to/stikfix/skill/SKILL.md .claude/skills/review-notes/SKILL.mdAny other folder-reading agent (Cursor, Codex, etc.): point it at skill/SKILL.md — it's plain markdown, no Claude-specific bits. For example: "follow the instructions in skill/SKILL.md."
Just say the word. Any of these kicks it off:
- "read my notes"
- "process review notes"
- "fix sticky notes"
- "what notes do I have"
Under the hood, it:
- Finds every unread
notes/*.md(skips*.read.mdand already-resolved/flagged notes), oldest serial first. - Reads the note plus its screenshots, then makes the code change.
- Marks the note resolved with a
reply(and optionalfixed_incommit ref) — only after the fix lands. If a fix is interrupted, the note stays unread and is retried next run. Resolved notes stay on the page (green ✓) so you can verify; archiving/dismissing (status: read+*.read.mdrename, which hides the pin) is a separate step done after you've acknowledged them. - Flags anything ambiguous instead of guessing — sets flagged with a
replyquestion (amber pin), so it surfaces again next run for you to clarify. - Gives you a one-line recap: N resolved, K flagged, J already done.
Run it on a clean directory and it just says "no unread notes." Safe to fire any time.
Demo

Recorded walkthrough coming soon — the placeholder above will be replaced with a GIF of the full drop-a-note → "read my notes" loop.
Cross-browser
| Browser | v1.0 status | Notes |
|---------|-------------|-------|
| Chrome | Supported | Load unpacked from .output/chrome-mv3/ |
| Edge | Supported | Drop-in; the same artifact loads directly. init registers Edge automatically |
| Firefox | Documented (next) | Different native-messaging manifest key; path documented |
| Safari | Documented (next) | App-bundled extension via Mac App Store; path documented |
Full packaging details, manifest locations, and the Firefox/Safari paths are in docs/cross-browser.md.
Security
stikfix is built localhost-first on purpose:
127.0.0.1only. The host binds to localhost and nothing else — never0.0.0.0, not reachable from your network.- Authorized writes only. Every
POST /annotationis token-checked. The token is delivered to the extension over the OS native-messaging channel during pairing — it never travels over the web and you never handle it. - Stays in its lane. The host only writes
.mdand.pngfiles inside the project folder you chose (itsnotes/dir). Path-traversal attempts are rejected; no eval, no shelling out. - Sensible limits. Oversized payloads are turned away (12 MB body cap →
413). - Right project, every time. Each tab's origin is mapped to its project, so notes land in the correct folder automatically.
- MIT, clean-room. Original implementation written from spec — contains no code from the GPL-3.0 upstream. See CLEAN-ROOM.md for the full provenance declaration and GPL grep audit.
Development
Build the extension and host from source:
npm install # installs deps + runs `wxt prepare`
npm run build # builds the extension (.output/chrome-mv3) + host bundles
npm test # host test suite
npm run check # full gate: tsc, clean-room check, host smoke test, all testsUseful scripts:
npm run dev— WXT dev server with HMR for the extension.npm run host -- --root /path/to/project --origin http://localhost:3000— start the host directly from a terminal (the Desktop launcher is the easy path; this is the manual one). On Windows PowerShell, use the equals form (--root=C:\path) or setSTIKFIX_ROOT/STIKFIX_ORIGINSenv vars, since npm 11.x swallows unknown--flags.
Removing stikfix:
npx stikfix uninstallThis removes the native-messaging manifest, the desktop launcher, and the local config — no leftovers.
Architecture (one-liner)
[Chrome/Edge Extension (MV3)] --POST /annotation--> [stikfix host (localhost)] --writes--> notes/NNNN-<ts>.md
you annotate token-authed, 127.0.0.1 only your AI agent reads thesePairing rides a separate OS-level native-messaging channel so the token never touches the web; notes themselves flow over the localhost HTTP relay (GET /status, POST /annotation, plus GET/PUT/DELETE /annotation/<serial> for the persistent on-page pins).
Tech stack
TypeScript ES modules both halves. Extension built with WXT (Vite, MV3) — vanilla DOM in a shadow root, @medv/finder for selectors, interactjs for drag + marquee, native chrome.tabs.captureVisibleTab + canvas crop for screenshots. The host is Node built-ins only plus yaml for safe frontmatter.
License & provenance
MIT © 2026 Omer Nesher. See LICENSE.
This is an original, clean-room implementation. See CLEAN-ROOM.md for the full MIT provenance declaration, clean-room method narrative, and the live GPL grep audit result.
