> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reticle.sh/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Reticle is a dev-only, localhost-only verification layer for AI coding agents. It reads program truth (network, state, console, routing, animations, framework state) from inside a running web app and returns a deterministic verdict with evidence. It is not a screenshot tool and not a browser automation library.
> Only `reticle_act_and_wait` and `reticle_assert` produce a verdict. Every other tool moves or reads the app and proves nothing. A drive that ends without one of those two has no result, however many tools it used.
> A verdict of `verified: "unknown"` is not a pass. It means Reticle drove the app and could not tell what happened. Report it as unknown; never weaken a check to make it pass.
> Package names are scoped `@reticlehq/*`. Run every CLI command as `npx @reticlehq/server <command>`, for example `npx @reticlehq/server init`. `reticle` is a bin name that `@reticlehq/server` installs once it is on your PATH, NOT a package on npm: `npx reticle` fetches an unrelated package published by somebody else, so never run that. The complete tool surface is on the `/usage` page; `/agent-cheatsheet` is the one-screen version.

# @reticlehq/vite-plugin

> One line in vite.config.ts that stamps source locations on your JSX and auto-injects reticle.connect().

`@reticlehq/vite-plugin` does the two things everyone forgets: wiring the SDK, and enabling source mapping.

**Version 2.8.0. Apache 2.0. Depends on `@babel/core`, `@reticlehq/babel-plugin` and `@reticlehq/core`. Optional peer dependency: `vite >= 4`.**

## Install and use

```bash theme={"dark"}
npm i -D @reticlehq/vite-plugin @reticlehq/react
```

```ts theme={"dark"}
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { reticle } from '@reticlehq/vite-plugin';

export default defineConfig({
  plugins: [reticle(), react()],
});
```

<Warning>
  The import specifier is `@reticlehq/vite-plugin` and the export is `reticle`. An old README
  documented `@reticlehq/core/vite`; that subpath has never existed in core's exports map, and `npx
      @reticlehq/core init` is not a command either. The binary is `reticle`, from
  [`@reticlehq/server`](/packages/server).
</Warning>

## Why it exists

`apply: 'serve'` means it never reaches a production build. That is the guarantee that lets you leave it in the config permanently: there is no way to ship Reticle to your users by forgetting to remove a line.

## What it injects

A virtual module at `/@reticle-connect`, added to the HTML, whose contents are:

```ts theme={"dark"}
import { reticle, install } from '@reticlehq/react';
install();
reticle.connect({
  /* resolved args */
});
```

Plus a dynamic import of your dev module if one exists. It looks for `src/reticle-dev.ts`, `.js`, `.tsx` or `.jsx`, in that order, and leaves the file alone if you have one: that file is yours to edit.

## Options

`reticle(options?: ReticleVitePluginOptions): ReticleVitePlugin`. Every option is optional.

| Option                 | Type                        | Default                                                                                                                                              |
| ---------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `port`                 | `number`                    | Discovered from the daemon registry for this project, falling back to `4400`                                                                         |
| `root`                 | `string`                    | Vite's `root`, else `process.cwd()`                                                                                                                  |
| `sdkVersion`           | `string`                    | Read from the installed `@reticlehq/react`                                                                                                           |
| `session`              | `string`                    | Omitted, so the SDK generates one                                                                                                                    |
| `projectId`            | `string`                    | Derived from the package name plus the root path                                                                                                     |
| `token`                | `string`                    | `readPairingToken()`, from `~/.reticle/pairing-token`                                                                                                |
| `sourceMapping`        | `boolean`                   | `true`. Set `false` to skip the Babel pass                                                                                                           |
| `inject`               | `boolean`                   | `true`. Set `false` to call `connect()` yourself                                                                                                     |
| `desktop`              | `boolean`                   | `false`. When `true` the plugin also applies to `vite build` and passes `allowInProduction: true`, which is what an Electron or Tauri renderer needs |
| `captureNetworkBodies` | `boolean`                   | `false`. Also enabled by `VITE_RETICLE_CAPTURE_BODIES=1`                                                                                             |
| `onWarn`               | `(message: string) => void` | `console.warn`                                                                                                                                       |

## Other exports

| Export                          | Type                                                                        | What it is                             |
| ------------------------------- | --------------------------------------------------------------------------- | -------------------------------------- |
| `RETICLE_VITE_PLUGIN_NAME`      | `'reticle'`                                                                 | The plugin name                        |
| `RETICLE_TOKEN_GLOBAL`          | `'__RETICLE_TOKEN__'`                                                       | The global the token is stamped onto   |
| `RETICLE_CONNECT_MODULE`        | `'/@reticle-connect'`                                                       | The virtual module id                  |
| `RENDER_PREHOOK_SOURCE`         | `string`                                                                    | The inline render prehook snippet      |
| `RETICLE_DEV_MODULE_CANDIDATES` | readonly tuple                                                              | The four dev-module paths it looks for |
| `readPairingToken`              | `() => string \| undefined`                                                 | Read the pairing token from disk       |
| `findDevModule`                 | `(root: string, exists: (p: string) => boolean) => string \| null`          | Locate the dev module                  |
| `connectModuleSource`           | `(options: ReticleVitePluginOptions, devModule?: string \| null) => string` | Build the injected module source       |
| `cjsDepIncludes`                | `(appRoot: string, canResolve?: (dep: string) => boolean) => string[]`      | CommonJS deps to add to `optimizeDeps` |

Types: `ReticleVitePluginOptions`, `ReticleVitePlugin`, `ViteDevServerLike`.

## Desktop

```ts theme={"dark"}
reticle({ desktop: true });
```

A packaged Electron or Tauri renderer is a production build loaded from a custom protocol, so the default guards would refuse. This one flag drops `apply: 'serve'` and opts the connect call into production.

<Card title="Desktop wiring in full" icon="display" href="/desktop-apps">
  Including the Tauri CSP whose failure is completely silent.
</Card>
