New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

notemend

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

notemend

A dev-only toolbar for Astro and Next.js sites: pinned page comments Claude Code can read and answer, spacing/size/type inspectors in design px, a layout grid, breakpoint canvas and device preview.

npmnpm
Version
0.1.20
Version published
Weekly downloads
724
-69.77%
Maintainers
1
Weekly downloads
 
Created
Source

notemend

Note it. Mend it. Pin a comment on any element of a live site, at the screen width it breaks; your coding agent — Claude Code, Codex, Cursor, Gemini CLI, Copilot or any other — takes the comment, fixes the code and says what it changed; a person confirms the fix with a tick. For design studios, their teams and their clients.

This package is the bar people comment with and the notemend CLI and MCP server agents work the queue with. The threads live in the Notemend cabinet at app.notemend.com, shared by everyone in a project — or, with no account, in feedback/comments.json in your repo. Docs: app.notemend.com/docs.

Start

  • Make a project at app.notemend.com.
  • Put the bar on the site — one line, any site (below) — open it with Notemend, and pin comments. Teammates and clients do the same.
  • In the site's code folder, connect your agent:
npx notemend init      # asks which agents you use and wires each one
npx notemend login     # shows a code; allow it in the cabinet
npx notemend link <project-id>

Then ask your agent for the open comments. It takes one (notemend start), fixes it and resolves it with a note (notemend done); the comment waits, marked, until a person confirms it on the site or in the cabinet.

On any site — one line, no build

Webflow, Shopify, WordPress, Framer, a live Next or Astro site: the cabinet's Install tab hands out one line for the site's custom code,

<script src="https://app.notemend.com/bar.js" data-project="<project-id>" defer></script>

