PageSourceSearch

https://sonomos.ai/assets/Canary-XMq-uMua.js

js sonomos.ai collected 2026-10-02 00:00:19 UTC 13,281 bytes, 11 lines download raw bytes

1import{c as x,j as e,k as u,S as h,H as p,a,A as l,L as o,M as c,N as n,E as g,h as y,F as b}from"./app-ptzYHIUo.js";import{C as f}from"./circle-check-BDUH5V4i.js";import{S as j}from"./shield-DeShVxfy.js";import{C as N}from"./chart-no-axes-column-C_p4KaHX.js";import{T as v}from"./triangle-alert-ISocwM80.js";/**
2 * @license lucide-react v0.462.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const w=x("FileJson",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1",key:"1oajmo"}],["path",{d:"M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1",key:"mpwhp6"}]]);/**
7 * @license lucide-react v0.462.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const k=x("Star",[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]]),C=2,S={canary:C},m="sonomoshq/Canary",I=({repo:s=m,className:t})=>{const r=s===m?S.canary:null,d=typeof r=="number"&&r>0,i=s.split("/").pop()??s;return e.jsxs("a",{href:`https://github.com/${s}`,target:"_blank",rel:"noopener noreferrer","aria-label":d?`Star ${i} on GitHub, ${r.toLocaleString()} stars`:`Star ${i} on GitHub`,className:u("inline-flex items-center gap-2 px-4 py-2 rounded-full glass-subtle text-sm font-medium text-foreground hover:bg-muted/60 transition-colors",t),children:[e.jsx(k,{className:"w-4 h-4",strokeWidth:1.5}),"Star on GitHub",d&&e.jsx("span",{className:"text-muted-foreground font-normal tabular-nums",children:r.toLocaleString()})]})},A=[{label:"Regex detectors (36)",items:["Credit cards (Luhn validated)","Social Security Numbers","AWS access keys","Phone numbers & emails","Bitcoin & Ethereum addresses","Bank routing numbers","VINs & driver's licenses","URLs with embedded credentials"]},{label:"Semantic detectors (70+)",items:["Full names & dates of birth","Physical addresses","Medical records & diagnoses","OAuth tokens & JWTs","Crypto seed phrases","Financial records & tax IDs","Passport & government IDs","And 60+ more categories"]}],L=[{icon:g,title:"See what you've already exposed",description:"A persistent counter tracks every PII hit across all sessions. The number only goes up — because the exposure already happened."},{icon:n,title:"Runs silently in the background",description:"Canary hooks into every Claude Code message as an asynchronous stop hook. It never blocks your workflow or slows you down."},{icon:j,title:"Fully local, zero telemetry",description:"No network requests. No external services — checked mechanically in CI. Findings are stored only in ~/.sonomos/leaks.jsonl with owner-only file permissions."},{icon:N,title:"Interactive dashboard",description:"Run /canary:leaked to open an HTML visualization of everything Canary has detected across your sessions."},{icon:w,title:"Export your exposure data",description:"Export findings as CSV or JSON for audits, compliance reviews, or your own analysis."},{icon:v,title:"Smart redaction, not raw storage",description:"Canary stores only the first and last two characters of each detected value, with the middle replaced by ••. Your actual data never persists."},{icon:y,title:"Audit your installed extensions",description:"Run /canary:audit to scan installed skills, agents, plugins, and MCP configs for leaked secrets and exfiltration patterns — not just your own conversation."}],M=()=>e.jsxs(e.Fragment,{children:[e.jsx(h,{canonical:"/canary",title:"Canary — Claude Code Privacy Plugin by Sonomos",description:"Canary is a free, open-source Claude Code plugin that tracks every piece of PII you expose during coding sessions. See the damage before you ignore it.",breadcrumbs:[{name:"Canary",path:"/canary"}]}),e.jsxs("div",{className:"min-h-screen bg-background text-foreground",children:[e.jsx(p,{}),e.jsxs("main",{id:"main-content",className:"pt-28 pb-20",role:"main",children:[e.jsx("section",{className:"pt-8 pb-16 md:pt-12 md:pb-20",children:e.jsx("div",{className:"container-wide",children:e.jsx(a,{children:e.jsxs("div",{className:"max-w-3xl mx-auto text-center",children:[e.jsxs("div",{className:"inline-flex items-center gap-2 px-3 py-1 rounded-full border border-border/60 bg-muted/40 text-[11px] tracking-wider up
11percase text-muted-foreground mb-6",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-status-green"}),"Free & Open Source · Claude Code Plugin"]}),e.jsx("h1",{className:"text-display-serif mb-6",children:"You have no idea how much PII you've fed to Claude."}),e.jsx("p",{className:"text-body text-muted-foreground max-w-2xl mx-auto mb-4",children:"Canary is a silent Claude Code plugin that tracks every piece of sensitive data exposed in your coding sessions — SSNs, API keys, medical records, credentials, and 70+ other categories. The number only goes up."}),e.jsx("p",{className:"text-sm text-muted-foreground/80 max-w-xl mx-auto mb-10",children:"Think of it as a mirror. Canary doesn't prevent exposure — it shows you exactly what's already happened, so you understand why Locke, our desktop app, exists."}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-center gap-4",children:[e.jsxs("a",{href:"https://github.com/sonomoshq/Canary",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-2 px-6 py-3 bg-foreground text-background text-sm font-medium rounded-full hover:opacity-90 transition-opacity",children:["View on GitHub",e.jsx(l,{className:"w-4 h-4"})]}),e.jsxs(o,{to:"/downloads/",className:"inline-flex items-center gap-2 px-6 py-3 border border-border/60 text-sm font-medium rounded-full hover:bg-muted transition-colors",children:[e.jsx(c,{className:"w-4 h-4"}),"Download Locke (desktop app — Early Access)"]})]}),e.jsx("div",{className:"mt-5 flex justify-center",children:e.jsx(I,{})})]})})})}),e.jsx("section",{className:"py-16 md:py-20 border-t border-border/40",children:e.jsx("div",{className:"container-wide",children:e.jsx(a,{children:e.jsxs("div",{className:"max-w-2xl mx-auto",children:[e.jsx("h2",{className:"text-2xl md:text-3xl font-display font-medium tracking-tight mb-2 text-center",children:"Install in two commands"}),e.jsx("p",{className:"text-sm text-muted-foreground text-center mb-10",children:"No API keys. No configuration. No external services. Just paste these into any Claude Code session."}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-xl border border-border/60 bg-muted/30 p-5",children:[e.jsx("p",{className:"text-[10px] tracking-wider uppercase text-muted-foreground/70 mb-3",children:"Step 1 — Add from the plugin marketplace"}),e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(n,{className:"w-4 h-4 text-muted-foreground mt-0.5 shrink-0"}),e.jsx("code",{className:"text-sm font-mono text-foreground",children:"/plugin marketplace add sonomoshq/Canary"})]})]}),e.jsxs("div",{className:"rounded-xl border border-border/60 bg-muted/30 p-5",children:[e.jsx("p",{className:"text-[10px] tracking-wider uppercase text-muted-foreground/70 mb-3",children:"Step 2 — Install the plugin"}),e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(n,{className:"w-4 h-4 text-muted-foreground mt-0.5 shrink-0"}),e.jsx("code",{className:"text-sm font-mono text-foreground",children:"/plugin install canary@sonomos"})]})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-6 text-center",children:["That's it. Canary starts running as a background hook on every future session. Run"," ",e.jsx("code",{className:"font-mono text-foreground/80 text-[11px] bg-muted px-1.5 py-0.5 rounded",children:"/canary:leaked"})," ","to open your dashboard."]})]})})})}),e.jsx("section",{className:"py-16 md:py-20 border-t border-border/40",children:e.jsx("div",{className:"container-wide",children:e.jsx(a,{children:e.jsxs("div",{className:"max-w-3xl mx-auto",children:[e.jsx("h2",{className:"text-2xl md:text-3xl font-display font-medium tracking-tight mb-2 text-center",children:"How Canary works"}),e.jsx("p",{className:"text-sm text-muted-foreground text-center mb-12 max-w-xl mx-auto",children:"Canary runs as an asynchronous stop hook inside Claude Code — it never touches your actual workflow."}),e.jsx("div",{className:"space-y-3",children:[{step:"01",title:"Hook fires after every message",desc:"After each Claude Code response, Canary's stop hook runs silently in the background — no interruption to your session."},{step:"02",title:"Two detection layers run in parallel",desc:"36 regex patterns (with real checksum val
11idation, not just shape-matching) catch structured PII. Claude then scans for 70+ semantic categories — names, medical records, tokens, and more."},{step:"03",title:"Findings are stored locally with redaction",desc:"Only the first and last two characters of each detected value are saved, with the middle replaced by ••. Everything goes to ~/.sonomos/leaks.jsonl with owner-only permissions."},{step:"04",title:"Counter persists across sessions",desc:"Your exposure count survives restarts. Every session adds to the total — a running record of what's already left your machine."}].map(({step:s,title:t,desc:r})=>e.jsxs("div",{className:"flex items-start gap-5 p-5 rounded-xl border border-border/40 bg-card/40",children:[e.jsx("span",{className:"text-[11px] font-mono text-muted-foreground/50 mt-0.5 shrink-0 w-6",children:s}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium mb-1",children:t}),e.jsx("p",{className:"text-xs text-muted-foreground leading-relaxed",children:r})]})]},s))})]})})})}),e.jsx("section",{className:"py-16 md:py-20 border-t border-border/40",children:e.jsx("div",{className:"container-wide",children:e.jsxs(a,{children:[e.jsx("h2",{className:"text-2xl md:text-3xl font-display font-medium tracking-tight mb-12 text-center",children:"What Canary tracks"}),e.jsx("div",{className:"grid md:grid-cols-2 gap-5 max-w-4xl mx-auto mb-14",children:A.map(s=>e.jsxs("div",{className:"rounded-xl border border-border/50 bg-card/40 p-6",children:[e.jsx("p",{className:"text-xs font-medium uppercase tracking-wider text-muted-foreground/70 mb-4",children:s.label}),e.jsx("ul",{className:"space-y-2",children:s.items.map(t=>e.jsxs("li",{className:"flex items-center gap-2 text-sm text-foreground/80",children:[e.jsx(f,{className:"w-3.5 h-3.5 text-muted-foreground/50 shrink-0"}),t]},t))})]},s.label))}),e.jsx("div",{className:"grid sm:grid-cols-2 lg:grid-cols-3 gap-5 max-w-4xl mx-auto",children:L.map(s=>e.jsxs("div",{className:"rounded-xl border border-border/40 bg-card/30 p-5",children:[e.jsx("div",{className:"inline-flex items-center justify-center w-8 h-8 rounded-lg bg-muted/60 mb-3",children:e.jsx(s.icon,{className:"w-4 h-4 text-foreground/70",strokeWidth:1.5})}),e.jsx("p",{className:"text-sm font-medium mb-1",children:s.title}),e.jsx("p",{className:"text-xs text-muted-foreground leading-relaxed",children:s.description})]},s.title))})]})})}),e.jsx("section",{className:"py-16 md:py-20 border-t border-border/40",children:e.jsx("div",{className:"container-wide",children:e.jsx(a,{children:e.jsxs("div",{className:"max-w-2xl mx-auto rounded-2xl border border-border/60 bg-card/50 p-8 sm:p-10 text-center",children:[e.jsx("div",{className:"inline-flex items-center justify-center w-10 h-10 rounded-full bg-muted/60 mb-5 mx-auto",children:e.jsx(c,{className:"w-5 h-5 text-foreground",strokeWidth:1.5})}),e.jsxs("div",{className:"flex items-center justify-center gap-2 mb-3",children:[e.jsx("p",{className:"text-micro",children:"NEXT STEP"}),e.jsx("span",{className:"text-[10px] tracking-wider text-muted-foreground/60 uppercase px-2 py-0.5 rounded-full border border-border/50",children:"Coming Soon"})]}),e.jsx("h2",{className:"text-2xl md:text-3xl font-display font-medium tracking-tight mb-3",children:"Stop counting. Start preventing."}),e.jsx("p",{className:"text-sm text-muted-foreground leading-relaxed mb-6 max-w-lg mx-auto",children:"Canary shows you the damage. Locke, our desktop app, stops it from happening — across the AI websites you browse and the command-line agents you run, not just Claude Code. 100% local, zero data leaving your device."}),e.jsxs(o,{to:"/locke/",className:"inline-flex items-center gap-2 px-6 py-3 bg-foreground text-background text-sm font-medium rounded-full hover:opacity-90 transition-opacity group",children:["Learn about Locke",e.jsx(l,{className:"w-4 h-4 group-hover:translate-x-0.5 transition-transform"})]}),e.jsxs("p",{className:"mt-5 text-xs text-muted-foreground/70",children:["Wondering how Locke compares to other approaches?"," ",e.jsx(o,{to:"/compare/",className:"underline hover:text-foreground transition-colors",children:"See the comparisons"}),"."]})]})})})})]}),e.jsx(b,{})]})]});
11export{M as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.