{"_id":"@boundedhq/beagle","name":"@boundedhq/beagle","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@boundedhq/beagle","version":"0.1.0","description":"Local transparency proxy for AI agents — see what they send, catch leaked secrets.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/boundedhq/beagle.git"},"homepage":"https://github.com/boundedhq/beagle","bin":{"beagle":"bin/beagle.cjs"},"optionalDependencies":{"@boundedhq/beagle-darwin-arm64":"0.1.0","@boundedhq/beagle-darwin-x64":"0.1.0","@boundedhq/beagle-linux-x64":"0.1.0","@boundedhq/beagle-linux-arm64":"0.1.0"},"engines":{"node":">=18"},"_id":"@boundedhq/beagle@0.1.0","gitHead":"219a3bdbd9cecf2a24bd6a5a4df78dd1848bce64","bugs":{"url":"https://github.com/boundedhq/beagle/issues"},"_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-bADJ8s0XmjCDRJVRWct6LVv3H4oDIzqJgzOREnnyAYBX+86yzfX4s6aE+13nUWz5A8z9O37oyZg7nwXof8YWeA==","shasum":"b52ef5786d16454a9a61b9fe6d155672d04df142","tarball":"https://registry.npmjs.org/@boundedhq/beagle/-/beagle-0.1.0.tgz","fileCount":4,"unpackedSize":30132,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@boundedhq%2fbeagle@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICMa/aDKsrOwr75asEenCdvjZlSuUFNNxafmjUittR6sAiAapqyG4qY5ZmEbVeA2BV/6jH1JOKWjS9/fdz7nzNDB+w=="}]},"_npmUser":{"name":"boundedhq","email":"pupuvegetable@gmail.com"},"directories":{},"maintainers":[{"name":"boundedhq","email":"pupuvegetable@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/beagle_0.1.0_1784786169236_0.5060316806947964"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-23T05:56:09.083Z","0.1.0":"2026-07-23T05:56:09.372Z","modified":"2026-07-23T05:56:09.815Z"},"maintainers":[{"name":"boundedhq","email":"pupuvegetable@gmail.com"}],"description":"Local transparency proxy for AI agents — see what they send, catch leaked secrets.","homepage":"https://github.com/boundedhq/beagle","repository":{"type":"git","url":"git+https://github.com/boundedhq/beagle.git"},"bugs":{"url":"https://github.com/boundedhq/beagle/issues"},"license":"MIT","readme":"# <img src=\"docs/assets/beagle.svg\" alt=\"\" width=\"38\" align=\"top\"> Beagle\n\n[![CI](https://github.com/boundedhq/beagle/actions/workflows/ci.yml/badge.svg)](https://github.com/boundedhq/beagle/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n**See what your AI agents actually send to model providers — and get alerted\nwhen a secret goes with it.**\n\nAI agents read your files, your shell output, your git history — and ship\nchunks of all of it to a model provider on every turn. Today that traffic is\ninvisible: you can't see what left, you can't search it, and if your AWS secret\nkey went with it, nobody tells you. Beagle is a local transparency proxy that\nmakes that traffic visible, searchable, and scanned for secrets — in one command,\nwithout changing your setup.\n\n![The Beagle dashboard: a live feed of every model call — what was asked, what came back — with leaks flagged in red](docs/assets/dashboard.png)\n\n## Quick start\n\nInstall, then let Beagle find your agents and tell you exactly what to run:\n\n```sh\nnpm install -g @boundedhq/beagle   # single self-contained binary — more options under Install\nbeagle detect\n```\n\n```\nFound 4 supported agents — to capture one session, run the command shown:\n\n  claude    → beagle run claude\n              signed in with a subscription — captured via the agent's own usage report\n  codex     → beagle run codex\n              signed in with a subscription — captured via the agent's own usage report\n  opencode  → beagle run opencode\n              captured on the wire, full fidelity\n  pi        → beagle run pi\n              captured on the wire, full fidelity\n\nTo capture every session automatically:  beagle watch <agent>\n```\n\nThat's this machine — Claude Code and Codex happen to be signed in with a\nsubscription here; yours may say *\"captured on the wire\"* instead (the\ndifference is explained under **Capture modes**). Either way, you run the\nexact command it prints.\n\nIf Beagle finds local evidence of another recognized agent it cannot capture\nyet, `detect` lists it separately with a link to the\n[agent-support vote](https://github.com/boundedhq/beagle/issues/154). Detection\nonly checks your local PATH and known application or configuration directories;\nit sends nothing anywhere.\n\nDesktop applications are reported separately from same-named CLIs: finding\nClaude Desktop or the Codex app does not imply their sessions are captured.\n\nWant to see Beagle fire before trusting it with an agent? Run:\n\n```sh\nbeagle demo\n```\n\nThe demo generates a synthetic AWS-secret-shaped canary, asks a mock agent to\nfind the project's AWS secret access key, and lets the agent choose to read the\nlocal `.env` file. The tool result travels through Beagle's normal daemon,\nproxy, capture, scanner, alert, and storage path. Its provider is an in-process\nmock bound to `127.0.0.1`; if that mock cannot bind, the demo aborts before\ncontacting the daemon. It needs no agent, account, or API key and opens no\nexternal connection.\n\nWhen desktop notifications are available, the normal OS notification fires;\nthe captured drill is saved with a `[demo]` badge, and the dashboard opens\ndirectly to its session. On Linux, notification banners use `notify-send`.\nDemo drills stay out of the dashboard's real-leak total. Run `beagle demo`\nagain to test notification delivery again, `beagle demo --clean` to remove\nevery demo session, or the normal `beagle purge` to erase all captured data\nincluding drills.\n\nWant to see the same alert during a real agent session? This paste-ready canary\nis a fixed synthetic value with the shape of an AWS secret access key and no\npaired access key ID, so it cannot authenticate\n([AWS access-key documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)):\n\n```sh\nmkdir -p /tmp/beagle-canary\nCANARY='wJa1rXUtnF3MI4K7MDENGbPxRf9CYZ8qLm2Vt0Bn'\nprintf 'AWS_SECRET_ACCESS_KEY=%s\\n' \"$CANARY\" > /tmp/beagle-canary/.env\nbeagle run claude        # or codex / opencode / pi\n# then ask: \"read /tmp/beagle-canary/.env and tell me what's in it\"\n```\n\nThe moment the agent sends that file's contents upstream, Beagle notifies you;\n`beagle leaks` records the event and the dashboard highlights where it left.\nFor telemetry-captured agents the alert can lag a few seconds because Beagle\nscans the agent's report, including captured tool output. Never test with real\nkeys. Clean up the file afterward with `rm -r /tmp/beagle-canary`.\n\nAWS's familiar documentation example ends in `EXAMPLE`; Beagle intentionally\nsuppresses obvious example/placeholder values, so the synthetic canary above\nis what exercises the detector.\n\n`beagle run` wraps **one** session. It touches none of *your* files or\nconfig — captures land in Beagle's own store (`~/.local/state/beagle`), and\nthe only background component it starts is a local capture daemon that\nidle-exits when unused.\n\nEvery model call is captured locally, and every captured call is scanned.\nIf a secret goes out you get an OS notification — dashboard open or not,\nand one per distinct secret, not one per call, even as the agent re-sends\nits history every turn. Afterwards:\n\n```console\n$ beagle leaks             # did anything leak? every call was already scanned\n1 leak event across 1 session — newest first:\n\n  Fix the deploy script — opencode · session 01KXAK6K2P\n      Jul 17 at 11:57 PM   AWS secret key → anthropic   ×1   call 01KXT07ZKK7RB6Y12N51Y8NNJX\n\n$ beagle ui                # or browse it all in the dashboard — leaks highlighted inline\n```\n\n## More than a leak detector\n\nCatching secrets is the headline, but the record Beagle keeps answers the\nquestions you ask while *building* with agents. (Everything below describes\nwire capture, the full-fidelity mode; subscription-login sessions are the\nagent's own report — see **Capture modes**.)\n\n- **What system prompt actually went out?** Open any session — the transcript\n  starts with the system prompt as captured, then every request and response\n  in order.\n- **What tools does the model see?** A call's raw view holds the complete\n  captured request — including the full `tools` array, names, descriptions,\n  and JSON schemas — as foldable JSON.\n- **What's new this turn vs. re-sent history?** Transcripts show each turn's\n  delta instead of re-printing the whole conversation; each call gets a\n  one-line \"what this turn did\" summary and records tokens in/out whenever\n  the provider reports usage — usually enough to answer \"why was that turn\n  50k tokens?\"\n- **What came back?** Responses reassembled from the stream: the model's\n  text, then its tool calls, each in the order emitted.\n- **Did that internal hostname ever leave?** `beagle search` checks every\n  call still in the local store — for strings no detector could know about.\n  A hit is definitive proof it was sent; \"no matches\" is bounded by the\n  retention window (7 days of payloads by default).\n\n![A captured session: the system prompt, each request and response, tool calls with their inputs — and a leaked AWS key, masked at capture, highlighted at the exact spot it left](docs/assets/transcript.png)\n\nIf you build agents, Beagle doubles as a context debugger: develop under\n`beagle run`, then read what the model actually saw. (In the shot above,\n`redact-on-capture` — the default — masked the key before it was ever\nwritten to disk; turn it off if you want Beagle's copy byte-exact.)\n\n## Capture modes\n\nThe command is the same for every agent — `beagle run <agent>` for one\nsession, `beagle watch <agent>` for always-on. What changes is *how* Beagle\ncaptures, and it picks that automatically from how the agent is signed in:\n\n| Your agent | Signed in with | What happens |\n|---|---|---|\n| **Claude Code** | Anthropic API key | wire capture — full fidelity |\n| **Claude Code** | Claude.ai subscription (Pro/Max) | telemetry capture, auto-detected |\n| **Codex** | OpenAI API key | wire capture — full fidelity |\n| **Codex** | \"Sign in with ChatGPT\" | telemetry capture, auto-detected |\n| **opencode** | API key **or** ChatGPT sign-in | wire capture — full fidelity |\n| **pi** | API key **or** ChatGPT sign-in | wire capture — full fidelity |\n\nIf Beagle can't tell how an agent is signed in, it asks once at the terminal\nand remembers your answer (`beagle config run-mode <agent> wire|telemetry|auto`\nto change it; `--wire` / `--telemetry` force a mode for one run). And if a\nwrong guess ever slips through, Beagle warns you when a session ends with\nnothing captured — and tells you which mode to force.\n\n**What's telemetry capture?** Two agents can't be wire-redirected when signed\nin with a subscription: Codex's ChatGPT login is locked to its built-in\nprovider (the endpoint override Beagle uses for API-key Codex doesn't reach\nit), and Anthropic restricts Claude.ai subscription OAuth to its official\nclient. So for those two, Beagle captures sessions from the agent's own\nusage reporting instead. Your prompts, tool inputs, and tool outputs (including\nfiles the agent reads) are still scanned and searchable — but it's the agent's\nself-report, not observed wire bytes. Those rows are badged **self-reported** in the\ndashboard (wire rows say **observed**), and alerts can lag a few seconds.\nNothing leaves your machine: the report goes to a loopback receiver on\n`127.0.0.1`, and the vendor's reporting flags are set per run, never written\nto your agent's config. One footnote: if your agent already exports telemetry\nto a company collector, that export is redirected to Beagle for the duration\nof the run — your collector won't receive events from that session.\n(opencode's and pi's ChatGPT sign-ins need none of this — their traffic\nproxies normally at full fidelity.)\n\n**And telemetry sessions still read like conversations.** The vendors' exports\narrive scattered — one event per tool execution, and Codex's omits the\nassistant's reply entirely — but the dashboard sequences them with the same\nrequest/response pattern as a wire-captured Pi session: a model response asks\nfor a tool, and the next request carries that tool's result. The final answer\nappears after the final result (for Codex, it is recovered from the session log\nCodex itself writes and arrives a beat later). Every captured telemetry row\nalso remains in the calls feed, so a live tool row never disappears after a\nrefresh; reconstructed cards link back to that row's raw detail.\n\nThis sequencing is a display projection and fails open: rollout links provide\nCodex's tool order, Claude hook ids keep results within their user prompt, and\nan event that cannot be placed stays standalone. Codex reports each execution\ntwice — a harness step and the inner tool — so both appear, as they do in\nCodex's own UI. The underlying rows remain independently captured, scanned,\nredacted, and searchable. The one gap wire capture doesn't have: Codex encrypts\nits reasoning, so what the model was thinking between tools is the one thing a\ntelemetry transcript can't show.\n\n## Always-on (`beagle watch`)\n\n`beagle watch <agent>` makes that agent captured on every run, not just ones\nyou remember to wrap. It shows you each change — the exact shim path, service\ndefinition, and rc line — and asks `y/N` before making it:\n\n- a **PATH shim** for that agent,\n- a **background service** so coverage survives reboots,\n- and — only if the shim isn't already winning your PATH — one **guarded\n  block** in your shell rc (`~/.zshrc` / `~/.bash_profile` / `config.fish`),\n  with an offer to refresh your current shell so coverage is live right away.\n\nEvery change is marker-owned and recorded; `beagle unwatch` (name an agent,\npick from a list, or `--all`) reverts them all.\n\n## How it works (and what it is *not*)\n\nIn wire-capture mode, `beagle run` starts a loopback proxy and points the agent\nat it for that run — via `ANTHROPIC_BASE_URL` for Claude Code, via a per-run\nprovider override for Codex, via a temporary merged config file for opencode,\nand via a one-run `-e` extension for pi. Your real config files are never\nmodified, and anything Beagle generates is deleted when the run ends. The agent\ntalks to `127.0.0.1`; Beagle streams the bytes to the real provider unmodified\nand unbuffered (SSE reaches your agent immediately) and keeps a copy locally:\n\n```\nagent ──HTTP──▶ beagle (127.0.0.1) ──HTTPS──▶ api.anthropic.com\n                   │\n                   ├─ scan outbound body for secrets → alert\n                   └─ store request/response locally (SQLite, 0600)\n```\n\nWhat Beagle is **not**:\n\n- **Not a TLS man-in-the-middle.** No CA certificate is installed, no TLS is\n  intercepted, no system proxy is configured. If an app doesn't honor the\n  redirect, its traffic simply doesn't route through Beagle — it can't\n  silently observe anything else. (That's also why desktop apps, IDE\n  extensions, and web UIs aren't covered in v1 — they launch their own\n  processes. `beagle status` always tells you exactly what is and isn't\n  covered.)\n- **Not a cloud service.** No account, no server, no phone-home — Beagle\n  itself sends nothing anywhere.\n- **Not a blocker.** v1 observes and alerts; a finding never causes Beagle to\n  rewrite or drop agent traffic. (An optional setting censors detected secrets\n  in *Beagle's own local records* — that changes what Beagle keeps, never what\n  goes over the wire.)\n\n## Commands\n\n```sh\nbeagle detect              # find supported agents and recognized coverage gaps\nbeagle demo                # run a local drill, save it as [demo], open dashboard\nbeagle demo --clean        # remove saved demo sessions\nbeagle run <agent>         # capture one session; your agent config stays untouched\nbeagle watch <agent>       # make that agent always-on (guided; asks before each change)\nbeagle unwatch [<agent>]   # stop watching; restores your setup\n                           # (no agent: pick from a list; --all for everything)\nbeagle status              # trust strip: coverage, store size, retention, changes\nbeagle leaks               # the leak log — every detected secret, deduped\nbeagle search [string]     # was this string sent? searches the local store\n                           # (no arg → reads stdin, keeps it out of history)\nbeagle show <id>           # one captured call, summarized\nbeagle ui                  # open the dashboard (loopback, one-time link)\nbeagle purge [all|panic]   # erase captured data (panic = zero records in place)\nbeagle stop                # stop the daemon; pause always-on until next watch\nbeagle uninstall           # remove everything Beagle installed (see Uninstall)\nbeagle config [...]        # redact-on-capture, exclusions, per-agent run-mode\n```\n\n`beagle help` lists them all. The whole loop works headless — a skeptic never\nhas to start the viewer.\n\n## Budgets (published, enforced in CI)\n\nTrust needs numbers, not adjectives:\n\n| Budget | Design target | CI gate |\n|---|---|---|\n| Dependency-free runtime core | ≤ 2,000 LOC | `bun run loc:check` fails the build over budget |\n| Capture-to-alert trust path (the core counts inside this, not on top of it) | ≤ 5,000 LOC | `bun run loc:check` fails over budget, or if a manifest file goes missing |\n| Scan time, 1 MB body | p99 ~10 ms | `tests/budget.test.ts` (median < 50 ms ceiling for CI variance); pathological inputs are bounded separately by per-rule/probe caps and the scan worker's 500 ms deadline |\n| Added request latency | p50 ≤ 5 ms | `tests/budget.test.ts` (< 25 ms ceiling for CI variance) |\n| Install size | ≤ 100 MB | CI binary-size check |\n\nScanner resource bounds fail safe: reaching a finding cap, exhausting the\ndecode-probe budget, or exceeding the worker deadline marks the exchange\n`incomplete`; with default redaction, unverified content is withheld rather\nthan stored under a clean verdict.\n\nZero third-party runtime dependencies in the core; `bun:*` imports confined\nto `src/adapters/`; the viewer's Preact+htm is vendored and pinned. `src/core/`\nis that portability boundary, not the whole security audit scope. The wider\ncapture-to-alert trust path is declared explicitly in\n[`TRUST_PATH_SCOPE`](scripts/loc-report.ts): core interception, scanning,\nalerting, and persistence plus daemon ingestion, telemetry/format parsers,\nredact-on-capture, scanner hosting, rollout capture, SQLite adaptation, and\nalert delivery, plus the demo's loopback-only/fail-closed orchestration.\n`bun run loc` labels both `CORE` and non-core `TRUST` files;\nthe core is counted once inside the trust-path total (the two budgets are\nnested, not additive). This is a legibility gate, not a claim that code\noutside the manifest needs no security review: the viewer's read-time\nrendering (which chooses the redacted projection over re-deriving the raw\nbody), plus CLI orchestration and installation, remain reviewed and visible\nin the total LOC report though outside the budgeted manifest.\n\n## Trust properties\n\n- **Local only.** The only outbound connections are the ones your agent was\n  already making, forwarded verbatim.\n- **Your setup, untouched.** `beagle run` does not modify your agent config.\n  `beagle watch`\n  asks before each change, records every one in a manifest, and reverts them\n  all on `unwatch`/uninstall — see **Always-on** above for exactly what it\n  touches.\n- **Your API key never rests.** Auth headers are scrubbed before anything\n  is written; the credential exists only in memory, in flight.\n- **The store is the liability, minimized.** `0600` files, 7-day rolling\n  payload window, and — on by default — `redact-on-capture`: a detected secret\n  is masked (`[REDACTED:type:hash]`) before it is ever written, so Beagle never\n  becomes a plaintext store of the very secrets it catches. Turn it off\n  (`beagle config redact-on-capture off`) for the raw-fidelity view.\n  One-command panic purge zeroes every record in place and compacts the\n  store (SQLite `secure_delete` + VACUUM) rather than just dropping rows —\n  best-effort on SSDs and copy-on-write filesystems, where full-disk\n  encryption is the real backstop.\n- **Auditable.** Found a hole? See [SECURITY.md](SECURITY.md) for private\n  reporting.\n\n## Install\n\nNo language/runtime dependencies — Beagle ships as a single self-contained\nbinary (macOS and Linux, x64 and arm64; Windows is post-v1). Linux desktop\nnotification banners use `notify-send` when it is available. The npm route\nneeds npm; the script route needs only curl.\n\n```sh\n# npm (primary) — the prebuilt binary for your platform. No post-install\n# script, no code fetched at install time.\nnpm install -g @boundedhq/beagle\n\n# or the one-line script (downloads from GitHub Releases, verifies the\n# sha256 checksum before installing, never runs post-install code). For a\n# transparency tool, read it before you pipe it:\n#   curl -fsSL https://github.com/boundedhq/beagle/releases/latest/download/install.sh -o install.sh\n#   less install.sh && sh install.sh\ncurl -fsSL https://github.com/boundedhq/beagle/releases/latest/download/install.sh | sh\n\n# or build from source (requires Bun ≥ 1.3)\ngit clone https://github.com/boundedhq/beagle && cd beagle\nbun install && bun run build     # → dist/beagle\n```\n\n(A Homebrew formula lives in `packaging/beagle.rb` for a future tap; npm already\ncovers macOS and Linux, so the tap isn't wired into releases yet.)\n\n## Update\n\nBeagle never checks for updates on its own — the only outbound traffic on\nyour machine is your agents' own calls, and an update check would break that\npromise. Updating is the same channel you installed with:\n\n```sh\n# npm\nnpm install -g @boundedhq/beagle@latest\n\n# install script — re-run it; it fetches the latest release and verifies the checksum\ncurl -fsSL https://github.com/boundedhq/beagle/releases/latest/download/install.sh | sh\n\n# from source\ngit pull && bun run build        # → dist/beagle (if you symlinked it into\n                                 #   your PATH — see Development — you're done)\n```\n\n**Then restart the daemon** — the new binary on disk doesn't change the\ndaemon already running from the old one. Beagle won't restart it behind your\nback (it may be mid-capture for another agent), but `beagle run` and\n`beagle ui` tell you when it's stale:\n\n```\nbeagle ▲ the running daemon is v0.1.0 but this beagle is v0.2.0 — it won't have this version's fixes until restarted.\n  Restart it: beagle stop   (the next 'beagle run' starts a fresh one on the new binary)\n```\n\n- **Plain use:** `beagle stop` — safer than a raw `kill`, because it refuses\n  while another agent's capture is live. The next `beagle run` / `beagle ui`\n  starts a fresh daemon on the new binary.\n- **Service-installed** (via `beagle watch`): here the warning says\n  `kill <pid>` instead, and that really is the right move — launchd/systemd\n  respawns the daemon immediately from the updated binary path. (Don't use\n  `beagle stop` for updates: it pauses always-on until the next\n  `beagle watch`.)\n\nIf the update changed the store schema, the new daemon migrates it in place\non startup (additive, data-preserving). Read commands against a\nnot-yet-migrated store refuse in plain language and say which side to\nrestart — never a stack trace. `beagle --version` prints the binary on disk;\n`beagle status` shows whether a daemon is running and its pid.\n\n## Uninstall\n\nBeagle must leave no trace — that's part of the trust contract. One command\ndoes the whole safe teardown, in the right order (unwatch every agent → stop\nthe daemon → erase captured data → remove the state dir):\n\n```sh\nbeagle uninstall                     # then remove the binary the way you installed it:\nnpm uninstall -g @boundedhq/beagle   # (npm)   or:   rm /usr/local/bin/beagle   (curl / source)\n```\n\n`beagle uninstall` restores your PATH and config before deleting anything,\nand — when the store is readable — zeroes its contents before unlinking it,\nrather than a bare `rm -rf` (best-effort — on SSDs and copy-on-write\nfilesystems full physical erasure can't be guaranteed from userspace;\nfull-disk encryption is the backstop). It's different from `beagle purge`,\nwhich clears the *data* while keeping you set up. Everything Beagle ever\nchanged is listed by `beagle status` while it's installed.\n\n## FAQ\n\n**Does my API key pass through Beagle?**\nIn wire-capture mode, yes (that's what a proxy is); at rest, never. Auth\nheaders are stripped before capture and are not stored, logged, or displayed.\n\n**What exactly is stored, and where?**\nRequest/response bodies, headers (minus credentials), timing and token\ncounts — in a SQLite file under `~/.local/state/beagle` (honors\n`$XDG_STATE_HOME`), mode `0600`, payloads pruned on a 7-day rolling window.\n`beagle purge` erases it on demand.\n\n**Can it see traffic from apps I didn't run under it?**\nNo. Coverage is opt-in per agent (`run` for one session, `watch` for\nalways-on). There is no system proxy, no packet capture, no TLS\ninterception — which also means GUI apps and IDE extensions aren't covered\nin v1.\n\n**How do I find out whether a secret leaked?**\nYou don't have to go looking — every outbound call is scanned automatically,\nand every credential finding is in `beagle leaks` and highlighted in the\ndashboard.\nDon't feed real keys into commands to check. `beagle search` is for strings\nthe detector *can't* know about (an internal password, a customer hostname);\nrun it with no argument and it reads the term from stdin, keeping it out of\nshell history. The search runs locally against your local store.\n\n**Why should I trust the detector?**\nIts rules are *derived from* the MIT-licensed gitleaks ruleset — a curated\nsubset, re-tiered and precision-tuned for agent traffic, then vendored as\ndata and sha256-pinned at load (see\n[THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md)). The matcher is ~200 lines\nyou can read in one sitting ([`src/core/scanner/`](src/core/scanner/)). A CI\nregression gate requires every hand-written negative fixture to remain free of\nloud (structured) findings and every positive fixture to remain detected\n([`tests/precision.test.ts`](tests/precision.test.ts)). That guards known cases;\nit is not a measured false-positive rate over representative traffic, and\nBeagle does not publish one without a larger, representative corpus. Detection\ntiers are honest: structured credential hits (AWS secret access keys,\nGitHub/Stripe keys, private keys, Luhn-checked cards) alert loudly;\nentropy-only hits stay a quiet \"possible.\" AWS access key IDs are recognized\nfor conservative redact-on-capture, but they are identifiers rather than\ncredentials, so they never create a leak event or alert.\n\n**What happens if Beagle crashes mid-run?**\nIn wire-capture mode, the proxy fails open for observation, never blocking\nyour agent: if capture fails, your agent's traffic still flows; the gap is\nrecorded as `capture truncated` rather than silently papered over.\n\n## Layout\n\n- `src/core/` — the dependency-free runtime foundation (separately LOC-budgeted,\n  stdlib-only, no `bun:*`); a subset of the trust path, not the full audit scope\n- [`TRUST_PATH_SCOPE`](scripts/loc-report.ts) — the explicit capture-to-alert\n  audit manifest and its ≤5,000-LOC budget (core plus the trust-path modules below)\n- `src/adapters/`, `src/parsers/`, `src/transform/`, `src/notifier/` — Bun surface\n  (`bun:sqlite`, workers), telemetry/format parsers, redact-on-capture, and alert\n  delivery; **on the trust path** (budgeted)\n- `src/daemon/` — capture → ingest → alert orchestration (`daemon.ts`, budgeted)\n  plus the control-plane socket (`control.ts`, outside the manifest)\n- `src/viewer/`, `src/install/`, and most of `src/cli/` — application and\n  orchestration code: reviewed and disclosed in the total LOC report, but not\n  in the budgeted trust manifest (`src/cli/demo.ts` is the explicit exception)\n- `rules/` — vendored, pinned detection rules (data; see [THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md))\n\n## Development\n\n```sh\nbun install\nbun run check          # lint + LOC budget + typecheck + tests\nbun run build          # → dist/beagle (self-contained binary)\n\n# run your build as `beagle` from anywhere (both pick up later rebuilds):\nexport PATH=\"$PWD/dist:$PATH\"                     # this shell only (add to your shell rc to persist)\nln -sf \"$PWD/dist/beagle\" /usr/local/bin/beagle   # or install it system-wide (may need sudo)\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). Beagle is a product of\n[Bounded](https://github.com/boundedhq), MIT-licensed.\n","readmeFilename":"README.md","_rev":"1-4ebb8109962a53a0dd7855de86362ed5"}