npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@insitue/sdk

v0.9.6

Published

InSitue capture SDK — drop one snippet into your deployed app; your users point at a bug, InSitue opens a verified pull request.

Readme

@insitue/sdk

The InSitue capture widget for browser apps. One component, two sinks: ship captures to the InSitue Cloud (production bug-reporting → autopilot → draft PR) or to a local @insitue/companion (developer mode → claude in your terminal acts on each pick).

import { InSitueCapture } from "@insitue/sdk";

// Dev: companion sink (no projectKey).
<InSitueCapture />

// Prod: cloud sink with your publishable project key.
<InSitueCapture projectKey="pk_..." />

Same widget. Same picker. Same screenshot pipeline. Only the submit step changes.


Install

npm install -D @insitue/sdk
# or pnpm add -D @insitue/sdk
# or yarn add -D @insitue/sdk

Dev mode (talk to claude in your terminal)

Mount with no props. The widget connects to a local companion over a loopback WebSocket. A claude session running /insitue:connect picks up each capture and edits the file you pointed at.

// app/layout.tsx (Next.js) — dev-gated so the chunk never
// ships in production.
import { InSitueCapture } from "@insitue/sdk";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        {children}
        {process.env.NODE_ENV !== "production" && <InSitueCapture />}
      </body>
    </html>
  );
}
// src/main.tsx (Vite)
import { InSitueCapture } from "@insitue/sdk";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <App />
    {import.meta.env.DEV && <InSitueCapture />}
  </StrictMode>,
);

Cloud issues inbox (dev mode)

When the companion is running (insitue dev) and you are logged in and linked to an InSitue Cloud project, the widget launcher gains an Issues entry with an unread count. Opening it lists the project's InSitue Cloud bug reports directly in your browser.

What it shows

