Skip to content
| Marketplace
Sign in
Visual Studio Code>Linters>aiwatch — AI chat visibility & guardrailsNew to Visual Studio Code? Get it now.
aiwatch — AI chat visibility & guardrails

aiwatch — AI chat visibility & guardrails

Ratnadeep Dey Roy

|
2 installs
| (0) | Free
Local-first visibility and policy guardrails for VSCode Copilot, Cursor, and Claude Code.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

aiwatch

Local-first visibility and policy guardrails for AI coding assistants.

aiwatch records every chat your VSCode/Cursor/Claude Code AI sends, applies your policy rules (regex, file-glob, AST, optional local LLM classifier), and blocks matching prompts to Claude Code before they leave your machine. All data stays on disk, encrypted with a key in your OS keychain (or a passphrase you choose).

Status: v0.3.0. Single architecture-independent .vsix: no native binaries, so the same package runs on macOS, Linux and Windows, x64 and arm64, against any Electron ABI VSCode ships.

Hosts

Host Visibility Enforcement before send
Claude Code ✅ ✅ block prompts, block or rewrite tool calls, via the official hooks
Cursor ✅ (polls its SQLite chat store) ❌ audit-only — no pre-send middleware exists
VSCode Copilot Chat ⚠️ only @aiwatch prompts ❌ audit-only — no pre-send API exists

What enforcement means, precisely. Claude Code exposes two hooks aiwatch uses, and they have different powers (docs):

On your prompt (UserPromptSubmit) — the hook can allow or refuse, but the API has no way to rewrite prompt text:

  • block → the prompt is refused and erased before it is sent. ✅
  • redact / encrypt-placeholder → also blocked, with a message naming the rule. Letting the prompt through would send exactly the secret the rule redacts, so aiwatch fails closed and asks you to edit the prompt. The redacted version is shown in the panel.
  • warn-and-allow → sent, with the warning attached as context.
  • log-only → sent, recorded silently.

On a tool call Claude makes (PreToolUse) — the hook can replace the tool's arguments outright, so here redaction really redacts:

  • block → the call never runs. ✅
  • redact / encrypt-placeholder → the matching span is rewritten in place and the call proceeds with the secret removed; you are told what was changed. ✅
  • warn-and-allow → runs, with the warning attached as context.

This covers the calls that actually move data off the machine — WebFetch, WebSearch, and Bash running curl or git push. A key in a curl -H "Authorization: …" is stripped rather than merely refused.

On Cursor and Copilot every action degrades to a recorded hit plus a toast: the prompt has already left by the time the adapter sees it.

What each host actually captures

  • Claude Code — everything, once you install the hooks (the panel offers a button, and aiwatch asks once on startup). Without them nothing is captured and nothing is blocked.
  • Cursor — aiwatch re-reads Cursor's SQLite chat store on startup and every 60 seconds, because Cursor exposes no API and emits no events. Chats appear shortly after Cursor writes them, not instantly. If Cursor changes its storage layout, capture stops and the panel says so rather than failing quietly.
  • Copilot Chat — only prompts you address to @aiwatch. VS Code gives extensions no way to observe ordinary Copilot requests, so normal Copilot use is invisible to aiwatch, and to any other extension.

Quick start

  1. Install from VSCode Marketplace (or build from source — see BUILD.md).
  2. Open the command palette → aiwatch: Open Panel.
  3. Run the onboarding wizard — pick how the encryption key is stored.
  4. (Claude Code only) press Install Claude Code hooks in the panel, or run the command of the same name. aiwatch also offers this once on startup. This writes signed stub scripts to ~/.claude/hooks/ and registers them in ~/.claude/settings.json, merging with any hooks you already have.
  5. Open the Policy tab and write your policy.yaml, or install a community rule pack via the panel.

The panel's status strip tells you, per host, whether capture is actually running — and if not, which button fixes it.

Example policy

version: 1
rules:
  - id: no-aws-keys
    detect: { regex: 'AKIA[0-9A-Z]{16}' }
    action: block
    severity: high

  - id: redact-customers
    detect: { regex: 'cust_[a-z0-9]{6,}' }
    action: redact
    placeholder: '[CUST]'

  - id: no-billing-src
    detect: { path_glob: 'src/billing/**' }
    action: block
    severity: high

  - id: warn-emails
    detect: { regex: '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}' }
    action: warn-and-allow

Save → the next prompt to Claude Code is checked against these rules.

Architecture

TL;DR:

  • Single VSCode extension, no daemon. Webview UI inside the IDE.
  • Storage: libsodium secretstream envelopes (XChaCha20-Poly1305) over JSON.
  • Key: VS Code SecretStorage by default, passphrase (argon2id 64MiB / 3 iter) optional.
  • Loopback HTTP server on 127.0.0.1:<random> with rotating 32-byte token for Claude Code hooks.
  • Regex vetted by SafeRegex: patterns that can backtrack catastrophically are rejected at load time, and every match runs under a time budget.
  • Cursor's SQLite history is read through sql.js (WebAssembly, read-only copy in memory — Cursor's own database is never opened for writing or locked), polled on a timer with an mtime filter, and de-duplicated per turn so re-reads are free.
  • Captured turns are buffered briefly and written as a batch, so recording a prompt costs the same whether the conversation has ten turns or a thousand.
  • Rule packs: declarative-only schema, SHA-256 pinned, never eval.

Data inventory & retention

What Where Encrypted Default retention
Chat turns + context file metadata ~/.aiwatch/global/<workspace-hash>/sessions/ or <repo>/.aiwatch/sessions/ yes 30 days
Search index index.enc beside the sessions yes rebuilt on demand
Audit log (policy hits, key-mode changes, hook installs) ~/.aiwatch/audit.log.enc yes 1 year
encrypt-placeholder mappings per-session, beside the session file yes 24 h unless pinned
Hook token / current port ~/.aiwatch/hook.token, ~/.aiwatch/port (mode 0600) no (rotates per IDE start) session
Config (key custody mode, rule-pack pins) ~/.aiwatch/config.json no (contains no secrets) until removed

aiwatch: Uninstall (cleanup hooks & data) removes the Claude Code hook stubs, the ~/.claude/settings.json entries aiwatch added, and — with an explicit confirmation — ~/.aiwatch/ itself.

Security

See SECURITY.md (threat model + reporting). The short version:

  • Bound to 127.0.0.1 only; constant-time token compare; DNS-rebind defended.
  • Webview has strict CSP, no inline scripts, no remote loads, DOMPurify for any markdown.
  • No telemetry. No crash reporting. No phone-home. SBOM ships with each release.

Privacy

See PRIVACY.md. Nothing leaves your machine by default. The only network calls are:

  • Rule-pack updates (only with explicit URL + SHA-256 pin).
  • Ollama (only if you enable the LLM classifier; hardcoded to localhost; remote requires explicit toggle).

Development

npm ci
npm run build       # builds dist/extension.js + dist/webview/ + dist/sql-wasm.wasm
npm run verify      # typecheck + tests (incl. security corpora) + prod npm audit
npm run package     # aiwatch-<version>.vsix

npm run release:artifacts runs the gates and produces the .vsix, the CycloneDX SBOM, and RELEASE-MANIFEST.txt (source→bundle SHA mapping — see BUILD.md).

Then open in VSCode, press F5 to launch an Extension Development Host.

License

MIT. See LICENSE.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft