JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 59
  • Score
    100M100P100Q75251F
  • License UNLICENSED

CleverOps review toolbar — drop-in React widget + Babel plugin + Turbopack loader for client-markup review sessions. Annotations land in Supabase and auto-create Linear issues for Claude Code to pick up.

Package Exports

  • @cleverops/toolbar
  • @cleverops/toolbar/next
  • @cleverops/toolbar/source-loc
  • @cleverops/toolbar/source-loc-loader

Readme

@cleverops/toolbar

The CleverOps review toolbar. One npm package covers:

  • Runtime widget<CleverOpsToolbar /> React component. Activates only when a reviewer link contains ?cleverops=<token>. Otherwise it renders null and does no work.
  • CDN script — lightweight loader at https://markup.cleverops.dev/toolbar.js for non-React sites (Webflow, WordPress, static HTML). It loads the widget bundle only when a review token/config exists.
  • Source-location transform — adds data-cleverops-loc="path:line:col" to JSX DOM elements at build time so element picks capture exact source locations for Claude Code. Available as @cleverops/toolbar/next (Turbopack-friendly Next plugin), @cleverops/toolbar/source-loc-loader (raw Turbopack/webpack loader), or @cleverops/toolbar/source-loc (Babel plugin for Vite/CRA).

Dashboard + API live at markup.cleverops.dev.

Quick start for Claude Code users

Paste a CLEVEROPS_API_KEY into your repo's .env.local (grab one from markup.cleverops.dev → Settings → API keys), then tell Claude Code:

Set up CleverOps review. API key is in .env.local.

Claude Code reads node_modules/@cleverops/toolbar/CLAUDE.md and takes care of installing the package, wiring the Babel plugin, calling the bootstrap API, and printing the reviewer link. Everything below is for manual setups.

Install (React / Next.js)

npm install @cleverops/toolbar

Render once in your root layout:

// app/layout.tsx
import { CleverOpsToolbar } from '@cleverops/toolbar';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <CleverOpsToolbar />
      </body>
    </html>
  );
}

If your host framework strips package-level "use client" directives, add a local client wrapper and import that from the layout:

// app/CleverOpsToolbarClient.tsx
'use client';

export { CleverOpsToolbar as default } from '@cleverops/toolbar';

Custom API host (staging / self-hosted)

<CleverOpsToolbar apiHost="https://staging.markup.cleverops.dev" />

Defaults to https://markup.cleverops.dev.

Install (script tag — any site)

Add to <head> or before </body>:

<script src="https://markup.cleverops.dev/toolbar.js" defer></script>

With a custom API host:

<script
  src="https://markup.cleverops.dev/toolbar.js"
  data-api-host="https://staging.markup.cleverops.dev"
  defer
></script>

Source-location transform

Lets the element picker report exact path:line:col from the source repo — Claude Code picks up Linear issues and knows which file to edit. Pick the install path that matches your bundler.

Next.js (Turbopack or webpack)

Wrap the Next config:

// next.config.ts
import { withCleverOps } from '@cleverops/toolbar/next';

const nextConfig = { /* existing config */ };

export default withCleverOps(nextConfig);

withCleverOps injects a Turbopack rule that runs the source-loc transform on .tsx/.jsx before SWC. Turbopack stays on; next/font/google, HMR, and SWC perf are unaffected. Webpack-mode Next builds use the Babel-plugin fallback below.

Vite

// vite.config.ts
import react from '@vitejs/plugin-react';

export default {
  plugins: [
    react({
      babel: { plugins: ['@cleverops/toolbar/source-loc'] },
    }),
  ],
};

Babel plugin (fallback / non-Next bundlers)

// babel.config.js
module.exports = {
  plugins: ['@cleverops/toolbar/source-loc'],
};

Adding babel.config.js to a Next project switches the build off SWC entirely — only use this path on webpack-mode Next or other bundlers.

Raw Turbopack / webpack loader

If you don't want the withCleverOps wrapper, declare the loader rule yourself:

// next.config.ts
const nextConfig = {
  turbopack: {
    rules: {
      '*.{tsx,jsx}': {
        loaders: ['@cleverops/toolbar/source-loc-loader'],
        as: '*.{tsx,jsx}',
      },
    },
  },
};

Plugin options

The Babel plugin (and, transitively, the loader and withCleverOps) accept these options:

option default effect
include everything under cwd glob patterns or RegExp — only instrument matching files
exclude ['node_modules/**'] skip matches
attrName 'data-cleverops-loc' override attribute name
includeColumn true when false, emit path:line instead of path:line:col

Example via the Babel plugin:

module.exports = {
  plugins: [
    ['@cleverops/toolbar/source-loc', {
      exclude: ['node_modules/**', '**/*.stories.tsx', '**/*.test.tsx'],
    }],
  ],
};

How it works

  1. Component (or CDN loader) mounts silently on page load.
  2. If the URL does not contain ?cleverops=<token> and there is no tab-scoped cached config, nothing else happens.
  3. If it does, the toolbar:
    • POSTs the token to <apiHost>/api/widget/validate
    • Caches the resolved config in sessionStorage (tab-scoped)
    • Strips the token from the address bar via history.replaceState
    • Mounts a shadow-DOM toolbar
  4. Reviewer picks elements, sketches via Excalidraw, drops replacement images, writes comments.
  5. Submissions go to <apiHost>/api/annotations + /api/screenshots. Each annotation auto-creates a Linear issue with selector, screenshot, source-loc, and the replacement file attached.
  6. On SPA navigation within the same origin, the toolbar stays mounted. On cross-origin navigation it unmounts.

Gotchas

  • Load the CDN loader in <head> or with defer in the body.
  • Strict CSP: script-src needs markup.cleverops.dev for the script-tag build; connect-src needs your chosen apiHost.
  • The widget mounts in a shadow DOM to isolate styles. It won't be affected by your site's CSS.

Bundle sizes

  • dist/index.js / .cjs — self-contained npm entry with React/ReactDOM as peers.
  • dist/cdn/toolbar.global.js — tiny CDN loader copied to /toolbar.js.
  • dist/cdn/toolbar-app.js + chunks — widget bundle copied to /toolbar-app.js and lazy chunks.
  • dist/source-loc.js / .cjs — ~3 KB. Babel plugin, Node-only.
  • dist/source-loc-loader.js / .cjs — Turbopack/webpack loader wrapping the Babel plugin.
  • dist/next/index.js / .cjswithCleverOps() Next plugin wrapper.

Development

npm install
npm run -w @cleverops/toolbar build
npm run -w @cleverops/toolbar dev        # watch mode
npm run -w @cleverops/toolbar typecheck