The inbox is a navigable stacked card deck — one card per issue, with a persistent launcher you can reopen at any time (it isn't a flat list you scroll once and lose). Page through the deck to triage; each card shows:

  • The reporter's screenshot
  • Description and a status badge (open / in-progress / resolved)
  • Source location as file:line (e.g. src/components/Header.tsx:42)
  • Duplicate-count pill when multiple users reported the same element

Claim → resolve flow

Fix locally doesn't claim immediately — it opens an inline, editable pre-filled request ("Send to Claude") so you can tweak the wording first. When you send, the issue is claimed and the repro (screenshot, DOM context, source location) is fed into the local agent loop and broadcast to any insitue connect / Claude Code MCP subscriber listening in your terminal. The agent acts on the file immediately — no cloud-agent run consumed, no PR quota touched.

Once you have a fix, Mark resolved accepts a PR URL inline and submits the resolution back to InSitue Cloud.

Reject marks the issue won't-fix (status → rejected) with an optional reason. It consumes no agent run — consistent with the dashboard.

Token handling

The browser never holds your auth token. Issue requests go through the companion process over the loopback WebSocket (ws://127.0.0.1:5747). The companion — which has filesystem access to ~/.insitue/ — proxies the cloud API call and returns only the issue data. The token and project link never leave the companion's process.

Prerequisites

| Requirement | How to satisfy | |---|---| | Companion running | insitue dev in your project root | | Authenticated | insitue login | | Project linked | insitue link | | Paid plan | Free plan shows a gated state | | Companion version | ≥ 0.7.0 |

Cloud features require companion ≥ 0.7.0 (the enforced floor). Older companions show an "Update InSitue to continue" banner instead of the issues inbox.

See the @insitue/companion docs for the full fix-cloud-issues-locally guide.

Error states

The widget surfaces a clear state for each failure instead of failing silently:

  • not_logged_in — no credentials. Run insitue login (or the /insitue:login slash command) from this repo.
  • not_linked — signed in but the repo isn't linked to a project. Run insitue link (note insitue login already auto-links, so this is rarely needed).
  • scope_mismatch — your token is scoped to a different project than the one linked here. The widget tells you to sign in for this project — run insitue login from this repo to mint a project-scoped token for it.
  • not_paid — the project is on the free plan; the inbox shows a gated state. Upgrade to unlock cloud issues.
  • offline — the companion can't reach InSitue Cloud. Check your connection; the widget retries automatically.

Production mode (cloud sink → autopilot → draft PR)

Pass your publishable projectKey (e.g. pk_…). The key is Origin-pinned and quota-gated server-side, so it's safe to ship in a public bundle.

<InSitueCapture projectKey={process.env.NEXT_PUBLIC_INSITUE_KEY!} />

End users see a friendly "Report a problem" pill in the corner of your app. Clicking it activates the picker; describing + sending submits to your InSitue inbox.


Props

interface InSitueCaptureProps {
  /** Publishable project key. Set → cloud sink. */
  projectKey?: string;
  /** Override the cloud ingest endpoint. */
  endpoint?: string;
  /** Take over delivery yourself. Wins over both projectKey
   *  and sink. */
  onCapture?: (draft: IssueDraft, bundle: CaptureBundle) => void;
  /** Explicit sink override (rarely needed — most callers rely
   *  on auto-detection). */
  sink?: CaptureSink;
  /** Force getDisplayMedia capture from mount. Dev/dogfood only. */
  defaultPixelPerfect?: boolean;
}

Sink auto-detection

| projectKey | sink | Result | |---|---|---| | set | unset | Cloud sink (post to InSitue Cloud) | | unset | unset | Companion sink (post to local WS, default port 5747) | | any | set | Use sink verbatim |

onCapture wins over everything when defined.


Bulletproof selection

Every pick the widget submits has a usable source location. The picker walks React fiber _debugSource first (exact), then the data-insitue-source attribute injected by @insitue/sdk/babel (exact), then the nearest owning component's source (approximate). If even that fails, the widget refuses to send and asks the user to pick a parent — claude never gets a meaningless selector-only pick.

The confidence chip is shown inline so users (and you, in testing) can see exactly what's been resolved before they hit Send.

Source attribution

In production builds React strips its component-debugger metadata, so without an explicit source attribute the picker can only ship a CSS selector + DOM snapshot — and the cloud agent has to guess which file to edit. Confidence drops below the resolution threshold and the report routes to a human instead of auto-opening a draft PR.

A source-attribution plugin fixes this by stamping data-insitue-source="file:line:col" onto every JSX element at compile time. Two interchangeable plugins produce the identical attribute:

SWC plugin — recommended on Next.js ≥ 16.1. Fastest builds (keeps Next's SWC compiler). See @insitue/swc-source-attr:

pnpm add -D @insitue/swc-source-attr@next16
// next.config.mjs
const nextConfig = {
  experimental: {
    swcPlugins: [["@insitue/swc-source-attr", { rootDir: process.cwd() }]],
  },
};
export default nextConfig;

Run npx @insitue/swc-source-attr doctor to confirm the right dist-tag for your Next version.

Babel plugin (the universal fallback)

@insitue/sdk/babel works on any Next.js version and any bundler (Vite, Webpack, older Next) and produces the identical data-insitue-source output as the SWC plugin — capture confidence is exactly the same. The cost: adding a Babel config opts your project out of Next's SWC compiler, which makes builds noticeably slower. Prefer the SWC plugin on Next ≥ 16.1; use Babel when you're on an older Next, can't upgrade, or use a non-SWC bundler.

Next.js — add a .babelrc (this is what switches Next from SWC to Babel):

{
  "presets": ["next/babel"],
  "plugins": [["@insitue/sdk/babel", { "root": "." }]]
}

Vite — wire it through the React plugin's Babel options:

// vite.config.ts
import insitueBabel from "@insitue/sdk/babel";

export default {
  plugins: [
    react({
      babel: {
        plugins: [[insitueBabel, { root: __dirname }]],
      },
    }),
  ],
};

The root must match the project directory the companion is scoped to (typically __dirname of the config file). The plugin is idempotent — safe to run alongside the SWC plugin during a migration.


What's in a capture

Every send produces a CaptureBundle:

interface CaptureBundle {
  id: string;                      // unique per capture
  target: { source, confidence, selector, componentStack };
  screenshot?: { dataUrl, source: "rasterise" | "display-media" };
  computedStyles: Record<string, string>;
  tailwindClasses: string[];
  userNote?: string;               // the user's description
  runtime: { url, route, console, network, errors };
  viewport: { w, h, dpr, breakpoint };
}

Cloud sink: this goes to https://www.insitue.com/api/v1/capture with your projectKey. Companion sink: it goes to ws://127.0.0.1:5747 (the local companion's loopback WS) which broadcasts to subscribed CLI/MCP listeners.

The SDK also sends a lightweight heartbeat that reports sdkVersion and hostNextVersion to InSitue Cloud. This is advisory telemetry only — it is never used to gate or reject captures.


Going to production

The same <InSitueCapture /> works in both modes — just pass projectKey in production and your users get the SaaS theme (warm, friendly) instead of the dev theme (dark, terminal-flavour). A typical setup:

const PROJECT_KEY = process.env.NEXT_PUBLIC_INSITUE_KEY;
const IS_PROD = process.env.NODE_ENV === "production";

export default function InSitueWidget() {
  if (IS_PROD && !PROJECT_KEY) return null;
  return IS_PROD ? <InSitueCapture projectKey={PROJECT_KEY} /> : <InSitueCapture />;
}

Then drop <InSitueWidget /> once in your app root.


Public API

The package ships three entry points:

@insitue/sdk (default)

  • <InSitueCapture /> — the canonical widget. Auto-detects sink (cloud when projectKey set, otherwise companion).
  • <InSitue /> — backward-compat dev alias for the companion sink. Equivalent to <InSitueCapture sink={{ kind: "companion", port }} />.
  • InSitueCaptureProps, InSitueProps — prop types.
  • SDK_VERSION: string — build-time-inlined package version. Surfaced in the widget footer so a screenshot proves the build.

@insitue/sdk/capture-only

  • mountCaptureOnly(opts): () => void — imperative mount for non-React apps (vanilla / Svelte / Vue). Returns a dispose function.
  • CaptureOnlyOptions — full options shape (sink, projectKey, endpoint, onCapture, defaultPixelPerfect).
  • CaptureSink — the sink discriminated union the SDK accepts.

@insitue/sdk/babel

  • Default export — the Babel plugin that injects data-insitue-source="file:line:col" onto intrinsic JSX elements. Optional; only needed when your bundler doesn't expose React fiber _debugSource (Vite, some Webpack setups).

The bundle ships with React fiber resolution as the primary source resolver, falling back to the build-injected attribute, falling back to the nearest owning component. The selector is always present as the last-resort locator.

Stability

The widget API (<InSitueCapture /> props, mountCaptureOnly options) is the stable consumer surface. Internal modules (capture.ts, picker.ts, client.ts) are not — import paths under @insitue/sdk/* other than the three documented entry points may change at any time.

The pre-0.3.0 chat-style overlay is removed; if you imported <InSitue /> for that, the new behaviour is the unified capture widget in companion-sink mode. No separate session history, no in-overlay diff.

Versioning

  • Major — backwards-incompatible widget prop changes, removed exports, changes to the auto-detection rules (e.g. a new prop precedence), bundle-shape changes that need a CAPTURE_SCHEMA_VERSION bump in @insitue/capture-core.
  • Minor — additive props, additive options, new exports, new sink kinds, new optional features (e.g. defaultPixelPerfect).
  • Patch — bug fixes, browser-quirk workarounds, docs, internal refactors, dep-bumps for transitive deps.

The SDK pins its CAPTURE_SCHEMA_VERSION and PROTOCOL_VERSION against the companion. A mismatch is rejected at the WS handshake rather than silently degraded.

Security

Report vulnerabilities privately — see SECURITY.md in the repo root. Especially relevant for this package: anything that lets the widget submit captures from a non-host origin, that leaks the projectKey outside its Origin pin, or that lets a host-page script read the Shadow DOM overlay's internal state.

The cloud sink ships projectKey (publishable, Origin-pinned, quota-gated). The companion sink connects loopback-only and authenticates via a per-session token written to <project>/.insitue/session.json by the companion at bind time.

Tests

The package has a small unit suite covering bundle building, a Next/Image-specific regression, and a "don't render layer 2" DOM check.

pnpm test            # one-shot
pnpm test:watch      # watch mode

Full integration coverage lives in @insitue/companion's trust-boundary tests and the cloud-side autopilot suite (closed- source). If you make a change here that touches the SDK ↔ companion contract, run the companion's tests too.

License

MIT. See LICENSE.