and the whole bar — comments, grid, spacing, size and type inspectors, breakpoints, devices — runs on the live site. A visitor sees nothing: the bar wakes only for people in the project, once they open the site with ?notemend (the cabinet's "Open site", the link you send a client) and sign in once on that browser. Their session stays with the cabinet, in a hidden frame of its own — the site's scripts never hold a token. The cabinet's Preview tab shows the site at desktop, tablet or mobile width with the bar in it. The pages menu comes from the site's sitemap.xml and the pages that already have threads.

bar.js is src/hosted.ts bundled by the cabinet's build (web/scripts/build-bar.mjs); its endpoints are the dev server's, served by the cabinet (src/hosting.mjs) as whoever is signed in, so the database's rules decide what they may read and write.

Your coding agent

The queue is a CLI any agent that runs commands can work, an MCP server for agents that take tools, and a Claude Code plugin. Whichever you use, a comment reaches the agent with its page, element, width, device, thread, screenshots and what the page logged (console errors and failed requests, secrets masked), quoted as what people wrote — never as instructions — and only the comments meant for the agent.

npx notemend                     open comments for the agent
npx notemend all                 including resolved ones and those given to people
npx notemend start <id> [--force]  take it before fixing: the thread shows the agent is on it,
                                 and another agent is refused (--force takes it anyway)
npx notemend reply <id> "..."    answer in the thread (also: note)
npx notemend done <id> "..." [--shot]  resolve as the agent, with a note (stays marked until a
                                 person confirms); --shot files a picture after the fix
npx notemend reopen <id>
npx notemend rm <id>             delete the thread and its screenshots
npx notemend shot <id> ["note"] [--before] [--url <dev server>]  a picture of the element at the comment's
                                 width (Playwright); a note goes in the thread as the agent's reply
npx notemend watch [--timeout <min>] [--start | --stop]  turbo: wait for a comment for the agent, print it, exit
npx notemend prune [--dry]       local store: move resolved threads to feedback/archive/
npx notemend digest | count      short forms for the agents' hooks (--format claude|codex|gemini|cursor)
npx notemend mcp                 the same queue as an MCP server (stdio)
npx notemend init [--yes] [--ci] [--agents=<list>] [--force]  set a project up (hooks, config; --ci adds the workflow)
npx notemend login [--code] | whoami | logout | link [<project-id>] | unlink
npx notemend --as <agent> …      sign as codex, gemini, cursor, copilot… (default: Claude)
npx notemend --version | --help

NOTEMEND_URL is the dev server for screenshots when there is no --url; NOTEMEND_KEY and NOTEMEND_PROJECT are for an agent on its own (below).

The root is the nearest directory with a package.json above the working directory, or --root <dir>. The panel numbers threads per page and breakpoint (#4); the CLI prints both that and the file-wide id: #4 (id 10). prune keeps a local store readable: resolved threads and their screenshots move to feedback/archive/, and the numbering carries on. Nothing is deleted.

Signing in

npx notemend login                 # shows a code and opens the cabinet — allow the same code there
npx notemend link                  # a new project named after the site (package.json name and homepage)
npx notemend link <project-id>     # or an existing one — the id is under Install in the cabinet

login works over SSH and in containers too — nothing listens on your computer; open the link on any machine where you are signed in. login --code signs in with the six-digit code the cabinet emails instead. The terminal gets a session of its own, so signing out in one never signs out the other. link writes .notemend.json; commit it and the whole team files into the same project. whoami says who you are and where comments go; unlink and logout undo.

Wiring each agent

init asks which agents you use (or --agents=claude,codex,cursor) and wires each the way it reads context:

AgentWhat init writesWhat it reads
Claude Code.claude/settings.json hooksdigest at session start, count on each prompt
Codex.codex/hooks.json (+ codex_hooks = true in .codex/config.toml)the same, as plain text
Gemini CLI.gemini/settings.json hooks, GEMINI.mdthe same, as hookSpecificOutput.additionalContext JSON
Cursor.cursor/hooks.json (sessionStart)digest as additional_context
Copilot, Windsurf, Amp, …a block in AGENTS.mdhow to list, take, answer and close threads

An agent signs what it writes: threads show Codex, Gemini or Cursor rather than Claude. Gemini CLI, Codex and Cursor are recognised from their environment; any other passes --as <agent> (npx notemend reply 3 "…" --as copilot).

MCP

npx notemend mcp serves the queue over stdio: list_comments, start, reply, resolve, reopen and screenshot (before, and a note that goes in the thread as a reply). Each runs the CLI above, so the cloud, agent keys and sign-in work as they do there; replies are signed with the client's own name. It is in the MCP Registry as io.github.zharkodv-cmd/notemend.

One click: Add to Cursor, Add to VS Code and the Claude Desktop bundle are on app.notemend.com/docs/mcp. By hand:

codex mcp add notemend -- npx -y notemend@latest mcp
claude mcp add notemend -- npx -y notemend@latest mcp
{ "mcpServers": { "notemend": { "command": "npx", "args": ["-y", "notemend@latest", "mcp", "--root", "/path/to/site"] } } }

Claude Code plugin

The hooks and the tools in one, no init needed for Claude Code:

/plugin marketplace add https://app.notemend.com/claude/marketplace.json
/plugin install notemend@notemend

Its files are in plugin/; npm run pack puts them at the package root, and npm run mcpb rebuilds the Claude Desktop bundle (web/public/notemend.mcpb) after a pack.

An agent that works on its own

A project's settings make agent keys (shown once, kept only as a hash). With one as NOTEMEND_KEY, the CLI needs no sign-in: it lists the project's threads and takes, answers and closes them as the agent — nothing else. npx notemend init --ci writes .github/workflows/notemend.yml: every hour (or by hand) it asks for the agent's threads and, when there are some, runs Claude Code's GitHub Action to fix them on a branch, close each with what it changed, and open a pull request. It needs the repository secrets NOTEMEND_KEY and ANTHROPIC_API_KEY, and .notemend.json committed. A person still merges, and confirms each fix on the live site.

The bar

Review a site the way you review a design file:

  • Pages — every route in one menu, grouped by folder (or your own groups), with the open-comment count per page and per breakpoint.
  • Grid — your layout grid drawn over the page, from your own .container / .grid.
  • Spacing · Size · Typography · Colour · Border & radius — hover an element for its padding, margin and gap, its size, its type (size, line height and letter spacing the way Figma states them), its fill and text colour, or its border per side and radius per corner — each colour by the CSS variable it was written with. Values are design px: actual px ÷ the root font scale.
  • Comments — Figma-style pins: threads, six types (General, Bug, Text, Motion, Design, Content), screenshots (paste, drop or pick) that go with the message they were sent with, your own messages editable, a half-written comment parked as a draft — a pencil pin on the page and a row in the panel — when you close it or click somewhere else; drafts never block a new comment. Filed per page and per breakpoint.
  • Keys — one key per tool, Figma-style: C comments, ⇧C panel, R resolved, G grid, P/S/T/O/B inspectors, E Sanity, 1–9 breakpoints, D devices, [ ] pages, \ hide the bar, ? the list (also behind the keyboard button). Physical keys, so any layout works; never while you type; inside the canvas too.
  • Breakpoints — the page in a canvas at a band's width; drag either edge inside the band. Comments written there belong to that band.
  • Devices — two lists behind one button. Preview: the eight screens most visitors use (iPhone 15/16, iPhone 17 Pro Max, iPhone SE, Galaxy S25, iPad, MacBook Air, a Windows laptop, a 1080p monitor), each drawn with its browser around the page — status bar and Safari on iPhone, Chrome on Android, a Safari or Chrome window with the menu bar and Dock or the taskbar on computers — so the page gets the height a real browser leaves it (393×695 on an iPhone 16, not 393×852). DevTools: every device Chrome DevTools knows (46, by kind, searchable) — the canvas at that device's exact size, rotatable. Both are working surfaces: comments go to the breakpoint the width falls in, and remember the device ("iPhone SE · bars folded").

Using the bar

Control
Pagesjump to any page. Chips show comment counts, one per breakpoint and status, in the six status colours: new, in progress, to review (an agent's fix, or Needs review), waiting, accepted, and resolved while resolved threads are shown
Gridthe layout grid overlay
Spacing / Size / Type / Colour / Borderinspectors, one at a time. Hold Alt to measure the parent
Sanityhides Sanity's visual-editing overlay (only with sanity: true)
Commentcomment mode: click anything to pin a note. The badge counts open threads
Panelthe list of this page's threads at this breakpoint
Resolvedshows or hides resolved threads, on the page and in the menu
Breakpointsopen the canvas at a band. The widest band is your own window
DevicePreview: a real screen with its browser. DevTools: the canvas at a device's size. Comments work in both
Tab on top of the barfolds the bar below the window edge and back

Keys: Esc closes a menu, then the note you are writing, then the open thread, then comment mode. Enter sends, Shift+Enter is a new line. Double-click a canvas handle to snap to the band's edge.

Everything the bar remembers (modes, canvas width, a half-typed comment) is in localStorage, per browser.

The bar in your dev server

For Astro and Next.js projects the same bar runs under astro dev / next dev — with no account, comments stay in feedback/comments.json and screenshots in feedback/images/; linked, they go to the project. Nothing of it reaches a build.

Install

npm i -D notemend
npx notemend init

init reads the project and asks only what it cannot read:

  • breakpoints — found in your CSS media queries (Tailwind's defaults if you use Tailwind), shown as bands for you to confirm or retype;
  • pages — every page under src/pages (Astro) or app/ (Next), named from its <title> or metadata.title, grouped by folder; dynamic routes are listed as examples for you to fill in;
  • grid — the container and grid classes the overlay should borrow;
  • agents — which coding agents you use, to wire each (above);
  • git — whether to keep pasted screenshots out of it.

It writes notemend.config.mjs, wires the bar in (Astro: notemend() in astro.config; Next: see below) where it is not there yet, and touches nothing else. npx notemend init --yes takes every default.

Without init, integrations: [notemend()] in astro.config.mjs is enough: four default breakpoints, pages grouped by folder.

After upgrading, stop and start astro dev. Astro's own restart (on a config change) runs in the same Node process, which keeps the old server half of the bar loaded while the browser half is already new.

Next.js

App Router, Next 15.3 or later, Turbopack or webpack. Next has no integrations, so init writes three small pieces instead:

// instrumentation-client.ts — loads the bar; a build drops the import with the branch
if (process.env.NODE_ENV === 'development') import('notemend/client');
// app/%5F%5Fdevbar/[...path]/route.ts — the /__devbar/ endpoints (`%5F` is how a Next
// folder serves a segment that starts with `_`); outside `next dev` it answers 404
export { GET, POST, PATCH, DELETE } from 'notemend/next';
// next.config.ts — the bar ships as TypeScript, which Next compiles from node_modules
// only when told
const nextConfig: NextConfig = { transpilePackages: ['notemend'] };

(src/app and src/instrumentation-client.ts in a project that keeps its code in src/.) An existing instrumentation-client gets the line appended; a next.config init cannot edit safely is left alone with a note of what to add.

A proxy.ts (middleware.ts before Next 16) that guards every route — a login wall — must let /__devbar/ through, or the bar cannot load its config:

export const config = { matcher: ['/((?!__devbar|_next/static|_next/image|favicon.ico).*)'] };

There is no enabled switch under Next: to keep the bar out of a Playwright run, add your own condition to the instrumentation-client line.

Configuration

Everything lives in notemend.config.mjs at the project root — named exports or one default object. It is re-read on every page load: edit, refresh, no restart.

// notemend.config.mjs
export const breakpoints = [
  { id: 'desktop', label: 'Desktop', min: 992, max: Infinity, ideal: 1440 },
  { id: 'tablet', label: 'Tablet', min: 768, max: 991, ideal: 834 },
  { id: 'landscape', label: 'Mobile landscape', min: 480, max: 767, ideal: 667 },
  { id: 'portrait', label: 'Mobile portrait', min: 0, max: 479, ideal: 390 },
];

// route → [name, group]. Unlisted pages still appear, named by <title>.
// A number in front of a name only orders the rows: '1.2. About' reads as 'About'.
export const pages = {
  '/': ['Home', 'Main'],
  '/blog/hello-world': ['Blog post', 'Blog'], // an address a dynamic route serves
};
export const groups = ['Main', 'Blog'];      // menu order; unlisted pages land in the last

export const grid = { container: 'container', grid: 'grid', columns: 12 };
export const sanity = true;                  // Sanity overlay toggle
export const ignore = ['.my-dev-nav'];       // selectors the inspectors skip
export const devices = [/* … */];            // the device shelf, see below
export const zIndex = 2000000020;            // the bar's base layer
KeyDefault
breakpointsthe four aboveid, label, min, max (Infinity for the widest), ideal (canvas width), optional icon (SVG paths, 20×20)
pagesfrom src/pages / app/route → [name, group]
groupsby foldergroup order
gridcontainer / grid / 12classes of your own layout the overlay reuses
devicesthe eight abovethe preview shelf: { id, label, group, w, h, shell, browser, note? } — shell: island home punch tablet macbook laptop monitor; browser: safari-ios chrome-android safari-ipad safari-mac chrome-windows; note is the row's tooltip. An older (mitka) config gave a device a frame picture; such an entry is skipped with a warning
sanityfalseshow the Sanity overlay toggle. Sanity's visual editing takes any iframe for Studio's Presentation and swallows clicks on CMS text there — in the canvas, tabs and buttons stop working. Skip its island inside the bar's frame: window.frameElement?.closest('.dt-frame')
shortcutstruesingle-key shortcuts and their list in the bar; false for a site with letter keys of its own (a video player)
ignore[]selectors the inspectors and comment picker skip
zIndex2000000020above Astro's dev toolbar and any app modal

Under Astro the same keys can be passed to notemend({ … }) in astro.config, where they win over the file. enabled only works there: notemend({ enabled: process.env.CI !== 'true' }) keeps the bar out of, say, a Playwright run.

A private install

Installed from a repo the build machine cannot reach (an optionalDependency on a private GitHub repo), import it behind a catch so a missing package never breaks the build — init writes it this way when it finds notemend under optionalDependencies:

const notemend = await import('notemend').then((m) => m.default).catch(() => null);
export default defineConfig({ integrations: [...(notemend ? [notemend()] : [])] });

How it works

  • The integration injects one script into every page under astro dev and serves its endpoints under /__devbar/ from Vite middleware. Under astro build it does nothing. Under Next the same endpoints are a route handler, and the script waits for React to hydrate <html> before it touches it — an attribute set earlier is a hydration error.
  • A client-side navigation (Next's <Link>, anything built on pushState) keeps the bar and moves it to the new page: its threads, its drafts, its row in the menu.
  • The canvas is the same page in an iframe. The bar runs in both copies; the one inside hides itself and takes its modes from the page over postMessage.
  • The bar stays above the page's modal <dialog>s: while one is open, the bar moves into a popover host inside it (top layer, not inert) and back out when it closes.
  • Writes to /__devbar/comments from another origin are refused — any site open in the same browser could otherwise post a "comment" an agent would read as a task.
  • The bar is sized in px on purpose: a site with a fluid root font-size would otherwise scale the dev UI along with the design.
  • A preview is an iframe, and some things only a real device or DevTools emulation shows: every vh/svh/lvh unit is the iframe's height (on the phone 100vh is the taller, bars-folded one), hover/pointer media queries answer for your mouse, env(safe-area-inset-*) is 0, and the pixel ratio is your screen's. The badge says which page size you are looking at; the bars button switches to the folded one.
  • The browser heights are measured (iOS 26 Safari, Chrome, macOS, Windows 11) except the Galaxy status bar and the iPad toolbar, which are estimates — see src/client/devices.ts.

Development

src/integration.mjs       the Astro integration
src/next.mjs              the Next.js route handler (notemend/next)
src/server/middleware.mjs /__devbar/* endpoints, notemend.config.mjs loading
src/hosted.ts             bar.js: the bar as one script for any site, signed in through the cabinet
src/hosting.mjs           the same endpoints as the cabinet serves them to bar.js (notemend/hosting)
src/store/                comments.json store, tags, statuses, thread helpers — shared by CLI, server, browser
src/store/cloud.mjs       the store in the cabinet's database, the CLI's session, `notemend login`
src/presets.mjs           the preview shelf, default breakpoints, switcher icons
src/client/               the bar: markup.ts builds the DOM, run.ts is the behaviour, notemend.css
src/client/devices.ts     the preview devices: bodies as SVG, status bars and browsers as HTML
bin/notemend.mjs          the CLI; bin/init.mjs is `notemend init`; bin/mcp.mjs the MCP server over it
tools/                    pack.mjs (the minified package for npm), mcpb.mjs (the Claude Desktop bundle),
                          sync-devtools-devices.mjs (Chrome's device list)

npm test runs the selftest (store, CLI, init, the endpoints). To work on the bar, point a test project at your checkout — "notemend": "file:../notemend" — and restart its dev server after changing anything outside src/client/. Turbopack will not compile a linked package that lives outside the project, so for a Next test project install a packed copy (npm pack, then npm i -D ../notemend/notemend-x.y.z.tgz) instead.

License

Proprietary — see LICENSE: you may install and run the package only to use Notemend. The DevTools device list (src/devtools-devices.mjs, regenerated by tools/sync-devtools-devices.mjs) comes from Chrome DevTools and keeps its BSD licence notice (© The Chromium Authors).

Keywords

astro-integration

FAQs

Package last updated on 14 Oct 2026

Related posts