nitz Add to Chrome

Feedback for the agent that built it.

Stop describing the button.

Point at it instead. nitz pins your note to the exact element on any page, then hands your coding agent a brief with the selector, the visible text, and often the source line.

Chrome extension. No account. Nothing leaves your browser unless you send it.

Your agent can’t see your cursor.

So you describe the button. It greps for “save”, opens six files, and asks which one you meant. A nit carries the selector, the visible text, and the source line, so the agent starts at the element instead of hunting for it.

Without nitz

the save button on settings is always enabled?? also billing has a typo somewhere

$ grep -rn "save" src/ | wc -l
38

Which save button?

With nitz
1 P1 [data-testid=save] "Save changes"
  Disable until the form is dirty.
  @ SettingsForm src/components/SettingsForm.tsx:88

Opening SettingsForm.tsx:88.

Nit this page. It’s broken on purpose.

We broke the settings page below in four places. Find them, pin a nit on each, then hand the brief to the agent and watch it fix exactly what you pointed at.

Find the 4 nits
app.example.com/settings
~0 tokens
Detail

No nits yet. Press Pick, then click something that looks wrong.

Every field earns its tokens.

nitz/1 is plain text, one fact per line, written for an agent to act on. A five-nit brief stays under 250 tokens. There’s a test that fails if it doesn’t.

~90 tokens
nitz/1 https://app.example.com/settings "Account settings" 1440x900
1 P1 [data-testid=save] "Save changes"
  Disable until the form is dirty; it is always enabled today.
  @ SettingsForm src/components/SettingsForm.tsx:88
2 P3 section:nth-of-type(2)>h2 "Bililng"
  Typo: should read "Billing".
  @ BillingCard src/components/BillingCard.tsx:14
3 P2 p.plan-note text "renews on…"
  Show the real renewal date instead of an ellipsis.
  @ BillingCard src/components/BillingCard.tsx:17
4 P2 page
  Layout shifts on load; reserve space for the avatar.
-- sig did:key:z6MkhaXg…BZ2v did:key:z6MkhaXg…#z6Mk… ed25519 k3Vq…Q0Bw

Adds the @ line: file and line when the page exposes them, a CSS path when it doesn’t. The default.

  1. Page, title, viewport. The title tells SPA routes apart. A layout nit means nothing without the viewport.
  2. Number and severity. The number sticks for the life of the nit, so replies can say “nit 3”. P0 blocks the release; P3 is a nit’s nit.
  3. Locator. The shortest selector unique on the page: test id, then id, then name, then class, then a short CSS path.
  4. Visible text. A sanity check and a grep target, trimmed to 40 characters.
  5. Your note. The only part you write.
  6. Source. The element’s own file and line, from React dev builds or data-loc attributes, with Vue and Svelte markers too. No file? A component name and CSS path.
  7. Signature. Optional. Ed25519 over every byte above it.

Teach your agent once.

Most agents read a brief cold. If yours wants the rules, these are all of them, in under 300 tokens. Drop them in AGENTS.md or CLAUDE.md.

Copy with ⌥⇧C, or download as .nitz.txt, Markdown, or JSON. Every export shows its token estimate.

# Reading a nitz brief

A brief is page feedback anchored to DOM elements:

nitz/1 <url> "<title>" <viewport>
<n> <P0..P3> [tags] <locator> "<visible text>"
  <what to change>
  @ <Component> <file:line>   or   @ <css path>

- `locator` is a CSS selector unique on that page at capture time; `querySelector` it or grep for the test id, id, or text.
- The `@` line is the fastest route: `file:line` points at the source; a CSS path is the fallback.
- `<locator> text "..."` targets the quoted text inside that element; `page` means the whole page.
- `P0` blocks release, `P1` high, `P2` normal, `P3` nit.
- A trailing `-- sig <did> <kid> ed25519 <sig>` line signs everything above it; leave that text untouched when forwarding.

Work through nits in order, one change per nit, and reference them by number (`nit 3`).

Pages move. Pins stay put.

Re-renders don’t lose your place.

Each nit stores a selector, visible text, role, and stable attributes. After a re-render, a re-sort, or a client-side route change, nitz re-resolves the pin with a scored match. If the element is really gone, the nit stays listed and marked orphaned.

Inside iframes, too.

Pick elements in embedded frames, sandboxed ones included. The brief adds a line so the agent looks in the right document.

  frame: https://embed.example.com/checkout

Text nits.

Select some text before you pick and the nit quotes it, with context either side.

3 P2 p.plan-note text "renews on…"

Page nits.

For feedback that isn’t about any one element.

4 P2 page
  Layout shifts on load.

Three keys.

  • ⌥⇧N pick an element
  • ⌥⇧K review, edit, mark done
  • ⌥⇧C copy the brief

Rebind them at chrome://extensions/shortcuts.

Get it out of the chat window.

Claude artifacts, ChatGPT canvases, the prototype someone pasted into a thread: nitz saves the rendered page as one self-contained HTML file that opens anywhere. Or sends it straight to a Hobbsidian vault, where it gets a link that renders.

Download
One .html file, the page as it rendered. No chat window around it.
Send to Hobbsidian
Lands in your vault with per-file access, ready for your team to nit and their agents to read.
New chat

Make me a pricing page for the launch.

PreviewCode

Pick a plan

Starter$0
Most popularPro$24
Team$60

Your turn Press Export page in the nitz toolbar.

launch-pricing.html 1 file, self-contained, 48 KB

Nits that travel.

Link a Hobbsidian hub and team mode turns nits on a shared document into a thread. Everyone who can see the document sees them. @mention someone and the nit lands in their agent’s inbox over MCP.

  1. You share it

    The exported page sits in your vault. You share it with the team.

  2. Priya pins it

    Everyone on the document sees it: a pin in nitz, a comment in the share view.

  3. She hands it off

    The @mention routes the nit to Sam’s agent, scoped to that one document.

  4. Sam’s agent ships it

    It fixes the page and resolves the nit. The hub records who did it, for whom, under which delegation.

Every brief can say who wrote it.

nitz keeps a did:key identity inside the extension, an Ed25519 key that WebCrypto won’t let anything export. Signing adds one line to the brief. Change a character above it and the signature stops checking out.

Try it. The key below is generated in your browser, right now.

brief.nitz.txt Unsigned
nitz/1 https://app.example.com/settings "Account settings" 1440x900
1 P1 [data-testid=save] "Save changes"
  Disable until the form is dirty; it is always enabled today.
  @ SettingsForm src/components/SettingsForm.tsx:88
2 P3 section:nth-of-type(2)>h2 "Bililng"
  Typo: should read "Billing".
  @ BillingCard src/components/BillingCard.tsx:14

Permission slip

Signed by
did:key:z6Mk… (you)
Grants
vault:write
Scope
one folder in one vault
For
one brief
Expires
10 minutes after dispatch, by default
Revocable
any time

Dispatch never hands over your key. It mints a delegation like this one. No hub link, no mint.

Nothing runs until you open it.

Asks for almost nothing.

storage, activeTab, scripting, and clipboard write. No host permissions at install. nitz runs on a page when you open it there.

Per site, if you want it.

Turn on “Restore pins on this site automatically” and nitz gets that one origin, so pins come back on load. Remove it from the options page any time.

Local by default.

Nits, settings, and your key live on your machine. nitz talks to a Hobbsidian hub on that hub’s own pages, or to an endpoint you configured, and nowhere else.

No servers. No telemetry. No tracking.

Read the privacy policy

Go nit something.

Your agent is waiting for a line number.

Add to Chrome