cc-safety-net 2.4.14 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,47 +1,47 @@
1
- import{a,s,ke,Ue,k,Ze,Ge,c,o,He,R,L,ve,Qe,f,We,d,r,v,i,re,n,g,le,F,tt,nt,l,ue,de,rt,I,K,oe,S,ot,M,b,Se,j,u,J,Be,ze,O,w,T,pe,fe,Le,it,m,e,Te,we,Ve,qe,ie,Ce,se,_e,Y,U,Pe,me,G,Ke,H,Z,X,ae,Je,Ye,C,W,Ae,Oe,De,E,Ne,Ee,Fe,h,t,Q,ge,y,x,_,st,Me,$e,p,B}from"./chunks/index-qbhpx1zs.js";import{te,z,je,D,N}from"./chunks/index-jb96wweh.js";var Zd=["-h","--help"];function xt(P,A){let q=Object.entries(P.booleans??{}),V=Object.entries(P.values??{}),ee=Object.entries(P.lists??{}),ne=Object.fromEntries(q.map(([Xe])=>[Xe,!1])),ce={},he=Object.fromEntries(ee.map(([Xe])=>[Xe,[]])),ye=[],be=[],xe=!1,Ie=-1;for(let[Xe,et]of A.entries()){if(Xe<=Ie)continue;if(et==="--"){ye.push(...A.slice(Xe+1));break}if(Zd.includes(et)){xe=!0;continue}let Re=q.find(([,lt])=>lt.includes(et));if(Re){ne[Re[0]]=!0;continue}let at=V.find(([,lt])=>lt.includes(et));if(at){let lt=A[Xe+1];if(lt===void 0||lt.startsWith("-")){be.push(`${et} requires a value`);continue}ce[at[0]]=lt,Ie=Xe+1;continue}let ct=ee.find(([,lt])=>lt.includes(et));if(ct){let lt=A.slice(Xe+1),ft=lt.findIndex((gt)=>gt.startsWith("-")),mt=lt.slice(0,ft===-1?lt.length:ft);if(mt.length===0){be.push(`${et} requires at least one value`);continue}he[ct[0]]=[...he[ct[0]]??[],...mt],Ie=Xe+mt.length;continue}if(et.startsWith("-")){be.push(`Unknown option for ${P.label}: ${et}`);continue}if(P.positionals==="tail"){ye.push(...A.slice(Xe));break}ye.push(et)}if(P.positionals!=="list"&&P.positionals!=="tail")be.push(...ye.map((Xe)=>`Unexpected argument for ${P.label}: ${Xe}`));return{flags:ne,values:ce,lists:he,positionals:ye,help:xe,errors:be}}function Ut(P){for(let A of P)console.error(A);return P.length>0}import{readdirSync as iu,statSync as Vi,unlinkSync as su}from"node:fs";import{basename as zi,dirname as au,isAbsolute as lu,join as cu,relative as du,resolve as uu,sep as pu}from"node:path";var Gi=(P)=>{let A=Date.now()-new Date(P).getTime();if(!Number.isFinite(A))return"";let q=Math.floor(A/60000),V=Math.floor(q/60),ee=Math.floor(V/24);if(ee>0)return`${ee}d ago`;if(V>0)return`${V}h ago`;if(q>0)return`${q}m ago`;return"just now"},so=(P)=>{let A=(P??"").trim().split(/\s+/).filter((ee)=>ee&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(ee)),q=A[0]?.split("/").pop();if(!q)return null;let V=A[1];return V&&/^[a-z][a-z0-9-]*$/.test(V)?`${q} ${V}`:q};function Bi(P){let A=(ee)=>`${ee.sessionId}
2
- ${so(ee.segment||ee.command)}`,q=P.filter((ee)=>ee.decision!=="allow"),V=q.filter((ee)=>ee.sessionId).reduce((ee,ne)=>ee.set(A(ne),(ee.get(A(ne))??0)+1),new Map);return new Set(q.filter((ee)=>ee.failureStage||(V.get(A(ee))??0)>=2))}import{existsSync as Qd,readdirSync as eu,readFileSync as tu}from"node:fs";import{join as nu}from"node:path";function Xt(P,A){try{return eu(P,{withFileTypes:!0,encoding:"utf8"}).flatMap((q)=>{let V=nu(P,q.name);if(q.isDirectory())return Xt(V,A);if(q.name.endsWith(".jsonl"))return[V];return[]})}catch{if(A&&Qd(P))A.count++;return[]}}var ru=["segment","reason","sessionId","decision","agent","ruleId","failureStage"];function ou(P){if(!P||typeof P!=="object"||Array.isArray(P))return!1;let A=P;if(typeof A.ts!=="string"||typeof A.command!=="string")return!1;return ru.every((q)=>A[q]===void 0||typeof A[q]==="string")}function mn(P,A){try{return tu(P,"utf-8").split(`
3
- `).filter(Boolean).flatMap((q)=>{try{let V=JSON.parse(q);if(!ou(V)){if(A)A.count++;return[]}return[V]}catch{if(A)A.count++;return[]}})}catch{if(A)A.count++;return[]}}function Ct(P){return Array.from(P,(A)=>{let q=A.charCodeAt(0);if(q<=31||q>=127&&q<=159)return`\\x${q.toString(16).padStart(2,"0")}`;return A}).join("")}function fu(P,A){let q=te(P),V=xt({label:"logs",booleans:{all:["--all"],suspect:["--suspect"],json:["--json"],pruneLegacy:["--prune-legacy"],dryRun:["--dry-run"]},values:{id:["--id"],limit:["--limit"],since:["--since"],agent:["--agent"],rule:["--rule"],session:["--session"],project:["--project"]}},A);if(Ut(V.errors))return null;if(V.values.id!==void 0&&!/^[a-f0-9]{16}$/.test(V.values.id))return console.error("--id must be 16 hexadecimal characters"),null;let ee=V.values.limit===void 0?20:qi(V.values.limit);if(ee===null)return console.error("--limit must be a positive number"),null;let ne=V.values.since===void 0?Math.min(30,q):qi(V.values.since);if(ne===null||ne>q)return console.error(`--since must be a positive number of days no greater than ${q}`),null;let ce={limit:ee,limitExplicit:V.values.limit!==void 0,since:ne,sinceExplicit:V.values.since!==void 0,all:V.flags.all,json:V.flags.json,suspect:V.flags.suspect,pruneLegacy:V.flags.pruneLegacy,dryRun:V.flags.dryRun,id:V.values.id,agent:V.values.agent,rule:V.values.rule,session:V.values.session,project:V.values.project===void 0?void 0:uu(V.values.project)};if(ce.id&&(ce.agent!==void 0||ce.rule!==void 0||ce.session!==void 0||ce.project!==void 0||ce.suspect||ce.sinceExplicit||ce.limitExplicit))return console.error("--id cannot be combined with --agent, --rule, --session, --project, --suspect, --since, or --limit"),null;if(ce.pruneLegacy&&(ce.id!==void 0||ce.agent!==void 0||ce.rule!==void 0||ce.session!==void 0||ce.project!==void 0||ce.suspect||ce.all||ce.sinceExplicit||ce.limitExplicit))return console.error("--prune-legacy cannot be combined with --id, --agent, --rule, --session, --project, --suspect, --all, --since, or --limit"),null;if(ce.dryRun&&!ce.pruneLegacy)return console.error("--dry-run requires --prune-legacy"),null;return ce}async function Ji(P,A,q={}){let V=fu(P,A);if(!V)return 1;let ee=q.logsDir??D(P);if(V.pruneLegacy)return mu(ee,V.json,V.dryRun);if(!ee)return console.log(V.json?"[]":V.id?`No retained audit log entry found for id ${Ct(V.id)}.`:"No audit log entries found."),0;z(P,ee);let ne={count:0},ce=Xt(ee,ne).flatMap((Ie)=>mn(Ie,ne).map((Xe)=>({entry:Xe,file:Ie})));if(ne.count>0)console.error(`warning: ${ne.count} audit log ${ne.count===1?"source":"sources"} could not be read; these results are incomplete`);if(V.id)return vu(ce,V,q.timeZone);let he=Date.now()-V.since*24*60*60*1000,ye=ce.filter((Ie)=>bu(Ie,V,ee,he)),be=V.suspect?Bi(ye.map((Ie)=>Ie.entry)):null,xe=(be?ye.filter((Ie)=>be.has(Ie.entry)):ye).sort((Ie,Xe)=>Date.parse(Xe.entry.ts)-Date.parse(Ie.entry.ts)).slice(0,V.limit);if(V.json)return console.log(JSON.stringify(xe.map((Ie)=>Ie.entry),null,2)),0;if(xe.length===0)return console.log("No audit log entries found."),0;for(let Ie of xe)console.log(ku(Ie.entry,q.timeZone));return 0}function mu(P,A,q){let V=P?hu(P).map((he)=>cu(P,he)):[];if(q)return gu(V,A);let ee=[],ne=0,ce=0;for(let he of V){let ye=Vi(he,{throwIfNoEntry:!1})?.size??0,be=yu(he);if(be){ee.push(`${zi(he)}: ${be}`);continue}ne++,ce+=ye}if(A)return console.log(JSON.stringify({removedFiles:ne,removedBytes:ce,failedFiles:ee.length})),ee.length===0?0:1;console.log(ne===0&&ee.length===0?"No legacy audit log files found.":`Removed ${ne} legacy audit log ${ne===1?"file":"files"} (${Wi(ce)}).`);for(let he of ee)console.error(`Could not remove ${Ct(he)}`);if(console.log("Nested v2 audit logs were not changed."),ne>0)console.log("This deletion cannot be undone.");return ee.length===0?0:1}function gu(P,A){let q=P.reduce((V,ee)=>V+(Vi(ee,{throwIfNoEntry:!1})?.size??0),0);if(A)return console.log(JSON.stringify({dryRun:!0,files:P.length,bytes:q})),0;if(console.log(P.length===0?"No legacy audit log files found.":`Would remove ${P.length} legacy audit log ${P.length===1?"file":"files"} (${Wi(q)}).`),console.log("Nested v2 audit logs are not included."),P.length>0)console.log("Run the same command without --dry-run to delete them.");return 0}function hu(P){try{return iu(P,{withFileTypes:!0}).filter((A)=>A.isFile()&&A.name.endsWith(".jsonl")).map((A)=>A.name)}catch{return[]}}function yu(P){try{return su(P),null}catch(A){return A instanceof Error?A.message:String(A)}}function Wi(P){let A=["B","KiB","MiB","GiB"],q=Math.min(Math.floor(Math.log2(Math.max(P,1))/10),A.length-1);return`${Math.round(P/1024**q*10)/10} ${A[q]}`}function vu(P,A,q){let V=P.filter((ne)=>ne.entry.id===A.id);if(V.length>1)return console.error(`Multiple audit log entries found for id ${Ct(A.id??"")}.`),1;if(A.json)return console.log(JSON.stringify(V.map((ne)=>ne.entry),null,2)),0;let ee=V[0];if(!ee)return console.log(`No retained audit log entry found for id ${Ct(A.id??"")}.`),0;return console.log(xu(ee.entry,q)),0}function bu(P,A,q,V){if(!A.all&&P.entry.decision==="allow")return!1;if(Date.parse(P.entry.ts)<V)return!1;if(A.agent!==void 0&&P.entry.agent!==A.agent)return!1;if(A.rule!==void 0&&P.entry.ruleId!==A.rule)return!1;if(A.session!==void 0&&!Lu(P,q,A.session))return!1;if(A.project!==void 0&&!wu(P.entry.cwd,A.project))return!1;return!0}function Lu(P,A,q){if(P.entry.sessionId===q)return!0;return au(P.file)===A&&zi(P.file,".jsonl")===q}function wu(P,A){if(!P)return!1;let q=du(A,P);return q!==".."&&!q.startsWith(`..${pu}`)&&!lu(q)}function ku(P,A){let q=Ct(P.id??"-"),V=Ct(P.decision??"deny"),ee=P.cwd?` [${Ct(P.cwd)}]`:"",ne=P.segment||P.command,ce=ne===P.command?"":"↳ ",he=ne.length>50?`${ne.slice(0,50)}…`:ne;return`${q.padEnd(16)} ${Ct(Ki(P.ts,A))} ${V.padEnd(5)} ${Ct(P.agent??"-").padEnd(15)} ${Ct(P.ruleId??"-").padEnd(20)} ${ce}${Ct(he)}${ee}`}function xu(P,A){let q=(ee)=>Ct(ee===void 0||ee===null||ee===""?"-":ee),V=P.shape?`${P.agent??"-"} (shape: ${P.shape})`:P.agent??"-";return[`id: ${q(P.id)}`,`ts: ${q(Ki(P.ts,A))}`,`decision: ${q(P.decision)}`,`agent: ${q(V)}`,`level: ${q(P.level)}`,`tool: ${q(P.toolName)}`,`rule: ${q(P.ruleId)}`,`intent: ${q(P.intent)}`,`stage: ${q(P.failureStage)}`,`error: ${q(P.errorCode)}`,`session: ${q(P.sessionId)}`,`cwd: ${q(P.cwd)}`,`version: ${q(P.v)}`,`truncated: ${q(P.truncated===!0?"yes":void 0)}`,`reason: ${q(P.reason)}`,`command: ${q(P.command)}`,`segment: ${q(P.segment)}`].join(`
4
- `)}function Ki(P,A){let q=new Date(P);if(Number.isNaN(q.getTime()))return P;return new Intl.DateTimeFormat("sv-SE",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hourCycle:"h23",timeZone:A}).format(q)}function qi(P){let A=Number(P);return Number.isFinite(A)&&A>0?A:null}var Yi={name:"doctor",aliases:["--doctor"],description:"Run diagnostic checks to verify installation and configuration",usage:"doctor [options]",options:[{flags:"--json",description:"Output diagnostics as JSON"},{flags:"--skip-update-check",description:"Skip npm registry version check"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net doctor","cc-safety-net doctor --json","cc-safety-net doctor --skip-update-check"]};var Xi={name:"explain",description:"Show step-by-step analysis trace of how a command would be analyzed",usage:"explain [options] <command>",argument:"<command>",options:[{flags:"--json",description:"Output analysis as JSON"},{flags:"--cwd",argument:"<path>",description:"Use custom working directory"},{flags:"-h, --help",description:"Show this help"}],examples:['cc-safety-net explain "git reset --hard"','cc-safety-net explain --json "rm -rf /"','cc-safety-net explain --cwd /tmp "git status"']};var Zi={name:"gui",description:"Open the local policy editor GUI",usage:"gui [options]",options:[{flags:"--no-open",description:"Print the URL without opening a browser"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net gui","cc-safety-net gui --no-open"]};var nr=[{id:"antigravity-cli",displayName:"Antigravity CLI",doctorOrder:3,runtime:{order:1,flags:["-ac","--agy-cli"],description:"Run as Antigravity CLI PreToolUse hook",legacyTopLevelFlags:[]},install:{order:2,flag:"--agy-cli",artifactKind:"hook config",probeCommand:["agy","--version"]}},{id:"claude-code",displayName:"Claude Code",doctorOrder:1,runtime:{order:2,displayName:"Coding CLI",flags:["-cc","--coding-cli"],legacyFlags:["--claude-code"],description:"Run as Coding CLI PreToolUse hook",legacyTopLevelFlags:["-cc","--claude-code"]},install:{order:3,flag:"--claude-code",artifactKind:"plugin",probeCommand:["claude","--version"]}},{id:"codex",displayName:"Codex",doctorOrder:4,runtime:{order:3,flags:["-cx","--codex"],description:"Run as a Codex PreToolUse hook",legacyTopLevelFlags:[]},install:{order:4,flag:"--codex",artifactKind:"plugin",probeCommand:["codex","--version"]}},{id:"copilot-cli",displayName:"GitHub Copilot CLI",doctorOrder:7,runtime:{order:6,flags:["-cp","--copilot-cli"],description:"Run as GitHub Copilot CLI PreToolUse hook",legacyTopLevelFlags:["-cp","--copilot-cli"]},install:{order:7,flag:"--copilot-cli",artifactKind:"plugin",probeCommand:["copilot","--binary-version"]}},{id:"gemini-cli",displayName:"Gemini CLI",doctorOrder:6,runtime:{order:5,flags:["-gc","--gemini-cli"],description:"Run as Gemini CLI BeforeTool hook",legacyTopLevelFlags:["-gc","--gemini-cli"]},install:{order:6,flag:"--gemini-cli",artifactKind:"extension",probeCommand:["gemini","--version"]}},{id:"grok-build",displayName:"Grok Build",doctorOrder:8,runtime:{order:7,flags:["-gb","--grok-build"],description:"Run as Grok Build PreToolUse hook",legacyTopLevelFlags:[]},install:{order:8,flag:"--grok-build",artifactKind:"hook config",probeCommand:["grok","--version"]}},{id:"hermes-agent",displayName:"Hermes Agent",doctorOrder:9,runtime:{order:8,flags:["-ha","--hermes-agent"],description:"Run as Hermes Agent pre_tool_call hook",legacyTopLevelFlags:[]},install:{order:9,flag:"--hermes-agent",artifactKind:"plugin",probeCommand:["hermes","--version"]}},{id:"kimi-code",displayName:"Kimi Code",doctorOrder:10,runtime:{order:9,flags:["-kc","--kimi-code"],description:"Run as Kimi Code PreToolUse hook",legacyTopLevelFlags:[]},install:{order:10,flag:"--kimi-code",artifactKind:"hook config",probeCommand:["kimi","--version"]}},{id:"openclaw",displayName:"OpenClaw",doctorOrder:11,install:{order:11,flag:"--openclaw",artifactKind:"plugin",probeCommand:["openclaw","--version"]}},{id:"opencode",displayName:"OpenCode",doctorOrder:12,install:{order:12,flag:"--opencode",artifactKind:"plugin",probeCommand:["opencode","--version"]}},{id:"pi",displayName:"Pi",doctorOrder:13,install:{order:13,flag:"--pi",artifactKind:"package",probeCommand:["pi","--version"]}},{id:"cursor",displayName:"Cursor",doctorOrder:5,runtime:{order:4,flags:["-cu","--cursor"],description:"Run as Cursor preToolUse hook",legacyTopLevelFlags:[]},install:{order:5,flag:"--cursor",artifactKind:"hook config",probeCommand:["cursor","--version"]}},{id:"amp",displayName:"Amp Code",doctorOrder:2,install:{order:1,flag:"--amp",artifactKind:"plugin",probeCommand:["amp","--version"]}}],rr=nr.slice().sort((P,A)=>P.doctorOrder-A.doctorOrder).map((P)=>P.id),En=nr.filter((P)=>("runtime"in P)).slice().sort((P,A)=>P.runtime.order-A.runtime.order).map((P)=>({id:P.id,displayName:"displayName"in P.runtime?P.runtime.displayName:P.displayName,flags:P.runtime.flags,legacyFlags:"legacyFlags"in P.runtime?P.runtime.legacyFlags:[],description:P.runtime.description,legacyTopLevelFlags:P.runtime.legacyTopLevelFlags})),$t=nr.slice().sort((P,A)=>P.install.order-A.install.order).map((P)=>({id:P.id,...P.install})).map(({order:P,...A})=>A),Cu=Object.fromEntries(nr.map((P)=>[P.id,P.displayName]));function bt(P){return Cu[P]}var Su=En.map((P)=>({flags:P.flags.join(", "),description:P.description})),Ru=En.flatMap((P)=>P.flags.map((A)=>`cc-safety-net hook ${A}`)),Qi={name:"hook",description:"Run as an agent CLI hook (reads JSON from stdin)",usage:"hook INTEGRATION_FLAG",options:[...Su,{flags:"-h, --help",description:"Show this help"}],examples:Ru};var es={name:"install",description:"Install CC Safety Net into a coding agent CLI",usage:"install [TARGET_FLAG]",options:[...$t.map((P)=>({flags:P.flag,description:`Install ${bt(P.id)} ${P.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net install",...$t.map((P)=>`cc-safety-net install ${P.flag}`)]},ts={name:"uninstall",description:"Uninstall CC Safety Net from a coding agent CLI",usage:"uninstall [TARGET_FLAG]",options:[...$t.map((P)=>({flags:P.flag,description:`Uninstall ${bt(P.id)} ${P.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net uninstall",...$t.map((P)=>`cc-safety-net uninstall ${P.flag}`)]},ns={name:"update",description:"Update every installed CC Safety Net integration to the latest version",usage:"update",options:[{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net update"]};var rs={name:"logs",description:"Browse audit log entries recorded by hooks",usage:"logs [options]",options:[{flags:"--id",argument:"<id>",description:"Show one entry from retained history by its 16-character id (not guaranteed once it is older than the configured retention)"},{flags:"--limit",argument:"<n>",description:"Maximum entries to print",default:"20"},{flags:"--since",argument:"<days>",description:"Only include entries newer than this many days (max: the configured audit retention, 1-365)",default:"30"},{flags:"--agent",argument:"<name>",description:"Filter by agent name"},{flags:"--rule",argument:"<ruleId>",description:"Filter by rule id"},{flags:"--session",argument:"<id>",description:"Filter by session id"},{flags:"--project",argument:"<path>",description:"Filter by project path"},{flags:"--suspect",description:"Only denials that look like false positives"},{flags:"--all",description:"Include allow entries"},{flags:"--prune-legacy",description:"Permanently delete all legacy root-level logs; nested logs are untouched"},{flags:"--dry-run",description:"With --prune-legacy, report what would be deleted and delete nothing"},{flags:"--json",description:"Output entries as JSON"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net logs --id 3fa9c2d1a70e8b42","cc-safety-net logs --agent claude-code","cc-safety-net logs --project . --since 7","cc-safety-net logs --suspect --since 7","cc-safety-net logs --json","cc-safety-net logs --prune-legacy --dry-run","cc-safety-net logs --prune-legacy"]};var or={name:"policy",description:"Check and apply project or user policy proposals",usage:"policy <subcommand>",subcommands:[{usage:"check <file>",description:"Validate a policy proposal and print its diff"},{usage:"apply <file>",description:"Apply a proposal after confirming in a terminal"}],options:[{flags:"-g, --global",description:"Use the user-scope policy instead of the project one"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net policy check proposal.json","cc-safety-net policy apply proposal.json","cc-safety-net policy apply proposal.json --global"]};var ao=[{flags:"--ref",argument:"<ref>",description:"Use a branch, tag, or commit"},{flags:"--only",argument:"<rulebook...>",description:"Add only these repository rulebooks"},{flags:"-g, --global",description:"Use user-scope rule config"},{flags:"-h, --help",description:"Show this help"}],lo=["cc-safety-net rule add project-rules","cc-safety-net rule add acme/safety-rules","cc-safety-net rule add acme/safety-rules --only aws gcloud","cc-safety-net rule add acme/safety-rules --ref v2 --only aws","cc-safety-net rule add --only terraform aws"],gn={name:"rule",description:"Manage CC Safety Net rule config and rulebook sources",usage:"rule <subcommand>",subcommands:[{usage:"init [--example]",description:"Create inert rule config"},{usage:"add [source] [--ref <ref>] [--only <rulebook...>]",description:"Add rulebook sources and sync"},{usage:"remove <source>",description:"Remove a rulebook source and sync"},{usage:"update [source]",description:"Re-fetch and vendor remote rulebooks"},{usage:"sync",description:"Deprecated: migrate lock and cache leftovers"},{usage:"list",description:"List active rulebooks"},{usage:"wrapper add <command>",description:"Trust a transparent command wrapper"},{usage:"wrapper remove <command>",description:"Remove a transparent command wrapper"},{usage:"wrapper list",description:"List transparent command wrappers"},{usage:"migrate [--cleanup]",description:"Migrate legacy inline rules"},{usage:"doc",description:"Print the rulebook authoring guide"},{usage:"verify",description:"Validate rule config files"}],options:[{flags:"-g, --global",description:"Use user-scope rule config"},{flags:"--cleanup",description:"Delete legacy files after rule migrate verifies them"},{flags:"--delete-source",description:"Delete clean local source directory on remove"},{flags:"--example",description:"Create an inactive example rulebook with rule init"},...ao.slice(0,2),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net rule init","cc-safety-net rule init --example","cc-safety-net rule wrapper add rtk",...lo,"cc-safety-net rule update","cc-safety-net rule migrate --cleanup","cc-safety-net rule verify"]};var os={name:"status",description:"Show what the runtime is enforcing right now",usage:"status",options:[{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net status"]};var is={name:"statusline",description:"Print status line with mode indicators for shell integration",usage:"statusline --claude-code",options:[{flags:"-cc, --claude-code",description:"Print status line for Claude Code"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net statusline -cc","cc-safety-net statusline --claude-code"]};var ir=[os,Yi,rs,Xi,gn,or,es,ns,ts,Qi,Zi,is];function Pu(P){return P.aliases??[]}function sr(P){let A=P.toLowerCase();return ir.find((q)=>q.name.toLowerCase()===A||Pu(q).some((V)=>V.toLowerCase()===A))}import{basename as Eu}from"node:path";function ar(P,A=7,q=D(P)){let V=Date.now()-A*24*60*60*1000,ee=[],ne=new Set,ce=0,he,ye,be,xe;if(q)z(P,q);let Ie={count:0},Xe=q?Xt(q,Ie):[];for(let Re of Xe)for(let at of mn(Re,Ie)){if(at.decision==="allow")continue;let ct=new Date(at.ts).getTime();if(ct>=V){if(ce++,ne.add(at.sessionId??Eu(Re,".jsonl")),ye===void 0||ct<=ye)he=at.ts,ye=ct;if(xe===void 0||ct>xe)be=at.ts,xe=ct;Du(ee,at,ct)}}let et=ee.map((Re)=>({timestamp:Re.ts,command:Re.command,reason:Re.reason,relativeTime:Gi(new Date(Re.ts))}));return{totalBlocked:ce,sessionCount:ne.size,recentEntries:et,oldestEntry:he,newestEntry:be,unreadable:Ie.count}}function Du(P,A,q){let V=P.findIndex((ee)=>q>new Date(ee.ts).getTime());if(V===-1){if(P.length<3)P.push(A);return}if(P.splice(V,0,A),P.length>3)P.pop()}import{dirname as Uu}from"node:path";import{dirname as Au,join as _u,resolve as Tu}from"node:path";var Iu="config.json";function Pt(P,A,q,V){g($u(P),`${JSON.stringify(A,null,2)}
5
- `,q,V)}function $u(P){return typeof P==="string"?re(P):P}function uo(P){return{errors:ie(Fu(P),": "," "),ruleNames:new Set(_e(P).map((A)=>A.toLowerCase()))}}var Ou="must match pattern (letters, numbers, hyphens, underscores; max 64 chars)",ss="must match pattern (letters, numbers, hyphens, underscores)";function Fu(P){if(!as(P))return[e([],"Config must be an object")];return[...P.version===1?[]:[e(["version"],"must be 1")],...Nu(P.rules)]}function Nu(P){if(P===void 0)return[];if(!Array.isArray(P))return[e(["rules"],"must be an array")];return[...P.flatMap((A,q)=>as(A)?ju(A,["rules",q]):[e(["rules",q],"must be an object")]),...Te(P)]}function ju(P,A){return[...co(P.name,[...A,"name"],"required string",l,Ou),...co(P.command,[...A,"command"],"required string",w,ss),...P.subcommand===void 0?[]:co(P.subcommand,[...A,"subcommand"],"must be a string if provided",w,ss),...Mu(P.block_args,[...A,"block_args"]),...Hu(P.reason,[...A,"reason"]),...P.intent===void 0||Ce(P.intent)?[]:[e([...A,"intent"],we)]]}function co(P,A,q,V,ee){if(typeof P!=="string")return[e(A,q)];return V.test(P)?[]:[e(A,ee)]}function Mu(P,A){if(!Array.isArray(P))return[e(A,"required array")];if(P.length===0)return[e(A,"must have at least one element")];return P.flatMap((q,V)=>{if(typeof q!=="string")return[e([...A,V],"must be a string")];return q===""?[e([...A,V],"must not be empty")]:[]})}function Hu(P,A){if(typeof P!=="string")return[e(A,"required string")];if(P==="")return[e(A,"must not be empty")];return P.length>T?[e(A,`must be at most ${T} characters`)]:[]}function as(P){return!!P&&typeof P==="object"&&!Array.isArray(P)}function po(P){let A=ls(P);if(!A.ok)return A.result;return uo(A.parsed)}function ls(P){let A=[],q=new Set;try{let V=typeof P==="string"?re(P):P,ee=n(V);if(ee===null)return A.push(`File not found: ${V.path}`),{ok:!1,result:{errors:A,ruleNames:q}};if(!ee.trim())return A.push("Config file is empty"),{ok:!1,result:{errors:A,ruleNames:q}};return{ok:!0,parsed:JSON.parse(ee)}}catch(V){if(V instanceof r)return A.push(V.message),{ok:!1,result:{errors:A,ruleNames:q}};let ee=V instanceof Error?V.message:String(V);return A.push(V instanceof SyntaxError?"Invalid JSON":ee),{ok:!1,result:{errors:A,ruleNames:q}}}}function cs(P){return Tu(P,".safety-net.json")}function Jt(P){let A=ls(P);if(!A.ok)return A.result;let q=Ve(A.parsed);return{errors:q.errors,ruleNames:q.sources}}function lr(P,A={}){return _u(Au(Se(P,A)),Iu)}function ds(P,A,q){let V;try{if(n(A)===null)return{path:P,exists:!1,valid:!1,ruleCount:0};V=Jt(A),V.errors.push(...U(P,q))}catch(ee){if(!(ee instanceof r))throw ee;V={errors:[ee.message],ruleNames:new Set}}return{path:P,exists:!0,valid:V.errors.length===0,ruleCount:V.ruleNames.size,...V.errors.length>0?{errors:V.errors}:{}}}function Gu(P,A){return{source:A,name:P.name,command:P.command,subcommand:P.subcommand,blockArgs:[...P.block_args],reason:P.reason}}function us(P,A){let q=j(P),V=M(A),ee=Uu(q),ne=Y(P,{cwd:A,userConfigPath:q,projectConfigPath:V,userConfigDir:ee}),ce=J(P,{cwd:A,userConfigPath:q,projectConfigPath:V,userConfigDir:ee}),he=new Map(ne.rulebooks.flatMap((ye)=>ye.rules.map((be)=>[be,ye.source])));return{userConfig:ds(q,ce.userConfigTarget,ce.userScope),projectConfig:ds(V,ce.projectConfigTarget,ce.projectScope),effectiveRules:ne.rules.map((ye)=>Gu(ye,he.get(ye.name)??"project"))}}var Bu=[{flag:o.level,description:"Safety level preset: standard, strict, or paranoid",defaultBehavior:"standard"},{flag:o.strict,description:"Legacy; equivalent to safety.overrides.fail_closed",defaultBehavior:"permissive"},{flag:o.paranoid,description:"Legacy; equivalent to safety.overrides.paranoid_rm and paranoid_interpreters",defaultBehavior:"off"},{flag:o.paranoidRm,description:"Legacy; equivalent to safety.overrides.paranoid_rm",defaultBehavior:"off"},{flag:o.paranoidInterpreters,description:"Legacy; equivalent to safety.overrides.paranoid_interpreters",defaultBehavior:"off"},{flag:o.worktree,description:"Allow local git discards in linked worktrees",defaultBehavior:"off"},{flag:o.debug,description:"Print diagnostic messages to stderr",defaultBehavior:"off"},{flag:o.auditScope,description:"Command decisions recorded: all, or blocked (privacy-minimizing, denials only)",defaultBehavior:"all"}];function ps(P){return[...Bu.map((A)=>({name:A.flag.name,value:ve(A.flag,P.env),isSet:Qe(A.flag,P.env),legacyName:A.flag.legacyName,legacyValue:A.flag.legacyName?P.env.get(A.flag.legacyName):void 0,legacyIsSet:A.flag.legacyName?P.env.get(A.flag.legacyName)!==void 0:void 0,description:A.description,defaultBehavior:A.defaultBehavior})),{name:"CC_SAFETY_NET_HOME",value:P.env.get("CC_SAFETY_NET_HOME"),isSet:P.env.get("CC_SAFETY_NET_HOME")!==void 0,description:"Override user-scope config/cache directory",defaultBehavior:"~/.cc-safety-net"}]}var fs={error:0,warning:1,info:2},qu=["policy","config","audit"];function Vu(P){return P.map((A)=>{if(A==="ownership")return"is not owned by the current user";if(A==="permissions")return"has unsafe permissions";if(A==="symlink")return"is a symbolic link";return"is not a directory"}).join(" and ")}var zu=[{derive:(P)=>P.hooks.length>0&&P.hooks.every((A)=>!A.configured)?[{checkId:"integration.none-configured",severity:"error",title:"No integration configured",detail:"CC Safety Net is not connected to any supported coding-agent integration.",fixHint:"Run `cc-safety-net install` and configure at least one integration."}]:[]},{derive:(P)=>P.hooks.filter((A)=>A.inspectionStatus==="failed").map((A)=>{let q=bt(A.platform);return{checkId:"integration.inspection-failed",severity:"error",title:`${q} inspection failed`,detail:`Doctor could not verify the ${q} integration configuration.`,fixHint:`Correct the reported ${q} configuration error, then run \`cc-safety-net doctor\` again.`,integration:A.platform}})},{derive:(P)=>P.userConfig.exists&&!P.userConfig.valid?[{checkId:"config.user-invalid",severity:"error",title:"User configuration is invalid",detail:"Doctor could not load a valid user rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:P.userConfig.path}]:[]},{derive:(P)=>P.projectConfig.exists&&!P.projectConfig.valid?[{checkId:"config.project-invalid",severity:"error",title:"Project configuration is invalid",detail:"Doctor could not load a valid project rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:P.projectConfig.path}]:[]},{derive:(P)=>P.configState.state==="degraded"?[{checkId:"config.runtime-degraded",severity:"warning",title:"Runtime is enforcing a fallback configuration",detail:`The rejected candidate configuration is not active: ${P.configState.reason}`,fixHint:"Fix the file named in the reason, or run `cc-safety-net rule update` to vendor a remote source, then rerun doctor."}]:[]},{derive:(P)=>P.v2Leftovers&&P.v2Leftovers.length>0?[{checkId:"config.v2-leftovers",severity:"info",title:"Rulebook lock and cache leftovers detected",detail:`Files an earlier version left behind are no longer read: ${P.v2Leftovers.join(", ")}.`,fixHint:"Run `cc-safety-net rule sync` (add `--global` for user scope) to migrate them, then rerun doctor."}]:[]},{derive:(P)=>{let A=P.environment.find((q)=>q.name==="CC_SAFETY_NET_AUDIT_SCOPE");return He(A?.value)==="invalid"?[{checkId:"environment.audit-scope-invalid",severity:"warning",title:"Audit scope value is invalid",detail:"CC_SAFETY_NET_AUDIT_SCOPE is not `all` or `blocked`, so allowed command decisions are not recorded.",fixHint:"Set CC_SAFETY_NET_AUDIT_SCOPE to `all` or `blocked`, then restart the integration."}]:[]}},...qu.map((P)=>({derive:(A)=>A.posture.directories.filter((q)=>q.kind===P&&q.status==="unsafe").map((q)=>({checkId:`posture.${P}-directory-unsafe`,severity:"error",title:`${P[0]?.toUpperCase()}${P.slice(1)} directory is unsafe`,detail:`The ${P} directory ${Vu(q.issues)}.`,fixHint:"Ensure this is a real directory owned by the current user with no group or other write access, then rerun doctor.",...q.path?{path:q.path}:{}}))})),{derive:(P)=>{let A=[...P.effectiveSafety.weakenedRuleOverrides].sort();return A.length>0?[{checkId:"posture.rule-overrides-weaken-preset",severity:"warning",title:"Rule overrides weaken the selected preset",detail:`Explicit overrides disable rules the resolved preset would enable: ${A.join(", ")}.`,fixHint:`Remove these \`off\` overrides or set them to \`on\`: ${A.join(", ")}.`}]:[]}}];function ms(P){return zu.flatMap((A,q)=>A.derive(P).map((V,ee)=>({finding:V,catalogOrder:q,occurrence:ee}))).sort((A,q)=>fs[A.finding.severity]-fs[q.finding.severity]||A.catalogOrder-q.catalogOrder||A.occurrence-q.occurrence).map((A)=>A.finding)}function Gt(){return Boolean(process.stdout.isTTY&&!process.env.NO_COLOR)}var Ju=(P)=>Gt()?`\x1B[32m${P}\x1B[0m`:P,Wu=(P)=>Gt()?`\x1B[33m${P}\x1B[0m`:P,Ku=(P)=>Gt()?`\x1B[34m${P}\x1B[0m`:P,Yu=(P)=>Gt()?`\x1B[36m${P}\x1B[0m`:P,Xu=(P)=>Gt()?`\x1B[31m${P}\x1B[0m`:P,Zu=(P)=>Gt()?`\x1B[2m${P}\x1B[0m`:P,Qu=(P)=>Gt()?`\x1B[1m${P}\x1B[0m`:P,dt={green:Ju,yellow:Wu,blue:Ku,cyan:Yu,red:Xu,dim:Zu,bold:Qu},ep="\x1B[0m",tp=[39,82,198,226,208,51,196,46,201,214,93,154,220,27,49,190,200,33,129,227,45,160,63,118,123,202];function np(P){let A=P;return()=>(A=(A*1664525+1013904223)%4294967296,A/4294967296)}function rp(P){let A=[...tp],q=np(P);for(let V=A.length-1;V>0;V--){let ee=Math.floor(q()*(V+1)),ne=A[V];A[V]=A[ee],A[ee]=ne}return A}function op(P,A=0){if(!Gt())return"";let q=rp(A);return`\x1B[38;5;${q[P%q.length]}m`}function gs(P,A,q=0){if(!Gt())return`"${P}"`;return`${op(A,q)}"${P}"${ep}`}function cr(P){return P==="default"?"built-in default":`${P} policy`}var ip=new RegExp("\x1B\\[[0-9;]*m","g"),fo=(P)=>P.replace(ip,"").length;function Zt(P){let A=(P.headers??P.rows[0]??[]).map((ce,he)=>{let ye=Math.max(...P.rows.map((be)=>fo(be[he]??"")));return Math.max(fo(ce),ye)}),q=(ce,he)=>ce+" ".repeat(Math.max(0,he-fo(ce))),V=(ce,he)=>he[0]+A.map((ye)=>ce.repeat(ye+2)).join(he[1])+he[2],ee=(ce)=>`│ ${ce.map((he,ye)=>q(he,A[ye]??0)).join(" │ ")} │`,ne=P.headers?[` ${ee(P.headers)}`,` ${V("─",["├","┼","┤"])}`]:[];return[` ${V("─",["┌","┬","┐"])}`,...ne,...P.rows.map((ce)=>` ${ee(ce)}`),` ${V("─",["└","┴","┘"])}`].join(`
6
- `)}function hs(P){let A=[];A.push("Hook Integration"),A.push(sp(P));let q=[],V=[];for(let ee of P){let ne=bt(ee.platform);if(ee.errors&&ee.errors.length>0)for(let ce of ee.errors)if(ee.configured)q.push({platform:ne,message:ce});else V.push({platform:ne,message:ce})}for(let ee of q)A.push(` Warning (${ee.platform}): ${ee.message}`);for(let ee of V)A.push(dt.red(` Error (${ee.platform}): ${ee.message}`));return A.join(`
7
- `)}function sp(P){let A=["Platform","Discovery","Configuration","Inspection"],q=P.map((V)=>{let ee=bt(V.platform);if(V.inspectionStatus==="not-inspected"){let ye=dt.dim("Not inspected");return[ee,ye,ye,ye]}let ne=V.detected?dt.green("Detected"):V.inspectionStatus==="failed"?dt.red("Unknown"):dt.dim("Not detected"),ce=V.configured?dt.green("Configured"):V.detected?dt.yellow("Not configured"):V.inspectionStatus==="failed"?dt.red("Unknown"):dt.dim("Not applicable"),he=V.inspectionStatus==="verified"?dt.green("Verified"):V.inspectionStatus==="failed"?dt.red("Failed"):dt.dim("Not applicable");return[ee,ne,ce,he]});return Zt({headers:A,rows:q})}function ys(P){let q=["Guard Engine Verification",` Synthetic self-test: ${P.failed>0?dt.red(`${P.passed}/${P.total} FAIL`):dt.green(`${P.passed}/${P.total} passed`)}`],V=P.results.filter((ee)=>!ee.passed);if(V.length>0){q.push(""),q.push(dt.red(" Failures:"));for(let ee of V)q.push(dt.red(` • ${ee.description}`)),q.push(dt.red(` expected ${ee.expected}, got ${ee.actual}`))}return q.join(`
8
- `)}function ap(P){if(P.length===0)return" (no custom rules)";let A=["Source","Name","Command","Block Args"],q=P.map((V)=>[V.source,V.name,V.subcommand?`${V.command} ${V.subcommand}`:V.command,V.blockArgs.join(", ")]);return Zt({headers:A,rows:q})}function vs(P){let A=[];if(A.push("Configuration"),A.push(lp(P.userConfig,P.projectConfig)),A.push(""),P.effectiveRules.length>0)A.push(` Effective rules (${P.effectiveRules.length} total):`),A.push(ap(P.effectiveRules));else A.push(" Effective rules: (none - using built-in rules only)");return A.join(`
9
- `)}function lp(P,A){let q=["Scope","Status"],V=(ne)=>{if(!ne.exists)return dt.dim("N/A");if(!ne.valid)return dt.red(`Invalid (${ne.errors?.[0]??"unknown error"})`);return dt.green("Configured")},ee=[["User",V(P)],["Project",V(A)]];return Zt({headers:q,rows:ee})}function bs(P){let A=[];return A.push("Environment"),A.push(cp(P)),A.join(`
10
- `)}function Ls(P){let A=P.effectiveSafety.policyScopes,q=["Effective Safety",` Selected preset: ${P.effectiveSafety.selectedPreset}${A?` (${cr(A.levelScope)})`:""}`,` Effective: ${P.effectiveSafety.level}`],V=[["fail_closed","fail_closed"],["paranoid_rm","paranoid_rm"],["paranoid_interpreters","paranoid_interpreters"]];for(let[ee,ne]of V){let ce=P.effectiveSafety.capabilities[ee],he=ce.enabled?dt.green("ON"):dt.dim("OFF"),ye=ce.sources.length>0?` (${ce.sources.join(", ")})`:"";q.push(` ${ne}: ${he} via ${ce.source}${ye}`)}if(A&&A.weakenings.length>0){q.push(" Project policy deltas:");for(let ee of A.weakenings)q.push(` ${ee}`)}q.push(` Stored rule customizations: ${P.effectiveSafety.ruleCounts.stored}`),q.push(` Effective rule customizations: ${P.effectiveSafety.ruleCounts.effective}`);for(let[ee,ne]of Object.entries(P.effectiveSafety.ruleOverrides))q.push(` ${ee}: ${ne}`);return q.join(`
11
- `)}function ws(P){let A=["Findings"];if(P.length===0)return A.push(" No findings from inspected doctor facts."),A.join(`
12
- `);for(let q of P){let V=`[${q.severity.toUpperCase()}] ${q.checkId}: ${Ct(q.title)}`,ee=q.severity==="error"?dt.red:q.severity==="warning"?dt.yellow:dt.blue;if(A.push(` ${ee(V)}`),A.push(` ${Ct(q.detail)}`),q.path)A.push(` Path: ${Ct(q.path)}`);if(q.fixHint)A.push(` Fix: ${Ct(q.fixHint)}`)}return A.join(`
13
- `)}function cp(P){let A=["Variable","Status","Legacy"],q=P.map((V)=>{let ee=V.isSet?dt.green("✓"):dt.dim("✗"),ne=V.legacyName&&V.legacyIsSet?`${V.legacyName} ${dt.green("✓")}`:V.legacyName??"";return[V.name,ee,ne]});return Zt({headers:A,rows:q})}function ks(P){let A=[];if(P.totalBlocked===0)A.push("Recent Activity"),A.push(" No blocked commands in the last 7 days"),A.push(" Tip: This is normal for new installations");else A.push(`Recent Activity · last 7 days (${P.totalBlocked} blocked / ${P.sessionCount} sessions)`),A.push(dp(P.recentEntries));if(P.unreadable>0)A.push(` Warning: ${P.unreadable} audit log ${P.unreadable===1?"source":"sources"} could not be read; this summary is incomplete`);return A.join(`
14
- `)}function dp(P){let A=["Time","Command"],q=P.map((V)=>{let ee=Ct(V.command.replace(/\r\n|\r|\n/g," ↵ ").replace(/\t/g," ")),ne=ee.length>40?`${ee.slice(0,37)}...`:ee;return[V.relativeTime,ne]});return Zt({headers:A,rows:q})}function xs(P){let A=[];if(A.push("Update Check"),P.latestVersion===null&&!P.error)return A.push(dr([["Status",dt.dim("Skipped")],["Installed",P.currentVersion]])),A.join(`
15
- `);if(P.error)return A.push(dr([["Status",`${dt.yellow("⚠")} Error`],["Installed",P.currentVersion],["Error",dt.dim(P.error)]])),A.join(`
16
- `);if(P.updateAvailable)return A.push(dr([["Status",`${dt.yellow("⚠")} Update Available`],["Current",P.currentVersion],["Latest",dt.green(P.latestVersion??"")]])),A.push(""),A.push(" Run: bunx cc-safety-net@latest doctor"),A.push(" Or: npx cc-safety-net@latest doctor"),A.join(`
17
- `);return A.push(dr([["Status",`${dt.green("✓")} Up to date`],["Version",P.currentVersion]])),A.join(`
18
- `)}function dr(P){return Zt({rows:P})}function Cs(P){let A=[];return A.push("System Info"),A.push(up(P)),A.join(`
19
- `)}function up(P){let A=["Component","Version"],q=(ne)=>{if(ne===null)return dt.dim("not found");return ne},ee=[{label:"cc-safety-net",value:P.version},...rr.map((ne)=>({label:bt(ne),value:P.versions[ne]??null})),{label:"Node.js",value:P.nodeVersion},{label:"npm",value:P.npmVersion},{label:"Bun",value:P.bunVersion},{label:"Platform",value:P.platform}].map((ne)=>[ne.label,q(ne.value)]);return Zt({headers:A,rows:ee})}function Ss(P){if(P.findings.length===0)return dt.green(`
20
- No findings from inspected doctor facts.`);let A={error:P.findings.filter((ne)=>ne.severity==="error").length,warning:P.findings.filter((ne)=>ne.severity==="warning").length,info:P.findings.filter((ne)=>ne.severity==="info").length},q=["error","warning","info"].filter((ne)=>A[ne]>0).map((ne)=>`${A[ne]} ${ne}`),V=P.findings.length===1?"finding":"findings",ee=`
21
- ${P.findings.length} ${V}: ${q.join(", ")}.`;if(A.error>0)return dt.red(ee);if(A.warning>0)return dt.yellow(ee);return dt.blue(ee)}import{lstatSync as pp}from"node:fs";import{dirname as mo}from"node:path";function go(P,A){try{let q=pp(A);if(q.isSymbolicLink())return{kind:P,path:A,status:"unsafe",issues:["symlink"]};if(!q.isDirectory())return{kind:P,path:A,status:"unsafe",issues:["not-directory"]};if(process.platform==="win32"||typeof process.getuid!=="function")return{kind:P,path:A,status:"unknown",issues:[]};let V=[...q.uid!==process.getuid()?["ownership"]:[],...(q.mode&18)!==0?["permissions"]:[]];return{kind:P,path:A,status:V.length>0?"unsafe":"safe",issues:V}}catch(q){if(typeof q==="object"&&q!==null&&"code"in q&&q.code==="ENOENT")return{kind:P,path:A,status:"not-applicable",issues:[]};return{kind:P,path:A,status:"unknown",issues:[]}}}function Rs(P,A){let q=D(P);return{directories:[go("policy",mo(mo(A))),go("config",mo(A)),...q?[go("audit",q)]:[{kind:"audit",status:"unknown",issues:[]}]]}}import{spawn as fp}from"node:child_process";import{existsSync as Ps}from"node:fs";import{delimiter as mp,extname as gp,join as hp}from"node:path";import{stripVTControlCharacters as Es}from"node:util";var As="2.4.14",yp=5000,vp="_CC_SAFETY_NET_TEST_SPAWN_PLATFORM";function wt(){return As}function ho(P,A){let q=P[A];if(q)return q;let V=Object.keys(P).find((ee)=>ee.toLowerCase()===A.toLowerCase()&&!!P[ee]);return V?P[V]:q}function bp(P){return(ho(P,"PATHEXT")||".COM;.EXE;.BAT;.CMD").split(";").filter((A)=>A.length>0)}function Lp(P,A){let q=gp(P)?[P]:[...bp(A).map((V)=>`${P}${V}`),P];if(P.includes("/")||P.includes("\\"))return q.find((V)=>Ps(V))??P;return(ho(A,"PATH")??"").split(mp).flatMap((V)=>q.map((ee)=>hp(V,ee))).find((V)=>Ps(V))??P}function Ds(P){if(!/[\s"&|<>^]/.test(P))return P;return`"${P.replace(/"/g,'""')}"`}function Qt(P,A){let[q,...V]=P,ee=A[vp]==="win32"?"win32":process.platform;if(!q||ee!=="win32")return{cmd:q??"",args:V};let ne=Lp(q,A);if(!/\.(?:bat|cmd)$/i.test(ne))return{cmd:ne,args:V};return{cmd:ho(A,"COMSPEC")??"cmd.exe",args:["/d","/c",["call",Ds(ne),...V.map(Ds)].join(" ")]}}var hn=async(P,A=yp)=>{let q=await wp(P,{timeoutMs:A});if(q.code!==0)return null;return Es(q.stdout).trim()||Es(q.stderr).trim()||null};function wp(P,A){let[q,...V]=P;if(!q)return Promise.resolve({code:null,stdout:"",stderr:""});return new Promise((ee)=>{try{let ne=Qt([q,...V],process.env),ce=fp(ne.cmd,ne.args,{stdio:["ignore","pipe","pipe"]}),he=!1,ye="",be="";ce.stdout.on("data",(Xe)=>{ye+=Xe.toString()}),ce.stderr.on("data",(Xe)=>{be+=Xe.toString()});let xe=(Xe)=>{if(he)return;he=!0,clearTimeout(Ie),ee(Xe)},Ie=setTimeout(()=>{ce.kill(),xe({code:null,stdout:ye,stderr:be})},A.timeoutMs);ce.on("close",(Xe)=>{xe({code:Xe,stdout:ye,stderr:be})}),ce.on("error",()=>{xe({code:null,stdout:ye,stderr:be})})}catch{ee({code:null,stdout:"",stderr:""})}})}function ur(P){if(!P)return null;let A=/Claude Code\s+(\d+\.\d+\.\d+)/i.exec(P);if(A)return A[1]??null;let q=/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/i.exec(P);if(q)return q[1]??null;return P.split(`
22
- `)[0]?.trim()||null}async function pr(P,A=hn,q=process.cwd()){let V=Promise.all($t.map(async(Ie)=>[Ie.id,ur(await A([...Ie.probeCommand]))])),[ee,ne,ce,he,ye,be,xe]=await Promise.all([V,V.then(async(Ie)=>{let Xe=Ie.find(([at])=>at==="opencode")?.[1];if(!Xe?.startsWith("2.")||!P(Xe))return null;let et=["--param",`location[directory]=${q}`],Re=["opencode","api","integration.list",...et];return await A(Re,30000),A(["opencode","api","plugin.list",...et],30000)}),A(["codex","plugin","list"],30000),A(["amp","plugins","list"],30000),A(["node","--version"]),A(["npm","--version"]),A(["bun","--version"])]);return{version:As,versions:Object.fromEntries(ee),codexPluginListOutput:ce,ampPluginListOutput:he,openCodePluginListOutput:ne,nodeVersion:ur(ye),npmVersion:ur(be),bunVersion:ur(xe),platform:`${process.platform} ${process.arch}`}}function yo(P,A){if(A==="dev")return!1;let q=P.split(".").map(Number),V=A.split(".").map(Number),[ee=0,ne=0,ce=0]=q,[he=0,ye=0,be=0]=V;if(ee!==he)return ee>he;if(ne!==ye)return ne>ye;return ce>be}async function Wt(){let P=wt(),A=new AbortController,q=setTimeout(()=>A.abort(),3000);try{let V=await fetch("https://registry.npmjs.org/cc-safety-net/latest",{signal:A.signal});if(!V.ok)return{currentVersion:P,latestVersion:null,updateAvailable:!1,error:`npm registry returned ${V.status}`};let ee=await V.json(),ne=yo(ee.version,P);return{currentVersion:P,latestVersion:ee.version,updateAvailable:ne}}catch(V){return{currentVersion:P,latestVersion:null,updateAvailable:!1,error:V instanceof Error?V.message:"Network error"}}finally{clearTimeout(q)}}import*as js from"node:readline";var $s=(P)=>`\x1B[${P}B`,kp=(P)=>`\x1B[${P}A`;var _s=["░","▒","▓","╱","╲","┃","━","┏","┓","┗","┛","╋"];function xp(P){return new Promise((A)=>setTimeout(A,P))}function Cp(P,A,q){if(!q)return A(P);if(q.aborted)return Promise.resolve();return new Promise((V,ee)=>{let ne=()=>q.removeEventListener("abort",ce),ce=()=>{ne(),V()};q.addEventListener("abort",ce,{once:!0}),A(P).then(()=>{ne(),V()},(he)=>{ne(),ee(he)})})}function fr(P){return Math.max(0,Math.min(1,P))}function yn(P){return Math.max(0,Math.min(255,Math.round(P)))}function vo(P){return P<=0.0031308?12.92*P:1.055*P**0.4166666666666667-0.055}function Sp(P,A,q){let V=q*Math.PI/180,ee=A*Math.cos(V),ne=A*Math.sin(V),ce=(P+0.3963377774*ee+0.2158037573*ne)**3,he=(P-0.1055613458*ee-0.0638541728*ne)**3,ye=(P-0.0894841775*ee-1.291485548*ne)**3;return{blue:yn(vo(fr(-0.0041960863*ce-0.7034186147*he+1.707614701*ye))*255),green:yn(vo(fr(-1.2684380046*ce+2.6097574011*he-0.3413193965*ye))*255),red:yn(vo(fr(4.0767416621*ce-3.3077115913*he+0.2309699292*ye))*255)}}function bo(P,A){let q=(A*P*180/Math.PI%360+360)%360;return Sp(0.72,0.15,q)}function Os(P,A=0.1){let q=bo(A,P);return`\x1B[38;2;${q.red};${q.green};${q.blue}m`}function Rp(P,A){return{blue:yn(P.blue+(255-P.blue)*A),green:yn(P.green+(255-P.green)*A),red:yn(P.red+(255-P.red)*A)}}function Fs(P,A,q){let V=Math.imul(P+2654435769,2246822507)^Math.imul(A+3266489909,668265263)^Math.imul(q+374761393,2654435761),ee=V^V>>>15,ne=Math.imul(ee,739982445),ce=ne^ne>>>12,he=Math.imul(ce,695872825);return((he^he>>>15)>>>0)/4294967296}function Pp(P,A,q){let V=Math.floor(Fs(P,A,q)*_s.length);return _s[V]??"░"}function Ts(P){let A=fr(P);return A*A*A*(A*(A*6-15)+10)}function Ep(P){if(P.length===0)return"";let A=[],q=!1,V="";for(let ee of P){let ne=`${ee.red};${ee.green};${ee.blue}`;if(ee.bold!==q)A.push(ee.bold?"\x1B[1m":"\x1B[22m"),q=ee.bold;if(ne!==V)A.push(`\x1B[38;2;${ne}m`),V=ne;A.push(ee.character)}return`${A.join("")}\x1B[22m\x1B[39m`}function Dp(P,A,q,V,ee){return P.map((ne,ce)=>({...bo(q,V+A+ce/ee),bold:!1,character:ne}))}function Ap(P,A,q,V,ee,ne,ce,he){let ye=Math.max(1,V*0.75),be=Math.min(1,q/ye),xe=ee*Ts(be),Ie=Math.max(0,(q-ye)/Math.max(1,V-ye)),Xe=(1-Ts(q/V))*he*2,et=0.35*Math.max(0,1-Ie*2),Re=be>=1,at=Math.min(P.length,Math.ceil(xe+2+1));return P.slice(0,at).map((ct,lt)=>{let ft=bo(ne,ce+A+lt/he+Xe),mt=lt+Fs(A,lt,7919)*2-1;if(mt>xe+2)return{...ft,bold:!1,character:" "};let gt=xe-mt,ut=0.8*Math.exp(-(gt*gt)/12.5),vt=Math.min(0.9,ut+et),At=!Re&&mt>xe-4;return{...Rp(ft,vt),bold:vt>0.3,character:At?Pp(A,lt,q):ct}})}function Is(P){return`\x1B[?2026h${P.map((A,q)=>`\x1B8${q>0?$s(q):""}${Ep(A)}`).join("")}\x1B[?2026l`}async function Lo(P,A={}){if(!P)return;let q=A.output??process.stdout,V=A.sleep??xp,ee=A.seed??0,ne=P.split(`
23
- `).map((xe)=>Array.from(xe)),ce=Math.max(...ne.map((xe)=>xe.length)),he=12000*ne.filter((xe)=>xe.length>0).length/40,ye=ce>0?Math.max(1,Math.ceil(he/16.666666666666668)):0,be=ye>0?he/ye:0;q.write(`\x1B[?25l${ne.length>1?`${`
24
- `.repeat(ne.length-1)}${kp(ne.length-1)}`:""}\x1B7`);try{for(let xe=1;xe<=ye;xe+=1){if(A.signal?.aborted)break;q.write(Is(ne.map((Ie,Xe)=>Ap(Ie,Xe,xe,ye,ce,0.1,ee,3)))),await Cp(be,V,A.signal)}}finally{if(q.write(Is(ne.map((xe,Ie)=>Dp(xe,Ie,0.1,ee,3)))),q.write("\x1B8"),ne.length>1)q.write($s(ne.length-1));q.write(`
25
- \x1B[0m\x1B[?25h`)}}var Ns=["┏━┛┏━┛ ┏━┛┏━┃┏━┛┏━┛━┏┛┃ ┃ ┏━ ┏━┛━┏┛","┃ ┃ ━━┃┏━┃┏━┛┏━┛ ┃ ━┏┛ ┃ ┃┏━┛ ┃ ","━━┛━━┛ ━━┛┛ ┛┛ ━━┛ ┛ ┛ ┛ ┛━━┛ ┛ "].join(`
26
- `);function _p(P){return Boolean(P.isTTY)}async function Dn(P={}){let A=P.output??process.stdout;if(!_p(A))return;let q=P.input??process.stdin,V={output:A,seed:P.seed??Math.random()*8192,sleep:P.sleep};if(!q.isTTY||typeof q.setRawMode!=="function"){await Lo(Ns,V);return}let ee=new AbortController,ne=q.readableFlowing===!0,ce=q.isRaw===!0,he=!1,ye=(be,xe)=>{if(xe.ctrl&&xe.name==="c")he=!0;if(he||xe.name==="return"||xe.name==="enter")ee.abort()};js.emitKeypressEvents(q),q.on("keypress",ye),q.setRawMode(!0),q.resume();try{await Lo(Ns,{...V,signal:ee.signal})}finally{if(q.off("keypress",ye),q.setRawMode(ce),!ne)q.pause()}if(!he)return;if(P.onInterrupt){P.onInterrupt();return}process.kill(process.pid,"SIGINT")}import{createHash as Fp}from"node:crypto";import{existsSync as Us}from"node:fs";import{dirname as mr,join as Gs}from"node:path";import{dirname as Ms,join as Tp,resolve as Ip}from"node:path";var $p="rule.lock";function Op(P){return Tp(Ms(P),$p)}function Hs(P={}){return Ip(P.cwd??process.cwd(),".safety-net.json")}function Et(P,A){let q=A.global?A.userConfigPath??j(P,A):A.projectConfigPath??M(A.cwd??process.cwd()),V=A.global?Be(P,A):ze(q,A.cwd??process.cwd()),ee=Op(q);return{configDir:Ms(q),configPath:q,lockPath:ee,filesystemScope:V,configTarget:i(V,q),lockTarget:i(V,ee)}}var Np="`cc-safety-net rule sync` is deprecated: rulebooks are live files that need no synchronization. This run only migrates the lock and cache an earlier version left behind.",jp="cache",Mp="rulebooks";function Bs(P,A={}){let q=Et(P,A),V=i(q.filesystemScope,Vs(q.configDir)),ee=n(q.lockTarget);if(console.log(Np),ee===null&&!Us(V.path))return console.log(`No v2 lock or cache leftovers found in ${mr(q.configDir)}; nothing to migrate.`),0;let ne=qp(ee),ce=m(q.configTarget);if(!ce.config&&(n(q.configTarget)!==null||ne.size>0))return console.error(`Cannot migrate: the rules config in ${mr(q.configDir)} is missing or unreadable while v2 leftovers remain. Restore rule.json, then re-run rule sync.`),1;let he=ce.config?.rules??[];for(let ye of he.flatMap((be)=>Hp(be,ne,q,V,A.global===!0)))console.log(ye);return F(q.lockTarget),tt(V),console.log(`Removed the v2 lock and cache under ${mr(q.configDir)}.`),0}function qs(P,A){return[...new Set([{cwd:A},{cwd:A,global:!0}].flatMap((q)=>{let V=Et(P,q);return[V.lockPath,Vs(V.configDir)]}))].filter((q)=>Us(q))}function Hp(P,A,q,V,ee){if(!S(P))return[];let ne=I(P).name,ce=i(q.filesystemScope,O(q.configDir,ne)),he=n(ce);if(he!==null&&Up(he,ne))return[];let ye=A.get(P),be=ye?Gp(ye,ne,V.path,q.filesystemScope):null;if(be===null)return[`Could not migrate ${P} from the v2 cache. Run \`cc-safety-net rule update ${P}${ee?" --global":""}\` to vendor it.`];if(g(ce,be),he!==null)return[`Restored ${P} from the v2 cache over an invalid file.`];return[`Vendored ${P} from the v2 cache.`]}function Up(P,A){let q=me(P);return!("problem"in q)&&q.rulebook.name===A}function Gp(P,A,q,V){let ee=Gs(q,Mp,`${Bp(P)}--${P.digest.replace("sha256:","").slice(0,12)}`,ue),ne=n(i(V,ee));if(ne===null||Jp(ne)!==P.digest)return null;let ce=me(ne);if("problem"in ce||ce.rulebook.name!==A)return null;return ne}function Vs(P){return Gs(mr(P),jp)}function Bp(P){return([P.owner,P.repo,P.display_ref,P.name].every((V)=>typeof V==="string"&&V!=="")?`${P.owner}/${P.repo}#${P.display_ref}/${P.name}`:P.spec).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"rulebook"}function qp(P){let A=P===null?null:zp(P),q=zs(A)&&Array.isArray(A.rulebooks)?A.rulebooks:[];return new Map(q.filter(Vp).map((V)=>[V.spec,V]))}function Vp(P){return zs(P)&&typeof P.spec==="string"&&typeof P.digest==="string"}function zs(P){return!!P&&typeof P==="object"}function zp(P){try{return JSON.parse(P)}catch{return null}}function Jp(P){return`sha256:${Fp("sha256").update(P).digest("hex")}`}var Js="\r\x1B[2K",Wp="\x1B[?25l",Kp="\x1B[39m",Yp="\x1B[?25h",Xp=100,Zp=0.55,Qp=80,Ws=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function e2(P){return new Promise((A)=>setTimeout(A,P))}async function gr(P,A={}){let q=A.output??process.stdout;if(!q.isTTY)return P;let V=A.sleep??e2,ee=!1,ne=P.then((he)=>(ee=!0,he),(he)=>{throw ee=!0,he});if(await Promise.race([ne.then(()=>!0),V(Xp).then(()=>!1)]))return ne;q.write(Wp);try{for(let he=0;!ee;he+=1)q.write(`${Js}${Os(he*Zp)}${Ws[he%Ws.length]}${Kp} ${A.loadingMessage??"Loading…"}`),await Promise.race([ne,V(Qp)]);return await ne}finally{q.write(`${Js}${Yp}`)}}async function An(P,A,q,V={}){let ee=A();if(P)await q();if(P&&ee.ready)await gr(ee.ready,V);return ee.finish()}import{stripVTControlCharacters as t2}from"node:util";var hr="amp plugins list",n2=/^\s*[✓✗]\s+cc-safety-net(?:\.ts)?\s+\(User Plugins\)\s+(\S+)\s*$/;function Ks(P){if(!P.ampPluginListOutput)return{platform:"amp",status:"n/a"};let A=t2(P.ampPluginListOutput).split(`
27
- `).map((q)=>n2.exec(q)?.[1]).find((q)=>q!==void 0);if(!A)return{platform:"amp",status:"n/a"};if(A!=="active")return{platform:"amp",status:"disabled",method:hr,configPath:hr,errors:[`Amp personal plugin cc-safety-net is ${A}; run "plugins: reload" in Amp or reinstall with install --amp`]};return{platform:"amp",status:"configured",method:hr,configPath:hr}}import{existsSync as a2,readFileSync as l2}from"node:fs";import{isAbsolute as kv,join as s2}from"node:path";function _n(P){return s2(P,".gemini","config","hooks.json")}var c2=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*(?:--agy-cli|-ac)(\s|["']|$)/;function d2(P){if(!P||typeof P!=="object"||Array.isArray(P))return[];return Object.values(P).flatMap((A)=>{if(!A||typeof A!=="object"||Array.isArray(A))return[];let q=A,V=q.PreToolUse;if(!Array.isArray(V))return[];return V.flatMap((ee)=>{if(!ee||typeof ee!=="object"||Array.isArray(ee))return[];let ne=ee.hooks;if(!Array.isArray(ne))return[];return ne.flatMap((ce)=>{if(!ce||typeof ce!=="object"||Array.isArray(ce))return[];let he=ce.command;if(typeof he!=="string"||!c2.test(he))return[];return[{command:he,enabled:q.enabled!==!1}]})})})}function Ys(P){let A=_n(P.environment.home);if(!a2(A))return{platform:"antigravity-cli",status:"n/a",configPath:A};let q;try{q=d2(JSON.parse(l2(A,"utf-8")))}catch(V){return{platform:"antigravity-cli",status:"n/a",configPath:A,errors:[`Failed to parse Antigravity hooks config ${A}: ${V instanceof Error?V.message:String(V)}`]}}if(q.some((V)=>V.enabled))return{platform:"antigravity-cli",status:"configured",method:"hook config",configPath:A};if(q.length>0)return{platform:"antigravity-cli",status:"disabled",method:"hook config",configPath:A};return{platform:"antigravity-cli",status:"n/a",configPath:A}}import{join as ko}from"node:path";import{existsSync as u2,lstatSync as p2,readFileSync as f2}from"node:fs";import{join as m2}from"node:path";function Ft(P,A=(q)=>q){if(!u2(P))return{kind:"missing"};try{return{kind:"ok",value:JSON.parse(A(f2(P,"utf-8")))}}catch{return{kind:"unreadable"}}}function en(P,A){if(P==="~")return A;if(P.startsWith("~/")||P.startsWith("~\\"))return m2(A,P.slice(2));return P}function Lt(P){try{return p2(P)}catch{return}}function yr(P,A){let q=Lt(A);if(!q)return{platform:P,status:"n/a",configPath:A};if(!q.isSymbolicLink()&&q.isDirectory())return;return{platform:P,status:"n/a",configPath:A,errors:[`${A} is a symlink or not a directory; move or remove it before installing`]}}function pt(P,A){return typeof P==="object"&&P!==null?P[A]:void 0}var wo="cc-safety-net@cc-marketplace";function vr(P){return P.env.get("CLAUDE_CONFIG_DIR")||ko(P.home,".claude")}function Xs(P){return ko(vr(P),"plugins","installed_plugins.json")}function Zs(P,A){let q=pt(pt(P,"plugins"),A);return Array.isArray(q)&&q.length>0}function br(P,A){let q=Ft(Xs(P));return q.kind==="ok"&&Zs(q.value,A)}function xo(P){let A=Xs(P),q=Ft(A);if(q.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(q.kind==="missing")return{platform:"claude-code",status:"n/a"};if(!Zs(q.value,wo))return{platform:"claude-code",status:"n/a"};let V=ko(vr(P),"settings.json"),ee=Ft(V);if(ee.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(!(ee.kind==="ok"&&pt(pt(ee.value,"enabledPlugins"),wo)===!0))return{platform:"claude-code",status:"disabled",method:"plugin config",configPath:V,errors:[`${wo} is installed but not enabled in Claude Code`]};return{platform:"claude-code",status:"configured",method:"plugin config",configPath:A}}function Qs(P){return xo(P.environment)}var ea="Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it.";function ta(P){if(!P.codexPluginListOutput)return{platform:"codex",status:"n/a"};let A=P.codexPluginListOutput.split(`
28
- `).find((q)=>q.includes("https://github.com/kenryu42/cc-safety-net.git"));if(!A)return{platform:"codex",status:"n/a"};if(!A.includes("installed,"))return{platform:"codex",status:"n/a"};if(!A.includes("installed, enabled"))return{platform:"codex",status:"disabled",method:"codex plugin list",configPath:"codex plugin list",errors:["Codex plugin line for https://github.com/kenryu42/cc-safety-net.git must contain installed, enabled."]};return{platform:"codex",status:"configured",method:"codex plugin list",configPath:"codex plugin list",errors:["Codex runs only trusted hooks, and doctor cannot check trust. Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it."]}}import{existsSync as Cr,readdirSync as g2,readFileSync as h2}from"node:fs";import{join as Rt}from"node:path";function _t(P){let A="",q=0,V=!1,ee=!1,ne=-1;while(q<P.length){let ce=P[q],he=P[q+1];if(ee){A+=ce,ee=!1,q++;continue}if(ce==='"'&&!V){V=!0,ne=-1,A+=ce,q++;continue}if(ce==='"'&&V){V=!1,A+=ce,q++;continue}if(ce==="\\"&&V){ee=!0,A+=ce,q++;continue}if(V){A+=ce,q++;continue}if(ce==="/"&&he==="/"){while(q<P.length&&P[q]!==`
29
- `)q++;continue}if(ce==="/"&&he==="*"){q+=2;while(q<P.length-1){if(P[q]==="*"&&P[q+1]==="/"){q+=2;break}q++}continue}if(ce===","){ne=A.length,A+=ce,q++;continue}if(ce==="}"||ce==="]"){if(ne!==-1){let ye=A.slice(ne+1);if(/^\s*$/.test(ye))A=A.slice(0,ne)+ye}ne=-1,A+=ce,q++;continue}if(!/\s/.test(ce))ne=-1;A+=ce,q++}return A}function ra(P,A,q){let V=A+1,ee=!1;while(V<P.length){if(ee){ee=!1,V++;continue}if(P[V]==="\\"){ee=!0,V++;continue}if(P[V]==='"')return V+1;V++}throw Error(q)}function So(P,A,q){let V=P[A],ee=V==="["?"]":"}",ne=0,ce=A;while(ce<P.length){let he=q.skipComment?.(P,ce)??ce;if(he!==ce){ce=he;continue}if(P[ce]==='"'){ce=ra(P,ce,q.stringError);continue}if(P[ce]===V)ne++;if(P[ce]===ee){if(ne--,ne===0)return ce}ce++}throw Error(q.bracketError)}function oa(P,A){let q=P.lastIndexOf(`
30
- `,A)+1;return/^[ \t]*/.exec(P.slice(q))?.[0]??""}function Lr(P,A){let q=A.end+(/^\s*/.exec(P.slice(A.end))?.[0].length??0);if(P[q]===","){let ce=P[q+1]===`
31
- `?q+2:q+1;return`${P.slice(0,A.start)}${P.slice(ce)}`}let V=P.slice(0,A.start).search(/\s*$/)-1;if(P[V]!==",")return`${P.slice(0,A.start)}${P.slice(A.end)}`;let ee=P.lastIndexOf(`
32
- `,V-1),ne=ee!==-1&&/^\s*$/.test(P.slice(ee+1,V))?ee:V;return`${P.slice(0,ne)}${P.slice(A.end)}`}function Co(P,A){if(P.startsWith("//",A)){let q=P.indexOf(`
33
- `,A+2);return q===-1?P.length:q+1}if(P.startsWith("/*",A)){let q=P.indexOf("*/",A+2);return q===-1?P.length:q+2}return A}function na(P,A){let q=A;while(q<P.length){if(/\s/.test(P[q]??"")){q++;continue}let V=Co(P,q);if(V===q)return q;q=V}return q}function ia(P,A,q){let V=0,ee=0;while(ee<P.length){let ne=Co(P,ee);if(ne!==ee){ee=ne;continue}if(P[ee]==='"'){let ce=ra(P,ee,q.stringError);if(V===1&&JSON.parse(P.slice(ee,ce))===A){let he=na(P,ce),ye=na(P,he+1);if(P[he]===":"&&P[ye]==="[")return{start:ye,end:So(P,ye,{skipComment:Co,...q})}}ee=ce;continue}if(P[ee]==="{"||P[ee]==="[")V++;if(P[ee]==="}"||P[ee]==="]")V--;ee++}return}var Nt="cc-safety-net@cc-marketplace",wr=["cc-marketplace","cc-safety-net"],sa=["_direct","copilot-safety-net"],aa=["cc-marketplace","safety-net"],la="safety-net@cc-marketplace";function kr(P,A){let q=A.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^a-z0-9-])${q}([^a-z0-9-]|$)`,"m").test(P??"")}function ca(P){return kr(P,"cc-safety-net@cc-marketplace")}function da(P){return kr(P,"cc-marketplace")}function ua(P){return kr(P,"copilot-safety-net")}function pa(P){return kr(P,"safety-net@cc-marketplace")}function xr(P){if(!P?.includes("cc-safety-net"))return!1;return/(^|\s)hook\s+(?:[^\s]+\s+)*(--copilot-cli|-cp)(\s|$)/.test(P)}function ma(P,A){if(!P)return null;let q=P.match(/(\d+)\.(\d+)\.(\d+)/);if(!q)return null;let V=[Number(q[1]),Number(q[2]),Number(q[3])];for(let ee=0;ee<A.length;ee++){let ne=V[ee]??0,ce=A[ee]??0;if(ne!==ce)return ne>ce}return!0}function y2(P){return ma(P,[0,0,422])}function v2(P){return ma(P,[1,0,8])}function In(P){return P.env.get("COPILOT_HOME")||Rt(P.home,".copilot")}function Ro(P){return(P.hooks?.preToolUse??[]).some((q)=>{if(q.type!==void 0&&q.type!=="command")return!1;return xr(q.command)||xr(q.bash)||xr(q.powershell)||xr(q.exec&&[q.exec,...q.args??[]].join(" "))})}function Tn(P){return P===void 0||typeof P==="string"}function b2(P){return P===void 0||Array.isArray(P)&&P.every((A)=>typeof A==="string")}function L2(P){if(!P||typeof P!=="object"||Array.isArray(P))return!1;let A=P;if(A.disableAllHooks!==void 0&&typeof A.disableAllHooks!=="boolean")return!1;if(A.hooks===void 0)return!0;if(!A.hooks||typeof A.hooks!=="object"||Array.isArray(A.hooks))return!1;let q=A.hooks.preToolUse;if(q===void 0)return!0;return Array.isArray(q)&&q.every((V)=>V!==null&&typeof V==="object"&&!Array.isArray(V)&&Tn(V.type)&&Tn(V.command)&&Tn(V.bash)&&Tn(V.powershell)&&Tn(V.exec)&&b2(V.args))}function Po(P,A){try{let q=JSON.parse(_t(h2(P,"utf-8")));if(!L2(q)){A?.push(`Invalid hook config ${P}: hooks.preToolUse must be an array of hook objects`);return}return q}catch(q){A?.push(`Failed to parse ${P}: ${q instanceof Error?q.message:String(q)}`);return}}function ga(P,A){try{return g2(P).filter((q)=>q.endsWith(".json")).sort((q,V)=>q.localeCompare(V))}catch(q){return A?.push(`Failed to read ${P}: ${q instanceof Error?q.message:String(q)}`),[]}}function w2(P,A){if(!Cr(P))return[];let q=[];for(let V of ga(P,A)){let ee=Rt(P,V),ne=Po(ee,A);if(ne&&Ro(ne))q.push(ee)}return q}function vn(P,A){if(!Cr(P))return;let q=Po(P,A);if(!q)return;return{path:P,config:q}}function fa(P,A,q,V){if(A){P.push(`GitHub Copilot CLI ${A} does not support ${q}; requires ${V}+`);return}P.push(`GitHub Copilot CLI version unavailable; skipping ${q} because it requires ${V}+`)}function k2(P){for(let A of P){if(A?.config.disableAllHooks===!0)return A.path;if(A?.config.disableAllHooks===!1)return}return}function x2(P,A,q,V){let ee=In(P),ne=Rt(A,".github","hooks"),ce=Rt(ee,"hooks"),he=Rt(A,".github","copilot"),ye=Rt(A,".claude"),be=v2(q),xe=be===!0?V:void 0,Ie=[vn(Rt(he,"settings.local.json"),xe),vn(Rt(he,"settings.json"),xe),vn(Rt(ye,"settings.local.json"),xe),vn(Rt(ye,"settings.json"),xe)],Xe=[vn(Rt(ee,"settings.json"),xe),vn(Rt(ee,"config.json"),xe)];if(be!==!1){let gt=k2([...Ie,...Xe]);if(gt){if(be===null)V.push(`GitHub Copilot CLI version unavailable; treating disableAllHooks in ${gt} as active`);return{activeConfigPaths:[],repoInlineSources:Ie,disabledBy:gt}}}let et=w2(ne,V),Re=y2(q),at=Re===!0?V:void 0,ct=Cr(ce)?ga(ce,at):[],lt=[];for(let gt of ct){let ut=Rt(ce,gt),vt=Po(ut,at);if(vt&&Ro(vt))lt.push(ut)}if(Re!==!0&&lt.length>0)fa(V,q,`user hook files in ${ce}`,"0.0.422"),lt.length=0;let ft=[];for(let gt of[...Ie,...Xe]){if(!gt)continue;if(!Ro(gt.config))continue;if(be===!0){ft.push(gt);continue}fa(V,q,"inline hook definitions in Copilot config files","1.0.8");break}let mt=(gt)=>gt.filter((ut)=>!!ut&&ft.includes(ut)).map((ut)=>ut.path);return{activeConfigPaths:[...mt(Ie),...et,...mt(Xe),...lt],repoInlineSources:Ie}}function ha(P){let A=[],q=x2(P.environment,P.cwd,P.copilotCliVersion,A);if(q.disabledBy)return{platform:"copilot-cli",status:"disabled",method:"hook config",configPath:q.disabledBy,configPaths:[q.disabledBy],errors:A.length>0?A:void 0};let V=In(P.environment),ee=Rt(V,"installed-plugins",...wr),ne=Cr(ee),ce=Rt(V,"settings.json"),he=Ft(ce,_t),ye=(et)=>pt(pt(et,"enabledPlugins"),Nt),be=q.repoInlineSources.find((et)=>typeof ye(et?.config)==="boolean"),xe=be??(he.kind==="ok"?{path:ce,config:he.value}:void 0);if(ne&&!be&&he.kind==="unreadable")return{platform:"copilot-cli",status:"not-inspected"};let Ie=ne&&xe!==void 0&&ye(xe.config)===!1;if(Ie&&q.activeConfigPaths.length===0)return{platform:"copilot-cli",status:"disabled",method:"plugin config",configPath:xe.path,errors:[`${Nt} is installed but not enabled in Copilot CLI`]};let Xe=ne&&!Ie;if(Xe||q.activeConfigPaths.length>0){let et=q.activeConfigPaths[0];return{platform:"copilot-cli",status:"configured",method:Xe?"plugin config":"hook config",configPath:et??(Xe?ee:void 0),configPaths:q.activeConfigPaths.length>0?q.activeConfigPaths:void 0,errors:A.length>0?A:void 0}}return{platform:"copilot-cli",status:"n/a",errors:A.length>0?A:void 0}}import{existsSync as I2,readFileSync as $2}from"node:fs";import{existsSync as ya,mkdirSync as R2,readFileSync as P2}from"node:fs";import{dirname as E2,join as D2}from"node:path";import{renameSync as C2,writeFileSync as S2}from"node:fs";function kt(P,A){let q=`${P}.${process.pid}.tmp`;S2(q,A),C2(q,P)}var jt=Object.fromEntries(En.map((P)=>[P.id,`npx -y cc-safety-net hook ${P.flags[1]}`]));var $n=jt.cursor,va=30;function Rr(P){return D2(P.home,".cursor","hooks.json")}function tn(P){return typeof P==="object"&&P!==null&&!Array.isArray(P)}function Eo(){return{command:$n,timeout:va,failClosed:!0}}function Sr(P){return tn(P)&&P.command===$n}function A2(P){return Object.keys(P).length===3&&P.command===$n&&P.timeout===va&&P.failClosed===!0}function _2(P){try{return JSON.parse(P2(P,"utf-8"))}catch(A){if(A instanceof SyntaxError)throw Error(`Failed to parse Cursor hooks config ${P}: ${A.message}`);throw A}}function ba(P){let A=_2(P);if(!tn(A))throw Error(`Cursor hooks config ${P} must be a JSON object`);if(A.version!==1)throw Error(`Cursor hooks config ${P} must set "version": 1`);if(A.hooks!==void 0&&!tn(A.hooks))throw Error(`Cursor hooks config ${P} "hooks" must be an object`);let q=tn(A.hooks)?A.hooks.preToolUse:void 0;if(q!==void 0&&!Array.isArray(q))throw Error(`Cursor hooks config ${P} "hooks.preToolUse" must be an array`);return A}function La(P){let A=tn(P.hooks)?P.hooks.preToolUse:void 0;return Array.isArray(A)?A:[]}function T2(P){if(!P.some(Sr))return[...P,Eo()];return P.reduce((A,q)=>{if(!Sr(q))return A.result.push(q),A;if(!A.inserted)A.result.push(Eo()),A.inserted=!0;return A},{result:[],inserted:!1}).result}function wa(P,A,q){let V=tn(A.hooks)?A.hooks:{},ee={...A,hooks:{...V,preToolUse:q}};kt(P,`${JSON.stringify(ee,null,2)}
34
- `)}function ka(P){let A=Rr(P);if(!ya(A))return R2(E2(A),{recursive:!0}),kt(A,`${JSON.stringify({version:1,hooks:{preToolUse:[Eo()]}},null,2)}
35
- `),{path:A,alreadyInstalled:!1};let q=ba(A),V=La(q),ee=V.filter(Sr);if(tn(q.hooks)&&Array.isArray(q.hooks.preToolUse)&&ee.length===1&&ee[0]!==void 0&&A2(ee[0]))return{path:A,alreadyInstalled:!0};return wa(A,q,T2(V)),{path:A,alreadyInstalled:!1}}function xa(P){let A=Rr(P);if(!ya(A))return{path:A,alreadyInstalled:!1};let q=ba(A),V=La(q),ee=V.filter((ne)=>!Sr(ne));if(ee.length===V.length)return{path:A,alreadyInstalled:!1};return wa(A,q,ee),{path:A,alreadyInstalled:!0}}function O2(P){if(!P||typeof P!=="object"||Array.isArray(P))return[];let A=P.hooks;if(!A||typeof A!=="object"||Array.isArray(A))return[];let q=A.preToolUse;if(!Array.isArray(q))return[];return q.filter((V)=>!!V&&typeof V==="object"&&!Array.isArray(V)&&V.command===$n)}function F2(P){let A=[];if(P.length>1)A.push("Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates");let q=P[0];if(q&&q.failClosed!==!0)A.push('Managed hook is missing "failClosed": true; reinstall to repair');if(q&&q.timeout!==30)A.push('Managed hook "timeout" is not 30; reinstall to repair');return A}function Ca(P){let A=Rr(P.environment);if(!I2(A))return{platform:"cursor",status:"n/a",configPath:A};let q;try{q=JSON.parse($2(A,"utf-8"))}catch(ne){return{platform:"cursor",status:"n/a",configPath:A,errors:[`Failed to parse Cursor hooks config ${A}: ${ne instanceof Error?ne.message:String(ne)}`]}}let V=O2(q);if(V.length===0)return{platform:"cursor",status:"n/a",configPath:A};let ee=F2(V);return{platform:"cursor",status:"configured",method:"hook config",configPath:A,errors:ee.length>0?ee:void 0}}import{existsSync as N2}from"node:fs";import{join as Do}from"node:path";var Ao="gemini-safety-net";function _o(P){let A=Do(P.home,".gemini","extensions"),q=Do(A,Ao);if(!N2(q))return{platform:"gemini-cli",status:"n/a"};let V=Do(A,"extension-enablement.json"),ee=Ft(V);if(ee.kind==="unreadable")return{platform:"gemini-cli",status:"not-inspected"};let ne=ee.kind==="ok"?pt(pt(ee.value,Ao),"overrides"):void 0;if(Array.isArray(ne)&&ne.some((he)=>typeof he==="string"&&he.startsWith("!")))return{platform:"gemini-cli",status:"disabled",method:"extension config",configPath:V,errors:[`${Ao} is disabled in Gemini CLI`]};return{platform:"gemini-cli",status:"configured",method:"extension config",configPath:q}}function Sa(P){return _o(P.environment)}import{existsSync as U2,readFileSync as G2}from"node:fs";import{existsSync as Pa,mkdirSync as j2,readFileSync as Ea,rmSync as M2}from"node:fs";import{dirname as H2,join as Ra}from"node:path";var On=jt["grok-build"],Dr=30;function Ar(P){return Ra(P.env.get("GROK_HOME")??Ra(P.home,".grok"),"hooks","cc-safety-net.json")}function nn(P){return typeof P==="object"&&P!==null&&!Array.isArray(P)}function Pr(){return{hooks:[{type:"command",command:On,timeout:Dr}]}}function Da(P){return nn(P)&&P.command===On}function Aa(P){return P.flatMap((A)=>{if(!nn(A)||!Array.isArray(A.hooks))return[A];let q=A.hooks.filter((V)=>!Da(V));if(q.length===A.hooks.length)return[A];return q.length===0?[]:[{...A,hooks:q}]})}function _a(P){try{let A=JSON.parse(P);return nn(A)?A:null}catch{return null}}function Ta(P){let A=nn(P.hooks)?P.hooks.PreToolUse:void 0;return Array.isArray(A)?A:[]}function Er(P,A,q){let V=nn(A.hooks)?A.hooks:{};kt(P,`${JSON.stringify({...A,hooks:{...V,PreToolUse:q}},null,2)}
36
- `)}function Ia(P){let A=Ar(P);if(!Pa(A))return j2(H2(A),{recursive:!0}),Er(A,{},[Pr()]),{path:A,alreadyInstalled:!1};let q=_a(Ea(A,"utf-8"));if(!q)return Er(A,{},[Pr()]),{path:A,alreadyInstalled:!1};let V=Ta(q),ee=V.filter((ne)=>nn(ne)&&Array.isArray(ne.hooks)&&ne.hooks.some(Da));if(ee.length===1&&JSON.stringify(ee[0])===JSON.stringify(Pr()))return{path:A,alreadyInstalled:!0};return Er(A,q,[...Aa(V),Pr()]),{path:A,alreadyInstalled:!1}}function $a(P){let A=Ar(P);if(!Pa(A))return{path:A,alreadyInstalled:!1};let q=_a(Ea(A,"utf-8"));if(!q)return{path:A,alreadyInstalled:!1};let V=Ta(q),ee=Aa(V);if(JSON.stringify(ee)===JSON.stringify(V))return{path:A,alreadyInstalled:!1};let ne=nn(q.hooks)?q.hooks:{};if(ee.length===0&&Object.keys(q).length===1&&Object.keys(ne).length===1)return M2(A),{path:A,alreadyInstalled:!0};return Er(A,q,ee),{path:A,alreadyInstalled:!0}}function Fn(P){return!!P&&typeof P==="object"&&!Array.isArray(P)}function B2(P){if(!Fn(P)||!Fn(P.hooks))return[];let A=P.hooks.PreToolUse;if(!Array.isArray(A))return[];return A.filter((q)=>Fn(q)&&Array.isArray(q.hooks)&&q.hooks.some((V)=>Fn(V)&&V.command===On))}function q2(P){let q=(Array.isArray(P.hooks)?P.hooks.filter(Fn):[]).find((V)=>V.command===On);return[...P.matcher===void 0||P.matcher===""||P.matcher==="*"?[]:['Managed hook has a "matcher" that narrows coverage; reinstall to repair'],...q?.type==="command"?[]:['Managed hook "type" is not "command"; reinstall to repair'],...q?.timeout===Dr?[]:[`Managed hook "timeout" is not ${Dr}; reinstall to repair`]]}function Oa(P){let A=Ar(P.environment);if(!U2(A))return{platform:"grok-build",status:"n/a",configPath:A};let q;try{q=JSON.parse(G2(A,"utf-8"))}catch(ne){return{platform:"grok-build",status:"n/a",configPath:A,errors:[`Failed to parse Grok Build hooks config ${A}: ${ne instanceof Error?ne.message:String(ne)}`]}}let V=B2(q)[0];if(!V)return{platform:"grok-build",status:"n/a",configPath:A};let ee=q2(V);return{platform:"grok-build",status:"configured",method:"hook config",configPath:A,errors:ee.length>0?ee:void 0}}import{readFileSync as qa}from"node:fs";import{join as Va}from"node:path";var It="cc-safety-net",To="# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent",V2=30;function Fa(P){return`${To}
37
- # version: ${P}
38
- `}function z2(P){return`${Fa(P)}name: ${It}
39
- version: "${P}"
1
+ import{a,s,_e,We,k,tt,Be,c,o,ze,R,T,Ce,rt,f,qe,l,r,v,i,ie,n,g,pe,j,it,st,u,fe,me,at,D,Y,se,S,ct,U,b,Ee,G,d,Z,Ke,Je,N,w,P,ge,he,Ae,lt,m,e,Ie,ke,Ye,Ze,ae,Re,ce,Oe,X,H,De,ye,W,Xe,B,Q,ee,le,Qe,et,C,z,Ne,Fe,Me,E,$e,Te,je,h,t,te,be,y,x,A,ut,Ue,Ge,p,V}from"./chunks/index-8cqwk53d.js";import{re,q,He,F,M}from"./chunks/index-mrn9mahg.js";var wu=["-h","--help"];function gn(_,I){let O=Object.entries(_.booleans??{}),L=Object.entries(_.values??{}),J=Object.entries(_.lists??{}),K=Object.fromEntries(O.map(([Se])=>[Se,!1])),ne={},oe=Object.fromEntries(J.map(([Se])=>[Se,[]])),de=[],ue=[],ve=!1,xe=-1;for(let[Se,Pe]of I.entries()){if(Se<=xe)continue;if(Pe==="--"){de.push(...I.slice(Se+1));break}if(wu.includes(Pe)){ve=!0;continue}let we=O.find(([,Ve])=>Ve.includes(Pe));if(we){K[we[0]]=!0;continue}let Le=L.find(([,Ve])=>Ve.includes(Pe));if(Le){let Ve=I[Se+1];if(Ve===void 0||Ve.startsWith("-")){ue.push(`${Pe} requires a value`);continue}ne[Le[0]]=Ve,xe=Se+1;continue}let en=J.find(([,Ve])=>Ve.includes(Pe));if(en){let Ve=I.slice(Se+1),on=Ve.findIndex((an)=>an.startsWith("-")),sn=Ve.slice(0,on===-1?Ve.length:on);if(sn.length===0){ue.push(`${Pe} requires at least one value`);continue}oe[en[0]]=[...oe[en[0]]??[],...sn],xe=Se+sn.length;continue}if(Pe.startsWith("-")){ue.push(`Unknown option for ${_.label}: ${Pe}`);continue}if(_.positionals==="tail"){de.push(...I.slice(Se));break}de.push(Pe)}if(_.positionals!=="list"&&_.positionals!=="tail")ue.push(...de.map((Se)=>`Unexpected argument for ${_.label}: ${Se}`));return{flags:K,values:ne,lists:oe,positionals:de,help:ve,errors:ue}}function On(_){for(let I of _)console.error(I);return _.length>0}import{readdirSync as Eu,statSync as ns,unlinkSync as Au}from"node:fs";import{basename as ts,dirname as _u,isAbsolute as Iu,join as Tu,relative as $u,resolve as Ou,sep as Du}from"node:path";var Xi=(_)=>{let I=Date.now()-new Date(_).getTime();if(!Number.isFinite(I))return"";let O=Math.floor(I/60000),L=Math.floor(O/60),J=Math.floor(L/24);if(J>0)return`${J}d ago`;if(L>0)return`${L}h ago`;if(O>0)return`${O}m ago`;return"just now"},co=(_)=>{let I=(_??"").trim().split(/\s+/).filter((J)=>J&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(J)),O=I[0]?.split("/").pop();if(!O)return null;let L=I[1];return L&&/^[a-z][a-z0-9-]*$/.test(L)?`${O} ${L}`:O};function Qi(_){let I=(J)=>`${J.sessionId}
2
+ ${co(J.segment||J.command)}`,O=_.filter((J)=>J.decision!=="allow"),L=O.filter((J)=>J.sessionId).reduce((J,K)=>J.set(I(K),(J.get(I(K))??0)+1),new Map);return new Set(O.filter((J)=>J.failureStage||(L.get(I(J))??0)>=2))}import{existsSync as ku,readdirSync as xu,readFileSync as Su}from"node:fs";import{join as Cu}from"node:path";function zn(_,I){try{return xu(_,{withFileTypes:!0,encoding:"utf8"}).flatMap((O)=>{let L=Cu(_,O.name);if(O.isDirectory())return zn(L,I);if(O.name.endsWith(".jsonl"))return[L];return[]})}catch{if(I&&ku(_))I.count++;return[]}}var Ru=["segment","reason","sessionId","decision","agent","ruleId","failureStage"];function Pu(_){if(!_||typeof _!=="object"||Array.isArray(_))return!1;let I=_;if(typeof I.ts!=="string"||typeof I.command!=="string")return!1;return Ru.every((O)=>I[O]===void 0||typeof I[O]==="string")}function ht(_,I){try{return Su(_,"utf-8").split(`
3
+ `).filter(Boolean).flatMap((O)=>{try{let L=JSON.parse(O);if(!Pu(L)){if(I)I.count++;return[]}return[L]}catch{if(I)I.count++;return[]}})}catch{if(I)I.count++;return[]}}function hn(_){return Array.from(_,(I)=>{let O=I.charCodeAt(0);if(O<=31||O>=127&&O<=159)return`\\x${O.toString(16).padStart(2,"0")}`;return I}).join("")}function Lu(_,I){let O=re(_),L=gn({label:"logs",booleans:{all:["--all"],suspect:["--suspect"],json:["--json"],pruneLegacy:["--prune-legacy"],dryRun:["--dry-run"]},values:{id:["--id"],limit:["--limit"],since:["--since"],agent:["--agent"],rule:["--rule"],session:["--session"],project:["--project"]}},I);if(On(L.errors))return null;if(L.values.id!==void 0&&!/^[a-f0-9]{16}$/.test(L.values.id))return console.error("--id must be 16 hexadecimal characters"),null;let J=L.values.limit===void 0?20:es(L.values.limit);if(J===null)return console.error("--limit must be a positive number"),null;let K=L.values.since===void 0?Math.min(30,O):es(L.values.since);if(K===null||K>O)return console.error(`--since must be a positive number of days no greater than ${O}`),null;let ne={limit:J,limitExplicit:L.values.limit!==void 0,since:K,sinceExplicit:L.values.since!==void 0,all:L.flags.all,json:L.flags.json,suspect:L.flags.suspect,pruneLegacy:L.flags.pruneLegacy,dryRun:L.flags.dryRun,id:L.values.id,agent:L.values.agent,rule:L.values.rule,session:L.values.session,project:L.values.project===void 0?void 0:Ou(L.values.project)};if(ne.id&&(ne.agent!==void 0||ne.rule!==void 0||ne.session!==void 0||ne.project!==void 0||ne.suspect||ne.sinceExplicit||ne.limitExplicit))return console.error("--id cannot be combined with --agent, --rule, --session, --project, --suspect, --since, or --limit"),null;if(ne.pruneLegacy&&(ne.id!==void 0||ne.agent!==void 0||ne.rule!==void 0||ne.session!==void 0||ne.project!==void 0||ne.suspect||ne.all||ne.sinceExplicit||ne.limitExplicit))return console.error("--prune-legacy cannot be combined with --id, --agent, --rule, --session, --project, --suspect, --all, --since, or --limit"),null;if(ne.dryRun&&!ne.pruneLegacy)return console.error("--dry-run requires --prune-legacy"),null;return ne}async function rs(_,I,O={}){let L=Lu(_,I);if(!L)return 1;let J=O.logsDir??F(_);if(L.pruneLegacy)return Nu(J,L.json,L.dryRun);if(!J)return console.log(L.json?"[]":L.id?`No retained audit log entry found for id ${hn(L.id)}.`:"No audit log entries found."),0;q(_,J);let K={count:0},ne=zn(J,K).flatMap((xe)=>ht(xe,K).map((Se)=>({entry:Se,file:xe})));if(K.count>0)console.error(`warning: ${K.count} audit log ${K.count===1?"source":"sources"} could not be read; these results are incomplete`);if(L.id)return Mu(ne,L,O.timeZone);let oe=Date.now()-L.since*24*60*60*1000,de=ne.filter((xe)=>Uu(xe,L,J,oe)),ue=L.suspect?Qi(de.map((xe)=>xe.entry)):null,ve=(ue?de.filter((xe)=>ue.has(xe.entry)):de).sort((xe,Se)=>Date.parse(Se.entry.ts)-Date.parse(xe.entry.ts)).slice(0,L.limit);if(L.json)return console.log(JSON.stringify(ve.map((xe)=>xe.entry),null,2)),0;if(ve.length===0)return console.log("No audit log entries found."),0;for(let xe of ve)console.log(qu(xe.entry,O.timeZone));return 0}function Nu(_,I,O){let L=_?Fu(_).map((oe)=>Tu(_,oe)):[];if(O)return ju(L,I);let J=[],K=0,ne=0;for(let oe of L){let de=ns(oe,{throwIfNoEntry:!1})?.size??0,ue=Hu(oe);if(ue){J.push(`${ts(oe)}: ${ue}`);continue}K++,ne+=de}if(I)return console.log(JSON.stringify({removedFiles:K,removedBytes:ne,failedFiles:J.length})),J.length===0?0:1;console.log(K===0&&J.length===0?"No legacy audit log files found.":`Removed ${K} legacy audit log ${K===1?"file":"files"} (${os(ne)}).`);for(let oe of J)console.error(`Could not remove ${hn(oe)}`);if(console.log("Nested v2 audit logs were not changed."),K>0)console.log("This deletion cannot be undone.");return J.length===0?0:1}function ju(_,I){let O=_.reduce((L,J)=>L+(ns(J,{throwIfNoEntry:!1})?.size??0),0);if(I)return console.log(JSON.stringify({dryRun:!0,files:_.length,bytes:O})),0;if(console.log(_.length===0?"No legacy audit log files found.":`Would remove ${_.length} legacy audit log ${_.length===1?"file":"files"} (${os(O)}).`),console.log("Nested v2 audit logs are not included."),_.length>0)console.log("Run the same command without --dry-run to delete them.");return 0}function Fu(_){try{return Eu(_,{withFileTypes:!0}).filter((I)=>I.isFile()&&I.name.endsWith(".jsonl")).map((I)=>I.name)}catch{return[]}}function Hu(_){try{return Au(_),null}catch(I){return I instanceof Error?I.message:String(I)}}function os(_){let I=["B","KiB","MiB","GiB"],O=Math.min(Math.floor(Math.log2(Math.max(_,1))/10),I.length-1);return`${Math.round(_/1024**O*10)/10} ${I[O]}`}function Mu(_,I,O){let L=_.filter((K)=>K.entry.id===I.id);if(L.length>1)return console.error(`Multiple audit log entries found for id ${hn(I.id??"")}.`),1;if(I.json)return console.log(JSON.stringify(L.map((K)=>K.entry),null,2)),0;let J=L[0];if(!J)return console.log(`No retained audit log entry found for id ${hn(I.id??"")}.`),0;return console.log(Vu(J.entry,O)),0}function Uu(_,I,O,L){if(!I.all&&_.entry.decision==="allow")return!1;if(Date.parse(_.entry.ts)<L)return!1;if(I.agent!==void 0&&_.entry.agent!==I.agent)return!1;if(I.rule!==void 0&&_.entry.ruleId!==I.rule)return!1;if(I.session!==void 0&&!Gu(_,O,I.session))return!1;if(I.project!==void 0&&!Bu(_.entry.cwd,I.project))return!1;return!0}function Gu(_,I,O){if(_.entry.sessionId===O)return!0;return _u(_.file)===I&&ts(_.file,".jsonl")===O}function Bu(_,I){if(!_)return!1;let O=$u(I,_);return O!==".."&&!O.startsWith(`..${Du}`)&&!Iu(O)}function qu(_,I){let O=hn(_.id??"-"),L=hn(_.decision??"deny"),J=_.cwd?` [${hn(_.cwd)}]`:"",K=_.segment||_.command,ne=K===_.command?"":"↳ ",oe=K.length>50?`${K.slice(0,50)}…`:K;return`${O.padEnd(16)} ${hn(is(_.ts,I))} ${L.padEnd(5)} ${hn(_.agent??"-").padEnd(15)} ${hn(_.ruleId??"-").padEnd(20)} ${ne}${hn(oe)}${J}`}function Vu(_,I){let O=(J)=>hn(J===void 0||J===null||J===""?"-":J),L=_.shape?`${_.agent??"-"} (shape: ${_.shape})`:_.agent??"-";return[`id: ${O(_.id)}`,`ts: ${O(is(_.ts,I))}`,`decision: ${O(_.decision)}`,`agent: ${O(L)}`,`level: ${O(_.level)}`,`tool: ${O(_.toolName)}`,`rule: ${O(_.ruleId)}`,`intent: ${O(_.intent)}`,`stage: ${O(_.failureStage)}`,`error: ${O(_.errorCode)}`,`session: ${O(_.sessionId)}`,`cwd: ${O(_.cwd)}`,`version: ${O(_.v)}`,`truncated: ${O(_.truncated===!0?"yes":void 0)}`,`reason: ${O(_.reason)}`,`command: ${O(_.command)}`,`segment: ${O(_.segment)}`].join(`
4
+ `)}function is(_,I){let O=new Date(_);if(Number.isNaN(O.getTime()))return _;return new Intl.DateTimeFormat("sv-SE",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hourCycle:"h23",timeZone:I}).format(O)}function es(_){let I=Number(_);return Number.isFinite(I)&&I>0?I:null}var ss={name:"doctor",aliases:["--doctor"],description:"Run diagnostic checks to verify installation and configuration",usage:"doctor [options]",options:[{flags:"--json",description:"Output diagnostics as JSON"},{flags:"--skip-update-check",description:"Skip npm registry version check"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net doctor","cc-safety-net doctor --json","cc-safety-net doctor --skip-update-check"]};var as={name:"explain",description:"Show step-by-step analysis trace of how a command would be analyzed",usage:"explain [options] <command>",argument:"<command>",options:[{flags:"--json",description:"Output analysis as JSON"},{flags:"--cwd",argument:"<path>",description:"Use custom working directory"},{flags:"-h, --help",description:"Show this help"}],examples:['cc-safety-net explain "git reset --hard"','cc-safety-net explain --json "rm -rf /"','cc-safety-net explain --cwd /tmp "git status"']};var ls={name:"gui",description:"Open the local policy editor GUI",usage:"gui [options]",options:[{flags:"--no-open",description:"Print the URL without opening a browser"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net gui","cc-safety-net gui --no-open"]};var uo=["npx","--offline","--no-install","@deepseek-ai/dsh","--version"],ir=[{id:"antigravity-cli",displayName:"Antigravity CLI",doctorOrder:3,runtime:{order:1,flags:["-ac","--agy-cli"],description:"Run as Antigravity CLI PreToolUse hook",legacyTopLevelFlags:[]},install:{order:2,flag:"--agy-cli",artifactKind:"hook config",probeCommand:["agy","--version"]}},{id:"claude-code",displayName:"Claude Code",doctorOrder:1,runtime:{order:2,displayName:"Coding CLI",flags:["-cc","--coding-cli"],legacyFlags:["--claude-code"],description:"Run as Coding CLI PreToolUse hook",legacyTopLevelFlags:["-cc","--claude-code"]},install:{order:3,flag:"--claude-code",artifactKind:"plugin",probeCommand:["claude","--version"]}},{id:"codex",displayName:"Codex",doctorOrder:4,runtime:{order:3,flags:["-cx","--codex"],description:"Run as a Codex PreToolUse hook",legacyTopLevelFlags:[]},install:{order:4,flag:"--codex",artifactKind:"plugin",probeCommand:["codex","--version"]}},{id:"copilot-cli",displayName:"GitHub Copilot CLI",doctorOrder:8,runtime:{order:6,flags:["-cp","--copilot-cli"],description:"Run as GitHub Copilot CLI PreToolUse hook",legacyTopLevelFlags:["-cp","--copilot-cli"]},install:{order:8,flag:"--copilot-cli",artifactKind:"plugin",probeCommand:["copilot","--binary-version"]}},{id:"gemini-cli",displayName:"Gemini CLI",doctorOrder:7,runtime:{order:5,flags:["-gc","--gemini-cli"],description:"Run as Gemini CLI BeforeTool hook",legacyTopLevelFlags:["-gc","--gemini-cli"]},install:{order:7,flag:"--gemini-cli",artifactKind:"extension",probeCommand:["gemini","--version"]}},{id:"grok-build",displayName:"Grok Build",doctorOrder:9,runtime:{order:7,flags:["-gb","--grok-build"],description:"Run as Grok Build PreToolUse hook",legacyTopLevelFlags:[]},install:{order:9,flag:"--grok-build",artifactKind:"hook config",probeCommand:["grok","--version"]}},{id:"hermes-agent",displayName:"Hermes Agent",doctorOrder:10,runtime:{order:8,flags:["-ha","--hermes-agent"],description:"Run as Hermes Agent pre_tool_call hook",legacyTopLevelFlags:[]},install:{order:10,flag:"--hermes-agent",artifactKind:"plugin",probeCommand:["hermes","--version"]}},{id:"kimi-code",displayName:"Kimi Code",doctorOrder:11,runtime:{order:9,flags:["-kc","--kimi-code"],description:"Run as Kimi Code PreToolUse hook",legacyTopLevelFlags:[]},install:{order:11,flag:"--kimi-code",artifactKind:"hook config",probeCommand:["kimi","--version"]}},{id:"openclaw",displayName:"OpenClaw",doctorOrder:12,install:{order:12,flag:"--openclaw",artifactKind:"plugin",probeCommand:["openclaw","--version"]}},{id:"opencode",displayName:"OpenCode",doctorOrder:13,install:{order:13,flag:"--opencode",artifactKind:"plugin",probeCommand:["opencode","--version"]}},{id:"pi",displayName:"Pi",doctorOrder:14,install:{order:14,flag:"--pi",artifactKind:"package",probeCommand:["pi","--version"]}},{id:"cursor",displayName:"Cursor",doctorOrder:5,runtime:{order:4,flags:["-cu","--cursor"],description:"Run as Cursor preToolUse hook",legacyTopLevelFlags:[]},install:{order:5,flag:"--cursor",artifactKind:"hook config",probeCommand:["cursor","--version"]}},{id:"deepseek-harness",displayName:"DeepSeek Harness",doctorOrder:6,install:{order:6,flag:"--deepseek-harness",artifactKind:"package",probeCommand:uo}},{id:"amp",displayName:"Amp Code",doctorOrder:2,install:{order:1,flag:"--amp",artifactKind:"plugin",probeCommand:["amp","--version"]}}],sr=ir.slice().sort((_,I)=>_.doctorOrder-I.doctorOrder).map((_)=>_.id),It=ir.filter((_)=>("runtime"in _)).slice().sort((_,I)=>_.runtime.order-I.runtime.order).map((_)=>({id:_.id,displayName:"displayName"in _.runtime?_.runtime.displayName:_.displayName,flags:_.runtime.flags,legacyFlags:"legacyFlags"in _.runtime?_.runtime.legacyFlags:[],description:_.runtime.description,legacyTopLevelFlags:_.runtime.legacyTopLevelFlags})),En=ir.slice().sort((_,I)=>_.install.order-I.install.order).map((_)=>({id:_.id,..._.install})).map(({order:_,...I})=>I),zu=Object.fromEntries(ir.map((_)=>[_.id,_.displayName]));function pn(_){return zu[_]}var Ju=It.map((_)=>({flags:_.flags.join(", "),description:_.description})),Wu=It.flatMap((_)=>_.flags.map((I)=>`cc-safety-net hook ${I}`)),cs={name:"hook",description:"Run as an agent CLI hook (reads JSON from stdin)",usage:"hook INTEGRATION_FLAG",options:[...Ju,{flags:"-h, --help",description:"Show this help"}],examples:Wu};var ds={name:"install",description:"Install CC Safety Net into a coding agent CLI",usage:"install [TARGET_FLAG]",options:[...En.map((_)=>({flags:_.flag,description:`Install ${pn(_.id)} ${_.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net install",...En.map((_)=>`cc-safety-net install ${_.flag}`)]},us={name:"uninstall",description:"Uninstall CC Safety Net from a coding agent CLI",usage:"uninstall [TARGET_FLAG]",options:[...En.map((_)=>({flags:_.flag,description:`Uninstall ${pn(_.id)} ${_.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net uninstall",...En.map((_)=>`cc-safety-net uninstall ${_.flag}`)]},ps={name:"update",description:"Update every installed CC Safety Net integration to the latest version",usage:"update",options:[{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net update"]};var fs={name:"logs",description:"Browse audit log entries recorded by hooks",usage:"logs [options]",options:[{flags:"--id",argument:"<id>",description:"Show one entry from retained history by its 16-character id (not guaranteed once it is older than the configured retention)"},{flags:"--limit",argument:"<n>",description:"Maximum entries to print",default:"20"},{flags:"--since",argument:"<days>",description:"Only include entries newer than this many days (max: the configured audit retention, 1-365)",default:"30"},{flags:"--agent",argument:"<name>",description:"Filter by agent name"},{flags:"--rule",argument:"<ruleId>",description:"Filter by rule id"},{flags:"--session",argument:"<id>",description:"Filter by session id"},{flags:"--project",argument:"<path>",description:"Filter by project path"},{flags:"--suspect",description:"Only denials that look like false positives"},{flags:"--all",description:"Include allow entries"},{flags:"--prune-legacy",description:"Permanently delete all legacy root-level logs; nested logs are untouched"},{flags:"--dry-run",description:"With --prune-legacy, report what would be deleted and delete nothing"},{flags:"--json",description:"Output entries as JSON"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net logs --id 3fa9c2d1a70e8b42","cc-safety-net logs --agent claude-code","cc-safety-net logs --project . --since 7","cc-safety-net logs --suspect --since 7","cc-safety-net logs --json","cc-safety-net logs --prune-legacy --dry-run","cc-safety-net logs --prune-legacy"]};var ar={name:"policy",description:"Check and apply project or user policy proposals",usage:"policy <subcommand>",subcommands:[{usage:"check <file>",description:"Validate a policy proposal and print its diff"},{usage:"apply <file>",description:"Apply a proposal after confirming in a terminal"}],options:[{flags:"-g, --global",description:"Use the user-scope policy instead of the project one"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net policy check proposal.json","cc-safety-net policy apply proposal.json","cc-safety-net policy apply proposal.json --global"]};var po=[{flags:"--ref",argument:"<ref>",description:"Use a branch, tag, or commit"},{flags:"--only",argument:"<rulebook...>",description:"Add only these repository rulebooks"},{flags:"-g, --global",description:"Use user-scope rule config"},{flags:"-h, --help",description:"Show this help"}],fo=["cc-safety-net rule add project-rules","cc-safety-net rule add acme/safety-rules","cc-safety-net rule add acme/safety-rules --only aws gcloud","cc-safety-net rule add acme/safety-rules --ref v2 --only aws","cc-safety-net rule add --only terraform aws"],yt={name:"rule",description:"Manage CC Safety Net rule config and rulebook sources",usage:"rule <subcommand>",subcommands:[{usage:"init [--example]",description:"Create inert rule config"},{usage:"add [source] [--ref <ref>] [--only <rulebook...>]",description:"Add rulebook sources and sync"},{usage:"remove <source>",description:"Remove a rulebook source and sync"},{usage:"update [source]",description:"Re-fetch and vendor remote rulebooks"},{usage:"sync",description:"Deprecated: migrate lock and cache leftovers"},{usage:"list",description:"List active rulebooks"},{usage:"wrapper add <command>",description:"Trust a transparent command wrapper"},{usage:"wrapper remove <command>",description:"Remove a transparent command wrapper"},{usage:"wrapper list",description:"List transparent command wrappers"},{usage:"migrate [--cleanup]",description:"Migrate legacy inline rules"},{usage:"doc",description:"Print the rulebook authoring guide"},{usage:"verify",description:"Validate rule config files"}],options:[{flags:"-g, --global",description:"Use user-scope rule config"},{flags:"--cleanup",description:"Delete legacy files after rule migrate verifies them"},{flags:"--delete-source",description:"Delete clean local source directory on remove"},{flags:"--example",description:"Create an inactive example rulebook with rule init"},...po.slice(0,2),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net rule init","cc-safety-net rule init --example","cc-safety-net rule wrapper add rtk",...fo,"cc-safety-net rule update","cc-safety-net rule migrate --cleanup","cc-safety-net rule verify"]};var ms={name:"status",description:"Show what the runtime is enforcing right now",usage:"status",options:[{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net status"]};var gs={name:"statusline",description:"Print status line with mode indicators for shell integration",usage:"statusline --claude-code",options:[{flags:"-cc, --claude-code",description:"Print status line for Claude Code"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net statusline -cc","cc-safety-net statusline --claude-code"]};var lr=[ms,ss,fs,as,yt,ar,ds,ps,us,cs,ls,gs];function Ku(_){return _.aliases??[]}function cr(_){let I=_.toLowerCase();return lr.find((O)=>O.name.toLowerCase()===I||Ku(O).some((L)=>L.toLowerCase()===I))}import{basename as Yu}from"node:path";function dr(_,I=7,O=F(_)){let L=Date.now()-I*24*60*60*1000,J=[],K=new Set,ne=0,oe,de,ue,ve;if(O)q(_,O);let xe={count:0},Se=O?zn(O,xe):[];for(let we of Se)for(let Le of ht(we,xe)){if(Le.decision==="allow")continue;let en=new Date(Le.ts).getTime();if(en>=L){if(ne++,K.add(Le.sessionId??Yu(we,".jsonl")),de===void 0||en<=de)oe=Le.ts,de=en;if(ve===void 0||en>ve)ue=Le.ts,ve=en;Zu(J,Le,en)}}let Pe=J.map((we)=>({timestamp:we.ts,command:we.command,reason:we.reason,relativeTime:Xi(new Date(we.ts))}));return{totalBlocked:ne,sessionCount:K.size,recentEntries:Pe,oldestEntry:oe,newestEntry:ue,unreadable:xe.count}}function Zu(_,I,O){let L=_.findIndex((J)=>O>new Date(J.ts).getTime());if(L===-1){if(_.length<3)_.push(I);return}if(_.splice(L,0,I),_.length>3)_.pop()}import{dirname as cp}from"node:path";import{dirname as Xu,join as Qu,resolve as ep}from"node:path";var np="config.json";function bn(_,I,O,L){g(tp(_),`${JSON.stringify(I,null,2)}
5
+ `,O,L)}function tp(_){return typeof _==="string"?ie(_):_}function go(_){return{errors:ae(op(_),": "," "),ruleNames:new Set(Oe(_).map((I)=>I.toLowerCase()))}}var rp="must match pattern (letters, numbers, hyphens, underscores; max 64 chars)",hs="must match pattern (letters, numbers, hyphens, underscores)";function op(_){if(!ys(_))return[e([],"Config must be an object")];return[..._.version===1?[]:[e(["version"],"must be 1")],...ip(_.rules)]}function ip(_){if(_===void 0)return[];if(!Array.isArray(_))return[e(["rules"],"must be an array")];return[..._.flatMap((I,O)=>ys(I)?sp(I,["rules",O]):[e(["rules",O],"must be an object")]),...Ie(_)]}function sp(_,I){return[...mo(_.name,[...I,"name"],"required string",u,rp),...mo(_.command,[...I,"command"],"required string",w,hs),..._.subcommand===void 0?[]:mo(_.subcommand,[...I,"subcommand"],"must be a string if provided",w,hs),...ap(_.block_args,[...I,"block_args"]),...lp(_.reason,[...I,"reason"]),..._.intent===void 0||Re(_.intent)?[]:[e([...I,"intent"],ke)]]}function mo(_,I,O,L,J){if(typeof _!=="string")return[e(I,O)];return L.test(_)?[]:[e(I,J)]}function ap(_,I){if(!Array.isArray(_))return[e(I,"required array")];if(_.length===0)return[e(I,"must have at least one element")];return _.flatMap((O,L)=>{if(typeof O!=="string")return[e([...I,L],"must be a string")];return O===""?[e([...I,L],"must not be empty")]:[]})}function lp(_,I){if(typeof _!=="string")return[e(I,"required string")];if(_==="")return[e(I,"must not be empty")];return _.length>P?[e(I,`must be at most ${P} characters`)]:[]}function ys(_){return!!_&&typeof _==="object"&&!Array.isArray(_)}function ho(_){let I=vs(_);if(!I.ok)return I.result;return go(I.parsed)}function vs(_){let I=[],O=new Set;try{let L=typeof _==="string"?ie(_):_,J=n(L);if(J===null)return I.push(`File not found: ${L.path}`),{ok:!1,result:{errors:I,ruleNames:O}};if(!J.trim())return I.push("Config file is empty"),{ok:!1,result:{errors:I,ruleNames:O}};return{ok:!0,parsed:JSON.parse(J)}}catch(L){if(L instanceof r)return I.push(L.message),{ok:!1,result:{errors:I,ruleNames:O}};let J=L instanceof Error?L.message:String(L);return I.push(L instanceof SyntaxError?"Invalid JSON":J),{ok:!1,result:{errors:I,ruleNames:O}}}}function bs(_){return ep(_,".safety-net.json")}function Un(_){let I=vs(_);if(!I.ok)return I.result;let O=Ye(I.parsed);return{errors:O.errors,ruleNames:O.sources}}function ur(_,I={}){return Qu(Xu(Ee(_,I)),np)}function ws(_,I,O){let L;try{if(n(I)===null)return{path:_,exists:!1,valid:!1,ruleCount:0};L=Un(I),L.errors.push(...H(_,O))}catch(J){if(!(J instanceof r))throw J;L={errors:[J.message],ruleNames:new Set}}return{path:_,exists:!0,valid:L.errors.length===0,ruleCount:L.ruleNames.size,...L.errors.length>0?{errors:L.errors}:{}}}function dp(_,I){return{source:I,name:_.name,command:_.command,subcommand:_.subcommand,blockArgs:[..._.block_args],reason:_.reason}}function ks(_,I){let O=G(_),L=U(I),J=cp(O),K=X(_,{cwd:I,userConfigPath:O,projectConfigPath:L,userConfigDir:J}),ne=Z(_,{cwd:I,userConfigPath:O,projectConfigPath:L,userConfigDir:J}),oe=new Map(K.rulebooks.flatMap((de)=>de.rules.map((ue)=>[ue,de.source])));return{userConfig:ws(O,ne.userConfigTarget,ne.userScope),projectConfig:ws(L,ne.projectConfigTarget,ne.projectScope),effectiveRules:K.rules.map((de)=>dp(de,oe.get(de.name)??"project"))}}var up=[{flag:o.level,description:"Safety level preset: standard, strict, or paranoid",defaultBehavior:"standard"},{flag:o.strict,description:"Legacy; equivalent to safety.overrides.fail_closed",defaultBehavior:"permissive"},{flag:o.paranoid,description:"Legacy; equivalent to safety.overrides.paranoid_rm and paranoid_interpreters",defaultBehavior:"off"},{flag:o.paranoidRm,description:"Legacy; equivalent to safety.overrides.paranoid_rm",defaultBehavior:"off"},{flag:o.paranoidInterpreters,description:"Legacy; equivalent to safety.overrides.paranoid_interpreters",defaultBehavior:"off"},{flag:o.worktree,description:"Allow local git discards in linked worktrees",defaultBehavior:"off"},{flag:o.debug,description:"Print diagnostic messages to stderr",defaultBehavior:"off"},{flag:o.auditScope,description:"Command decisions recorded: all, or blocked (privacy-minimizing, denials only)",defaultBehavior:"all"}];function xs(_){return[...up.map((I)=>({name:I.flag.name,value:Ce(I.flag,_.env),isSet:rt(I.flag,_.env),legacyName:I.flag.legacyName,legacyValue:I.flag.legacyName?_.env.get(I.flag.legacyName):void 0,legacyIsSet:I.flag.legacyName?_.env.get(I.flag.legacyName)!==void 0:void 0,description:I.description,defaultBehavior:I.defaultBehavior})),{name:"CC_SAFETY_NET_HOME",value:_.env.get("CC_SAFETY_NET_HOME"),isSet:_.env.get("CC_SAFETY_NET_HOME")!==void 0,description:"Override user-scope config/cache directory",defaultBehavior:"~/.cc-safety-net"}]}var Ss={error:0,warning:1,info:2},pp=["policy","config","audit"];function fp(_){return _.map((I)=>{if(I==="ownership")return"is not owned by the current user";if(I==="permissions")return"has unsafe permissions";if(I==="symlink")return"is a symbolic link";return"is not a directory"}).join(" and ")}var mp=[{derive:(_)=>_.hooks.length>0&&_.hooks.every((I)=>!I.configured)?[{checkId:"integration.none-configured",severity:"error",title:"No integration configured",detail:"CC Safety Net is not connected to any supported coding-agent integration.",fixHint:"Run `cc-safety-net install` and configure at least one integration."}]:[]},{derive:(_)=>_.hooks.filter((I)=>I.inspectionStatus==="failed").map((I)=>{let O=pn(I.platform);return{checkId:"integration.inspection-failed",severity:"error",title:`${O} inspection failed`,detail:`Doctor could not verify the ${O} integration configuration.`,fixHint:`Correct the reported ${O} configuration error, then run \`cc-safety-net doctor\` again.`,integration:I.platform}})},{derive:(_)=>_.userConfig.exists&&!_.userConfig.valid?[{checkId:"config.user-invalid",severity:"error",title:"User configuration is invalid",detail:"Doctor could not load a valid user rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:_.userConfig.path}]:[]},{derive:(_)=>_.projectConfig.exists&&!_.projectConfig.valid?[{checkId:"config.project-invalid",severity:"error",title:"Project configuration is invalid",detail:"Doctor could not load a valid project rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:_.projectConfig.path}]:[]},{derive:(_)=>_.configState.state==="degraded"?[{checkId:"config.runtime-degraded",severity:"warning",title:"Runtime is enforcing a fallback configuration",detail:`The rejected candidate configuration is not active: ${_.configState.reason}`,fixHint:"Fix the file named in the reason, or run `cc-safety-net rule update` to vendor a remote source, then rerun doctor."}]:[]},{derive:(_)=>_.v2Leftovers&&_.v2Leftovers.length>0?[{checkId:"config.v2-leftovers",severity:"info",title:"Rulebook lock and cache leftovers detected",detail:`Files an earlier version left behind are no longer read: ${_.v2Leftovers.join(", ")}.`,fixHint:"Run `cc-safety-net rule sync` (add `--global` for user scope) to migrate them, then rerun doctor."}]:[]},{derive:(_)=>{let I=_.environment.find((O)=>O.name==="CC_SAFETY_NET_AUDIT_SCOPE");return ze(I?.value)==="invalid"?[{checkId:"environment.audit-scope-invalid",severity:"warning",title:"Audit scope value is invalid",detail:"CC_SAFETY_NET_AUDIT_SCOPE is not `all` or `blocked`, so allowed command decisions are not recorded.",fixHint:"Set CC_SAFETY_NET_AUDIT_SCOPE to `all` or `blocked`, then restart the integration."}]:[]}},...pp.map((_)=>({derive:(I)=>I.posture.directories.filter((O)=>O.kind===_&&O.status==="unsafe").map((O)=>({checkId:`posture.${_}-directory-unsafe`,severity:"error",title:`${_[0]?.toUpperCase()}${_.slice(1)} directory is unsafe`,detail:`The ${_} directory ${fp(O.issues)}.`,fixHint:"Ensure this is a real directory owned by the current user with no group or other write access, then rerun doctor.",...O.path?{path:O.path}:{}}))})),{derive:(_)=>{let I=[..._.effectiveSafety.weakenedRuleOverrides].sort();return I.length>0?[{checkId:"posture.rule-overrides-weaken-preset",severity:"warning",title:"Rule overrides weaken the selected preset",detail:`Explicit overrides disable rules the resolved preset would enable: ${I.join(", ")}.`,fixHint:`Remove these \`off\` overrides or set them to \`on\`: ${I.join(", ")}.`}]:[]}}];function Cs(_){return mp.flatMap((I,O)=>I.derive(_).map((L,J)=>({finding:L,catalogOrder:O,occurrence:J}))).sort((I,O)=>Ss[I.finding.severity]-Ss[O.finding.severity]||I.catalogOrder-O.catalogOrder||I.occurrence-O.occurrence).map((I)=>I.finding)}function Dn(){return Boolean(process.stdout.isTTY&&!process.env.NO_COLOR)}var gp=(_)=>Dn()?`\x1B[32m${_}\x1B[0m`:_,hp=(_)=>Dn()?`\x1B[33m${_}\x1B[0m`:_,yp=(_)=>Dn()?`\x1B[34m${_}\x1B[0m`:_,vp=(_)=>Dn()?`\x1B[36m${_}\x1B[0m`:_,bp=(_)=>Dn()?`\x1B[31m${_}\x1B[0m`:_,wp=(_)=>Dn()?`\x1B[2m${_}\x1B[0m`:_,kp=(_)=>Dn()?`\x1B[1m${_}\x1B[0m`:_,nn={green:gp,yellow:hp,blue:yp,cyan:vp,red:bp,dim:wp,bold:kp},xp="\x1B[0m",Sp=[39,82,198,226,208,51,196,46,201,214,93,154,220,27,49,190,200,33,129,227,45,160,63,118,123,202];function Cp(_){let I=_;return()=>(I=(I*1664525+1013904223)%4294967296,I/4294967296)}function Rp(_){let I=[...Sp],O=Cp(_);for(let L=I.length-1;L>0;L--){let J=Math.floor(O()*(L+1)),K=I[L];I[L]=I[J],I[J]=K}return I}function Pp(_,I=0){if(!Dn())return"";let O=Rp(I);return`\x1B[38;5;${O[_%O.length]}m`}function Rs(_,I,O=0){if(!Dn())return`"${_}"`;return`${Pp(I,O)}"${_}"${xp}`}function pr(_){return _==="default"?"built-in default":`${_} policy`}var Ep=new RegExp("\x1B\\[[0-9;]*m","g"),yo=(_)=>_.replace(Ep,"").length;function Jn(_){let I=(_.headers??_.rows[0]??[]).map((ne,oe)=>{let de=Math.max(..._.rows.map((ue)=>yo(ue[oe]??"")));return Math.max(yo(ne),de)}),O=(ne,oe)=>ne+" ".repeat(Math.max(0,oe-yo(ne))),L=(ne,oe)=>oe[0]+I.map((de)=>ne.repeat(de+2)).join(oe[1])+oe[2],J=(ne)=>`│ ${ne.map((oe,de)=>O(oe,I[de]??0)).join(" │ ")} │`,K=_.headers?[` ${J(_.headers)}`,` ${L("─",["├","┼","┤"])}`]:[];return[` ${L("─",["┌","┬","┐"])}`,...K,..._.rows.map((ne)=>` ${J(ne)}`),` ${L("─",["└","┴","┘"])}`].join(`
6
+ `)}function Ps(_){let I=[];I.push("Hook Integration"),I.push(Ap(_));let O=[],L=[];for(let J of _){let K=pn(J.platform);if(J.errors&&J.errors.length>0)for(let ne of J.errors)if(J.configured)O.push({platform:K,message:ne});else L.push({platform:K,message:ne})}for(let J of O)I.push(` Warning (${J.platform}): ${J.message}`);for(let J of L)I.push(nn.red(` Error (${J.platform}): ${J.message}`));return I.join(`
7
+ `)}function Ap(_){let I=["Platform","Discovery","Configuration","Inspection"],O=_.map((L)=>{let J=pn(L.platform);if(L.inspectionStatus==="not-inspected"){let de=nn.dim("Not inspected");return[J,de,de,de]}let K=L.detected?nn.green("Detected"):L.inspectionStatus==="failed"?nn.red("Unknown"):nn.dim("Not detected"),ne=L.configured?nn.green("Configured"):L.detected?nn.yellow("Not configured"):L.inspectionStatus==="failed"?nn.red("Unknown"):nn.dim("Not applicable"),oe=L.inspectionStatus==="verified"?nn.green("Verified"):L.inspectionStatus==="failed"?nn.red("Failed"):nn.dim("Not applicable");return[J,K,ne,oe]});return Jn({headers:I,rows:O})}function Es(_){let O=["Guard Engine Verification",` Synthetic self-test: ${_.failed>0?nn.red(`${_.passed}/${_.total} FAIL`):nn.green(`${_.passed}/${_.total} passed`)}`],L=_.results.filter((J)=>!J.passed);if(L.length>0){O.push(""),O.push(nn.red(" Failures:"));for(let J of L)O.push(nn.red(` • ${J.description}`)),O.push(nn.red(` expected ${J.expected}, got ${J.actual}`))}return O.join(`
8
+ `)}function _p(_){if(_.length===0)return" (no custom rules)";let I=["Source","Name","Command","Block Args"],O=_.map((L)=>[L.source,L.name,L.subcommand?`${L.command} ${L.subcommand}`:L.command,L.blockArgs.join(", ")]);return Jn({headers:I,rows:O})}function As(_){let I=[];if(I.push("Configuration"),I.push(Ip(_.userConfig,_.projectConfig)),I.push(""),_.effectiveRules.length>0)I.push(` Effective rules (${_.effectiveRules.length} total):`),I.push(_p(_.effectiveRules));else I.push(" Effective rules: (none - using built-in rules only)");return I.join(`
9
+ `)}function Ip(_,I){let O=["Scope","Status"],L=(K)=>{if(!K.exists)return nn.dim("N/A");if(!K.valid)return nn.red(`Invalid (${K.errors?.[0]??"unknown error"})`);return nn.green("Configured")},J=[["User",L(_)],["Project",L(I)]];return Jn({headers:O,rows:J})}function _s(_){let I=[];return I.push("Environment"),I.push(Tp(_)),I.join(`
10
+ `)}function Is(_){let I=_.effectiveSafety.policyScopes,O=["Effective Safety",` Selected preset: ${_.effectiveSafety.selectedPreset}${I?` (${pr(I.levelScope)})`:""}`,` Effective: ${_.effectiveSafety.level}`],L=[["fail_closed","fail_closed"],["paranoid_rm","paranoid_rm"],["paranoid_interpreters","paranoid_interpreters"]];for(let[J,K]of L){let ne=_.effectiveSafety.capabilities[J],oe=ne.enabled?nn.green("ON"):nn.dim("OFF"),de=ne.sources.length>0?` (${ne.sources.join(", ")})`:"";O.push(` ${K}: ${oe} via ${ne.source}${de}`)}if(I&&I.weakenings.length>0){O.push(" Project policy deltas:");for(let J of I.weakenings)O.push(` ${J}`)}O.push(` Stored rule customizations: ${_.effectiveSafety.ruleCounts.stored}`),O.push(` Effective rule customizations: ${_.effectiveSafety.ruleCounts.effective}`);for(let[J,K]of Object.entries(_.effectiveSafety.ruleOverrides))O.push(` ${J}: ${K}`);return O.join(`
11
+ `)}function Ts(_){let I=["Findings"];if(_.length===0)return I.push(" No findings from inspected doctor facts."),I.join(`
12
+ `);for(let O of _){let L=`[${O.severity.toUpperCase()}] ${O.checkId}: ${hn(O.title)}`,J=O.severity==="error"?nn.red:O.severity==="warning"?nn.yellow:nn.blue;if(I.push(` ${J(L)}`),I.push(` ${hn(O.detail)}`),O.path)I.push(` Path: ${hn(O.path)}`);if(O.fixHint)I.push(` Fix: ${hn(O.fixHint)}`)}return I.join(`
13
+ `)}function Tp(_){let I=["Variable","Status","Legacy"],O=_.map((L)=>{let J=L.isSet?nn.green("✓"):nn.dim("✗"),K=L.legacyName&&L.legacyIsSet?`${L.legacyName} ${nn.green("✓")}`:L.legacyName??"";return[L.name,J,K]});return Jn({headers:I,rows:O})}function $s(_){let I=[];if(_.totalBlocked===0)I.push("Recent Activity"),I.push(" No blocked commands in the last 7 days"),I.push(" Tip: This is normal for new installations");else I.push(`Recent Activity · last 7 days (${_.totalBlocked} blocked / ${_.sessionCount} sessions)`),I.push($p(_.recentEntries));if(_.unreadable>0)I.push(` Warning: ${_.unreadable} audit log ${_.unreadable===1?"source":"sources"} could not be read; this summary is incomplete`);return I.join(`
14
+ `)}function $p(_){let I=["Time","Command"],O=_.map((L)=>{let J=hn(L.command.replace(/\r\n|\r|\n/g," ↵ ").replace(/\t/g," ")),K=J.length>40?`${J.slice(0,37)}...`:J;return[L.relativeTime,K]});return Jn({headers:I,rows:O})}function Os(_){let I=[];if(I.push("Update Check"),_.latestVersion===null&&!_.error)return I.push(fr([["Status",nn.dim("Skipped")],["Installed",_.currentVersion]])),I.join(`
15
+ `);if(_.error)return I.push(fr([["Status",`${nn.yellow("⚠")} Error`],["Installed",_.currentVersion],["Error",nn.dim(_.error)]])),I.join(`
16
+ `);if(_.updateAvailable)return I.push(fr([["Status",`${nn.yellow("⚠")} Update Available`],["Current",_.currentVersion],["Latest",nn.green(_.latestVersion??"")]])),I.push(""),I.push(" Run: bunx cc-safety-net@latest doctor"),I.push(" Or: npx cc-safety-net@latest doctor"),I.join(`
17
+ `);return I.push(fr([["Status",`${nn.green("✓")} Up to date`],["Version",_.currentVersion]])),I.join(`
18
+ `)}function fr(_){return Jn({rows:_})}function Ds(_){let I=[];return I.push("System Info"),I.push(Op(_)),I.join(`
19
+ `)}function Op(_){let I=["Component","Version"],O=(K)=>{if(K===null)return nn.dim("not found");return K},J=[{label:"cc-safety-net",value:_.version},...sr.map((K)=>({label:pn(K),value:_.versions[K]??null})),{label:"Node.js",value:_.nodeVersion},{label:"npm",value:_.npmVersion},{label:"Bun",value:_.bunVersion},{label:"Platform",value:_.platform}].map((K)=>[K.label,O(K.value)]);return Jn({headers:I,rows:J})}function Ls(_){if(_.findings.length===0)return nn.green(`
20
+ No findings from inspected doctor facts.`);let I={error:_.findings.filter((K)=>K.severity==="error").length,warning:_.findings.filter((K)=>K.severity==="warning").length,info:_.findings.filter((K)=>K.severity==="info").length},O=["error","warning","info"].filter((K)=>I[K]>0).map((K)=>`${I[K]} ${K}`),L=_.findings.length===1?"finding":"findings",J=`
21
+ ${_.findings.length} ${L}: ${O.join(", ")}.`;if(I.error>0)return nn.red(J);if(I.warning>0)return nn.yellow(J);return nn.blue(J)}import{lstatSync as Dp}from"node:fs";import{dirname as vo}from"node:path";function bo(_,I){try{let O=Dp(I);if(O.isSymbolicLink())return{kind:_,path:I,status:"unsafe",issues:["symlink"]};if(!O.isDirectory())return{kind:_,path:I,status:"unsafe",issues:["not-directory"]};if(process.platform==="win32"||typeof process.getuid!=="function")return{kind:_,path:I,status:"unknown",issues:[]};let L=[...O.uid!==process.getuid()?["ownership"]:[],...(O.mode&18)!==0?["permissions"]:[]];return{kind:_,path:I,status:L.length>0?"unsafe":"safe",issues:L}}catch(O){if(typeof O==="object"&&O!==null&&"code"in O&&O.code==="ENOENT")return{kind:_,path:I,status:"not-applicable",issues:[]};return{kind:_,path:I,status:"unknown",issues:[]}}}function Ns(_,I){let O=F(_);return{directories:[bo("policy",vo(vo(I))),bo("config",vo(I)),...O?[bo("audit",O)]:[{kind:"audit",status:"unknown",issues:[]}]]}}import{spawn as Lp}from"node:child_process";import{existsSync as js}from"node:fs";import{delimiter as Np,extname as jp,join as Fp}from"node:path";import{stripVTControlCharacters as Fs}from"node:util";var Ms="2.5.0",Hp=5000,Mp="_CC_SAFETY_NET_TEST_SPAWN_PLATFORM";function fn(){return Ms}function wo(_,I){let O=_[I];if(O)return O;let L=Object.keys(_).find((J)=>J.toLowerCase()===I.toLowerCase()&&!!_[J]);return L?_[L]:O}function Up(_){return(wo(_,"PATHEXT")||".COM;.EXE;.BAT;.CMD").split(";").filter((I)=>I.length>0)}function Gp(_,I){let O=jp(_)?[_]:[...Up(I).map((L)=>`${_}${L}`),_];if(_.includes("/")||_.includes("\\"))return O.find((L)=>js(L))??_;return(wo(I,"PATH")??"").split(Np).flatMap((L)=>O.map((J)=>Fp(L,J))).find((L)=>js(L))??_}function Hs(_){if(!/[\s"&|<>^]/.test(_))return _;return`"${_.replace(/"/g,'""')}"`}function Wn(_,I){let[O,...L]=_,J=I[Mp]==="win32"?"win32":process.platform;if(!O||J!=="win32")return{cmd:O??"",args:L};let K=Gp(O,I);if(!/\.(?:bat|cmd)$/i.test(K))return{cmd:K,args:L};return{cmd:wo(I,"COMSPEC")??"cmd.exe",args:["/d","/c",["call",Hs(K),...L.map(Hs)].join(" ")]}}var vt=async(_,I=Hp)=>{let O=await Bp(_,{timeoutMs:I});if(O.code!==0)return null;return Fs(O.stdout).trim()||Fs(O.stderr).trim()||null};function Bp(_,I){let[O,...L]=_;if(!O)return Promise.resolve({code:null,stdout:"",stderr:""});return new Promise((J)=>{try{let K=Wn([O,...L],process.env),ne=Lp(K.cmd,K.args,{stdio:["ignore","pipe","pipe"]}),oe=!1,de="",ue="";ne.stdout.on("data",(Se)=>{de+=Se.toString()}),ne.stderr.on("data",(Se)=>{ue+=Se.toString()});let ve=(Se)=>{if(oe)return;oe=!0,clearTimeout(xe),J(Se)},xe=setTimeout(()=>{ne.kill(),ve({code:null,stdout:de,stderr:ue})},I.timeoutMs);ne.on("close",(Se)=>{ve({code:Se,stdout:de,stderr:ue})}),ne.on("error",()=>{ve({code:null,stdout:de,stderr:ue})})}catch{J({code:null,stdout:"",stderr:""})}})}function mr(_){if(!_)return null;let I=/Claude Code\s+(\d+\.\d+\.\d+)/i.exec(_);if(I)return I[1]??null;let O=/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/i.exec(_);if(O)return O[1]??null;return _.split(`
22
+ `)[0]?.trim()||null}async function gr(_,I=vt,O=process.cwd()){let L=Promise.all(En.map(async(xe)=>[xe.id,mr(await I([...xe.probeCommand]))])),[J,K,ne,oe,de,ue,ve]=await Promise.all([L,L.then(async(xe)=>{let Se=xe.find(([Le])=>Le==="opencode")?.[1];if(!Se?.startsWith("2.")||!_(Se))return null;let Pe=["--param",`location[directory]=${O}`],we=["opencode","api","integration.list",...Pe];return await I(we,30000),I(["opencode","api","plugin.list",...Pe],30000)}),I(["codex","plugin","list"],30000),I(["amp","plugins","list"],30000),I(["node","--version"]),I(["npm","--version"]),I(["bun","--version"])]);return{version:Ms,versions:Object.fromEntries(J),codexPluginListOutput:ne,ampPluginListOutput:oe,openCodePluginListOutput:K,nodeVersion:mr(de),npmVersion:mr(ue),bunVersion:mr(ve),platform:`${process.platform} ${process.arch}`}}function ko(_,I){if(I==="dev")return!1;let O=_.split(".").map(Number),L=I.split(".").map(Number),[J=0,K=0,ne=0]=O,[oe=0,de=0,ue=0]=L;if(J!==oe)return J>oe;if(K!==de)return K>de;return ne>ue}async function Gn(){let _=fn(),I=new AbortController,O=setTimeout(()=>I.abort(),3000);try{let L=await fetch("https://registry.npmjs.org/cc-safety-net/latest",{signal:I.signal});if(!L.ok)return{currentVersion:_,latestVersion:null,updateAvailable:!1,error:`npm registry returned ${L.status}`};let J=await L.json(),K=ko(J.version,_);return{currentVersion:_,latestVersion:J.version,updateAvailable:K}}catch(L){return{currentVersion:_,latestVersion:null,updateAvailable:!1,error:L instanceof Error?L.message:"Network error"}}finally{clearTimeout(O)}}import*as Ws from"node:readline";var qs=(_)=>`\x1B[${_}B`,qp=(_)=>`\x1B[${_}A`;var Us=["░","▒","▓","╱","╲","┃","━","┏","┓","┗","┛","╋"];function Vp(_){return new Promise((I)=>setTimeout(I,_))}function zp(_,I,O){if(!O)return I(_);if(O.aborted)return Promise.resolve();return new Promise((L,J)=>{let K=()=>O.removeEventListener("abort",ne),ne=()=>{K(),L()};O.addEventListener("abort",ne,{once:!0}),I(_).then(()=>{K(),L()},(oe)=>{K(),J(oe)})})}function hr(_){return Math.max(0,Math.min(1,_))}function bt(_){return Math.max(0,Math.min(255,Math.round(_)))}function xo(_){return _<=0.0031308?12.92*_:1.055*_**0.4166666666666667-0.055}function Jp(_,I,O){let L=O*Math.PI/180,J=I*Math.cos(L),K=I*Math.sin(L),ne=(_+0.3963377774*J+0.2158037573*K)**3,oe=(_-0.1055613458*J-0.0638541728*K)**3,de=(_-0.0894841775*J-1.291485548*K)**3;return{blue:bt(xo(hr(-0.0041960863*ne-0.7034186147*oe+1.707614701*de))*255),green:bt(xo(hr(-1.2684380046*ne+2.6097574011*oe-0.3413193965*de))*255),red:bt(xo(hr(4.0767416621*ne-3.3077115913*oe+0.2309699292*de))*255)}}function So(_,I){let O=(I*_*180/Math.PI%360+360)%360;return Jp(0.72,0.15,O)}function Vs(_,I=0.1){let O=So(I,_);return`\x1B[38;2;${O.red};${O.green};${O.blue}m`}function Wp(_,I){return{blue:bt(_.blue+(255-_.blue)*I),green:bt(_.green+(255-_.green)*I),red:bt(_.red+(255-_.red)*I)}}function zs(_,I,O){let L=Math.imul(_+2654435769,2246822507)^Math.imul(I+3266489909,668265263)^Math.imul(O+374761393,2654435761),J=L^L>>>15,K=Math.imul(J,739982445),ne=K^K>>>12,oe=Math.imul(ne,695872825);return((oe^oe>>>15)>>>0)/4294967296}function Kp(_,I,O){let L=Math.floor(zs(_,I,O)*Us.length);return Us[L]??"░"}function Gs(_){let I=hr(_);return I*I*I*(I*(I*6-15)+10)}function Yp(_){if(_.length===0)return"";let I=[],O=!1,L="";for(let J of _){let K=`${J.red};${J.green};${J.blue}`;if(J.bold!==O)I.push(J.bold?"\x1B[1m":"\x1B[22m"),O=J.bold;if(K!==L)I.push(`\x1B[38;2;${K}m`),L=K;I.push(J.character)}return`${I.join("")}\x1B[22m\x1B[39m`}function Zp(_,I,O,L,J){return _.map((K,ne)=>({...So(O,L+I+ne/J),bold:!1,character:K}))}function Xp(_,I,O,L,J,K,ne,oe){let de=Math.max(1,L*0.75),ue=Math.min(1,O/de),ve=J*Gs(ue),xe=Math.max(0,(O-de)/Math.max(1,L-de)),Se=(1-Gs(O/L))*oe*2,Pe=0.35*Math.max(0,1-xe*2),we=ue>=1,Le=Math.min(_.length,Math.ceil(ve+2+1));return _.slice(0,Le).map((en,Ve)=>{let on=So(K,ne+I+Ve/oe+Se),sn=Ve+zs(I,Ve,7919)*2-1;if(sn>ve+2)return{...on,bold:!1,character:" "};let an=ve-sn,rn=0.8*Math.exp(-(an*an)/12.5),un=Math.min(0.9,rn+Pe),xn=!we&&sn>ve-4;return{...Wp(on,un),bold:un>0.3,character:xn?Kp(I,Ve,O):en}})}function Bs(_){return`\x1B[?2026h${_.map((I,O)=>`\x1B8${O>0?qs(O):""}${Yp(I)}`).join("")}\x1B[?2026l`}async function Co(_,I={}){if(!_)return;let O=I.output??process.stdout,L=I.sleep??Vp,J=I.seed??0,K=_.split(`
23
+ `).map((ve)=>Array.from(ve)),ne=Math.max(...K.map((ve)=>ve.length)),oe=12000*K.filter((ve)=>ve.length>0).length/40,de=ne>0?Math.max(1,Math.ceil(oe/16.666666666666668)):0,ue=de>0?oe/de:0;O.write(`\x1B[?25l${K.length>1?`${`
24
+ `.repeat(K.length-1)}${qp(K.length-1)}`:""}\x1B7`);try{for(let ve=1;ve<=de;ve+=1){if(I.signal?.aborted)break;O.write(Bs(K.map((xe,Se)=>Xp(xe,Se,ve,de,ne,0.1,J,3)))),await zp(ue,L,I.signal)}}finally{if(O.write(Bs(K.map((ve,xe)=>Zp(ve,xe,0.1,J,3)))),O.write("\x1B8"),K.length>1)O.write(qs(K.length-1));O.write(`
25
+ \x1B[0m\x1B[?25h`)}}var Js=["┏━┛┏━┛ ┏━┛┏━┃┏━┛┏━┛━┏┛┃ ┃ ┏━ ┏━┛━┏┛","┃ ┃ ━━┃┏━┃┏━┛┏━┛ ┃ ━┏┛ ┃ ┃┏━┛ ┃ ","━━┛━━┛ ━━┛┛ ┛┛ ━━┛ ┛ ┛ ┛ ┛━━┛ ┛ "].join(`
26
+ `);function Qp(_){return Boolean(_.isTTY)}async function Tt(_={}){let I=_.output??process.stdout;if(!Qp(I))return;let O=_.input??process.stdin,L={output:I,seed:_.seed??Math.random()*8192,sleep:_.sleep};if(!O.isTTY||typeof O.setRawMode!=="function"){await Co(Js,L);return}let J=new AbortController,K=O.readableFlowing===!0,ne=O.isRaw===!0,oe=!1,de=(ue,ve)=>{if(ve.ctrl&&ve.name==="c")oe=!0;if(oe||ve.name==="return"||ve.name==="enter")J.abort()};Ws.emitKeypressEvents(O),O.on("keypress",de),O.setRawMode(!0),O.resume();try{await Co(Js,{...L,signal:J.signal})}finally{if(O.off("keypress",de),O.setRawMode(ne),!K)O.pause()}if(!oe)return;if(_.onInterrupt){_.onInterrupt();return}process.kill(process.pid,"SIGINT")}import{createHash as of}from"node:crypto";import{existsSync as Zs}from"node:fs";import{dirname as yr,join as Xs}from"node:path";import{dirname as Ks,join as ef,resolve as nf}from"node:path";var tf="rule.lock";function rf(_){return ef(Ks(_),tf)}function Ys(_={}){return nf(_.cwd??process.cwd(),".safety-net.json")}function wn(_,I){let O=I.global?I.userConfigPath??G(_,I):I.projectConfigPath??U(I.cwd??process.cwd()),L=I.global?Ke(_,I):Je(O,I.cwd??process.cwd()),J=rf(O);return{configDir:Ks(O),configPath:O,lockPath:J,filesystemScope:L,configTarget:i(L,O),lockTarget:i(L,J)}}var sf="`cc-safety-net rule sync` is deprecated: rulebooks are live files that need no synchronization. This run only migrates the lock and cache an earlier version left behind.",af="cache",lf="rulebooks";function Qs(_,I={}){let O=wn(_,I),L=i(O.filesystemScope,na(O.configDir)),J=n(O.lockTarget);if(console.log(sf),J===null&&!Zs(L.path))return console.log(`No v2 lock or cache leftovers found in ${yr(O.configDir)}; nothing to migrate.`),0;let K=ff(J),ne=m(O.configTarget);if(!ne.config&&(n(O.configTarget)!==null||K.size>0))return console.error(`Cannot migrate: the rules config in ${yr(O.configDir)} is missing or unreadable while v2 leftovers remain. Restore rule.json, then re-run rule sync.`),1;let oe=ne.config?.rules??[];for(let de of oe.flatMap((ue)=>cf(ue,K,O,L,I.global===!0)))console.log(de);return j(O.lockTarget),it(L),console.log(`Removed the v2 lock and cache under ${yr(O.configDir)}.`),0}function ea(_,I){return[...new Set([{cwd:I},{cwd:I,global:!0}].flatMap((O)=>{let L=wn(_,O);return[L.lockPath,na(L.configDir)]}))].filter((O)=>Zs(O))}function cf(_,I,O,L,J){if(!S(_))return[];let K=D(_).name,ne=i(O.filesystemScope,N(O.configDir,K)),oe=n(ne);if(oe!==null&&df(oe,K))return[];let de=I.get(_),ue=de?uf(de,K,L.path,O.filesystemScope):null;if(ue===null)return[`Could not migrate ${_} from the v2 cache. Run \`cc-safety-net rule update ${_}${J?" --global":""}\` to vendor it.`];if(g(ne,ue),oe!==null)return[`Restored ${_} from the v2 cache over an invalid file.`];return[`Vendored ${_} from the v2 cache.`]}function df(_,I){let O=ye(_);return!("problem"in O)&&O.rulebook.name===I}function uf(_,I,O,L){let J=Xs(O,lf,`${pf(_)}--${_.digest.replace("sha256:","").slice(0,12)}`,fe),K=n(i(L,J));if(K===null||hf(K)!==_.digest)return null;let ne=ye(K);if("problem"in ne||ne.rulebook.name!==I)return null;return K}function na(_){return Xs(yr(_),af)}function pf(_){return([_.owner,_.repo,_.display_ref,_.name].every((L)=>typeof L==="string"&&L!=="")?`${_.owner}/${_.repo}#${_.display_ref}/${_.name}`:_.spec).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"rulebook"}function ff(_){let I=_===null?null:gf(_),O=ta(I)&&Array.isArray(I.rulebooks)?I.rulebooks:[];return new Map(O.filter(mf).map((L)=>[L.spec,L]))}function mf(_){return ta(_)&&typeof _.spec==="string"&&typeof _.digest==="string"}function ta(_){return!!_&&typeof _==="object"}function gf(_){try{return JSON.parse(_)}catch{return null}}function hf(_){return`sha256:${of("sha256").update(_).digest("hex")}`}var ra="\r\x1B[2K",yf="\x1B[?25l",vf="\x1B[39m",bf="\x1B[?25h",wf=100,kf=0.55,xf=80,oa=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function Sf(_){return new Promise((I)=>setTimeout(I,_))}async function vr(_,I={}){let O=I.output??process.stdout;if(!O.isTTY)return _;let L=I.sleep??Sf,J=!1,K=_.then((oe)=>(J=!0,oe),(oe)=>{throw J=!0,oe});if(await Promise.race([K.then(()=>!0),L(wf).then(()=>!1)]))return K;O.write(yf);try{for(let oe=0;!J;oe+=1)O.write(`${ra}${Vs(oe*kf)}${oa[oe%oa.length]}${vf} ${I.loadingMessage??"Loading…"}`),await Promise.race([K,L(xf)]);return await K}finally{O.write(`${ra}${bf}`)}}async function $t(_,I,O,L={}){let J=I();if(_)await O();if(_&&J.ready)await vr(J.ready,L);return J.finish()}import{stripVTControlCharacters as Cf}from"node:util";var br="amp plugins list",Rf=/^\s*[✓✗]\s+cc-safety-net(?:\.ts)?\s+\(User Plugins\)\s+(\S+)\s*$/;function ia(_){if(!_.ampPluginListOutput)return{platform:"amp",status:"n/a"};let I=Cf(_.ampPluginListOutput).split(`
27
+ `).map((O)=>Rf.exec(O)?.[1]).find((O)=>O!==void 0);if(!I)return{platform:"amp",status:"n/a"};if(I!=="active")return{platform:"amp",status:"disabled",method:br,configPath:br,errors:[`Amp personal plugin cc-safety-net is ${I}; run "plugins: reload" in Amp or reinstall with install --amp`]};return{platform:"amp",status:"configured",method:br,configPath:br}}import{existsSync as If,readFileSync as Tf}from"node:fs";import{isAbsolute as Kk,join as _f}from"node:path";function Ot(_){return _f(_,".gemini","config","hooks.json")}var $f=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*(?:--agy-cli|-ac)(\s|["']|$)/;function Of(_){if(!_||typeof _!=="object"||Array.isArray(_))return[];return Object.values(_).flatMap((I)=>{if(!I||typeof I!=="object"||Array.isArray(I))return[];let O=I,L=O.PreToolUse;if(!Array.isArray(L))return[];return L.flatMap((J)=>{if(!J||typeof J!=="object"||Array.isArray(J))return[];let K=J.hooks;if(!Array.isArray(K))return[];return K.flatMap((ne)=>{if(!ne||typeof ne!=="object"||Array.isArray(ne))return[];let oe=ne.command;if(typeof oe!=="string"||!$f.test(oe))return[];return[{command:oe,enabled:O.enabled!==!1}]})})})}function sa(_){let I=Ot(_.environment.home);if(!If(I))return{platform:"antigravity-cli",status:"n/a",configPath:I};let O;try{O=Of(JSON.parse(Tf(I,"utf-8")))}catch(L){return{platform:"antigravity-cli",status:"n/a",configPath:I,errors:[`Failed to parse Antigravity hooks config ${I}: ${L instanceof Error?L.message:String(L)}`]}}if(O.some((L)=>L.enabled))return{platform:"antigravity-cli",status:"configured",method:"hook config",configPath:I};if(O.length>0)return{platform:"antigravity-cli",status:"disabled",method:"hook config",configPath:I};return{platform:"antigravity-cli",status:"n/a",configPath:I}}import{join as Po}from"node:path";import{existsSync as Df,lstatSync as Lf,readFileSync as Nf}from"node:fs";import{join as jf}from"node:path";function Rn(_,I=(O)=>O){if(!Df(_))return{kind:"missing"};try{return{kind:"ok",value:JSON.parse(I(Nf(_,"utf-8")))}}catch{return{kind:"unreadable"}}}function Ln(_,I){if(_==="~")return I;if(_.startsWith("~/")||_.startsWith("~\\"))return jf(I,_.slice(2));return _}function cn(_){try{return Lf(_)}catch{return}}function wr(_,I){let O=cn(I);if(!O)return{platform:_,status:"n/a",configPath:I};if(!O.isSymbolicLink()&&O.isDirectory())return;return{platform:_,status:"n/a",configPath:I,errors:[`${I} is a symlink or not a directory; move or remove it before installing`]}}function tn(_,I){return typeof _==="object"&&_!==null?_[I]:void 0}var Ro="cc-safety-net@cc-marketplace";function kr(_){return _.env.get("CLAUDE_CONFIG_DIR")||Po(_.home,".claude")}function aa(_){return Po(kr(_),"plugins","installed_plugins.json")}function la(_,I){let O=tn(tn(_,"plugins"),I);return Array.isArray(O)&&O.length>0}function xr(_,I){let O=Rn(aa(_));return O.kind==="ok"&&la(O.value,I)}function Eo(_){let I=aa(_),O=Rn(I);if(O.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(O.kind==="missing")return{platform:"claude-code",status:"n/a"};if(!la(O.value,Ro))return{platform:"claude-code",status:"n/a"};let L=Po(kr(_),"settings.json"),J=Rn(L);if(J.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(!(J.kind==="ok"&&tn(tn(J.value,"enabledPlugins"),Ro)===!0))return{platform:"claude-code",status:"disabled",method:"plugin config",configPath:L,errors:[`${Ro} is installed but not enabled in Claude Code`]};return{platform:"claude-code",status:"configured",method:"plugin config",configPath:I}}function ca(_){return Eo(_.environment)}var da="Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it.";function ua(_){if(!_.codexPluginListOutput)return{platform:"codex",status:"n/a"};let I=_.codexPluginListOutput.split(`
28
+ `).find((O)=>O.includes("https://github.com/kenryu42/cc-safety-net.git"));if(!I)return{platform:"codex",status:"n/a"};if(!I.includes("installed,"))return{platform:"codex",status:"n/a"};if(!I.includes("installed, enabled"))return{platform:"codex",status:"disabled",method:"codex plugin list",configPath:"codex plugin list",errors:["Codex plugin line for https://github.com/kenryu42/cc-safety-net.git must contain installed, enabled."]};return{platform:"codex",status:"configured",method:"codex plugin list",configPath:"codex plugin list",errors:["Codex runs only trusted hooks, and doctor cannot check trust. Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it."]}}import{existsSync as Er,readdirSync as Ff,readFileSync as Hf}from"node:fs";import{join as vn}from"node:path";function Sn(_){let I="",O=0,L=!1,J=!1,K=-1;while(O<_.length){let ne=_[O],oe=_[O+1];if(J){I+=ne,J=!1,O++;continue}if(ne==='"'&&!L){L=!0,K=-1,I+=ne,O++;continue}if(ne==='"'&&L){L=!1,I+=ne,O++;continue}if(ne==="\\"&&L){J=!0,I+=ne,O++;continue}if(L){I+=ne,O++;continue}if(ne==="/"&&oe==="/"){while(O<_.length&&_[O]!==`
29
+ `)O++;continue}if(ne==="/"&&oe==="*"){O+=2;while(O<_.length-1){if(_[O]==="*"&&_[O+1]==="/"){O+=2;break}O++}continue}if(ne===","){K=I.length,I+=ne,O++;continue}if(ne==="}"||ne==="]"){if(K!==-1){let de=I.slice(K+1);if(/^\s*$/.test(de))I=I.slice(0,K)+de}K=-1,I+=ne,O++;continue}if(!/\s/.test(ne))K=-1;I+=ne,O++}return I}function fa(_,I,O){let L=I+1,J=!1;while(L<_.length){if(J){J=!1,L++;continue}if(_[L]==="\\"){J=!0,L++;continue}if(_[L]==='"')return L+1;L++}throw Error(O)}function _o(_,I,O){let L=_[I],J=L==="["?"]":"}",K=0,ne=I;while(ne<_.length){let oe=O.skipComment?.(_,ne)??ne;if(oe!==ne){ne=oe;continue}if(_[ne]==='"'){ne=fa(_,ne,O.stringError);continue}if(_[ne]===L)K++;if(_[ne]===J){if(K--,K===0)return ne}ne++}throw Error(O.bracketError)}function ma(_,I){let O=_.lastIndexOf(`
30
+ `,I)+1;return/^[ \t]*/.exec(_.slice(O))?.[0]??""}function Sr(_,I){let O=I.end+(/^\s*/.exec(_.slice(I.end))?.[0].length??0);if(_[O]===","){let ne=_[O+1]===`
31
+ `?O+2:O+1;return`${_.slice(0,I.start)}${_.slice(ne)}`}let L=_.slice(0,I.start).search(/\s*$/)-1;if(_[L]!==",")return`${_.slice(0,I.start)}${_.slice(I.end)}`;let J=_.lastIndexOf(`
32
+ `,L-1),K=J!==-1&&/^\s*$/.test(_.slice(J+1,L))?J:L;return`${_.slice(0,K)}${_.slice(I.end)}`}function Ao(_,I){if(_.startsWith("//",I)){let O=_.indexOf(`
33
+ `,I+2);return O===-1?_.length:O+1}if(_.startsWith("/*",I)){let O=_.indexOf("*/",I+2);return O===-1?_.length:O+2}return I}function pa(_,I){let O=I;while(O<_.length){if(/\s/.test(_[O]??"")){O++;continue}let L=Ao(_,O);if(L===O)return O;O=L}return O}function ga(_,I,O){let L=0,J=0;while(J<_.length){let K=Ao(_,J);if(K!==J){J=K;continue}if(_[J]==='"'){let ne=fa(_,J,O.stringError);if(L===1&&JSON.parse(_.slice(J,ne))===I){let oe=pa(_,ne),de=pa(_,oe+1);if(_[oe]===":"&&_[de]==="[")return{start:de,end:_o(_,de,{skipComment:Ao,...O})}}J=ne;continue}if(_[J]==="{"||_[J]==="[")L++;if(_[J]==="}"||_[J]==="]")L--;J++}return}var _n="cc-safety-net@cc-marketplace",Cr=["cc-marketplace","cc-safety-net"],ha=["_direct","copilot-safety-net"],ya=["cc-marketplace","safety-net"],va="safety-net@cc-marketplace";function Rr(_,I){let O=I.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^a-z0-9-])${O}([^a-z0-9-]|$)`,"m").test(_??"")}function ba(_){return Rr(_,"cc-safety-net@cc-marketplace")}function wa(_){return Rr(_,"cc-marketplace")}function ka(_){return Rr(_,"copilot-safety-net")}function xa(_){return Rr(_,"safety-net@cc-marketplace")}function Pr(_){if(!_?.includes("cc-safety-net"))return!1;return/(^|\s)hook\s+(?:[^\s]+\s+)*(--copilot-cli|-cp)(\s|$)/.test(_)}function Ca(_,I){if(!_)return null;let O=_.match(/(\d+)\.(\d+)\.(\d+)/);if(!O)return null;let L=[Number(O[1]),Number(O[2]),Number(O[3])];for(let J=0;J<I.length;J++){let K=L[J]??0,ne=I[J]??0;if(K!==ne)return K>ne}return!0}function Mf(_){return Ca(_,[0,0,422])}function Uf(_){return Ca(_,[1,0,8])}function Lt(_){return _.env.get("COPILOT_HOME")||vn(_.home,".copilot")}function Io(_){return(_.hooks?.preToolUse??[]).some((O)=>{if(O.type!==void 0&&O.type!=="command")return!1;return Pr(O.command)||Pr(O.bash)||Pr(O.powershell)||Pr(O.exec&&[O.exec,...O.args??[]].join(" "))})}function Dt(_){return _===void 0||typeof _==="string"}function Gf(_){return _===void 0||Array.isArray(_)&&_.every((I)=>typeof I==="string")}function Bf(_){if(!_||typeof _!=="object"||Array.isArray(_))return!1;let I=_;if(I.disableAllHooks!==void 0&&typeof I.disableAllHooks!=="boolean")return!1;if(I.hooks===void 0)return!0;if(!I.hooks||typeof I.hooks!=="object"||Array.isArray(I.hooks))return!1;let O=I.hooks.preToolUse;if(O===void 0)return!0;return Array.isArray(O)&&O.every((L)=>L!==null&&typeof L==="object"&&!Array.isArray(L)&&Dt(L.type)&&Dt(L.command)&&Dt(L.bash)&&Dt(L.powershell)&&Dt(L.exec)&&Gf(L.args))}function To(_,I){try{let O=JSON.parse(Sn(Hf(_,"utf-8")));if(!Bf(O)){I?.push(`Invalid hook config ${_}: hooks.preToolUse must be an array of hook objects`);return}return O}catch(O){I?.push(`Failed to parse ${_}: ${O instanceof Error?O.message:String(O)}`);return}}function Ra(_,I){try{return Ff(_).filter((O)=>O.endsWith(".json")).sort((O,L)=>O.localeCompare(L))}catch(O){return I?.push(`Failed to read ${_}: ${O instanceof Error?O.message:String(O)}`),[]}}function qf(_,I){if(!Er(_))return[];let O=[];for(let L of Ra(_,I)){let J=vn(_,L),K=To(J,I);if(K&&Io(K))O.push(J)}return O}function wt(_,I){if(!Er(_))return;let O=To(_,I);if(!O)return;return{path:_,config:O}}function Sa(_,I,O,L){if(I){_.push(`GitHub Copilot CLI ${I} does not support ${O}; requires ${L}+`);return}_.push(`GitHub Copilot CLI version unavailable; skipping ${O} because it requires ${L}+`)}function Vf(_){for(let I of _){if(I?.config.disableAllHooks===!0)return I.path;if(I?.config.disableAllHooks===!1)return}return}function zf(_,I,O,L){let J=Lt(_),K=vn(I,".github","hooks"),ne=vn(J,"hooks"),oe=vn(I,".github","copilot"),de=vn(I,".claude"),ue=Uf(O),ve=ue===!0?L:void 0,xe=[wt(vn(oe,"settings.local.json"),ve),wt(vn(oe,"settings.json"),ve),wt(vn(de,"settings.local.json"),ve),wt(vn(de,"settings.json"),ve)],Se=[wt(vn(J,"settings.json"),ve),wt(vn(J,"config.json"),ve)];if(ue!==!1){let an=Vf([...xe,...Se]);if(an){if(ue===null)L.push(`GitHub Copilot CLI version unavailable; treating disableAllHooks in ${an} as active`);return{activeConfigPaths:[],repoInlineSources:xe,disabledBy:an}}}let Pe=qf(K,L),we=Mf(O),Le=we===!0?L:void 0,en=Er(ne)?Ra(ne,Le):[],Ve=[];for(let an of en){let rn=vn(ne,an),un=To(rn,Le);if(un&&Io(un))Ve.push(rn)}if(we!==!0&&Ve.length>0)Sa(L,O,`user hook files in ${ne}`,"0.0.422"),Ve.length=0;let on=[];for(let an of[...xe,...Se]){if(!an)continue;if(!Io(an.config))continue;if(ue===!0){on.push(an);continue}Sa(L,O,"inline hook definitions in Copilot config files","1.0.8");break}let sn=(an)=>an.filter((rn)=>!!rn&&on.includes(rn)).map((rn)=>rn.path);return{activeConfigPaths:[...sn(xe),...Pe,...sn(Se),...Ve],repoInlineSources:xe}}function Pa(_){let I=[],O=zf(_.environment,_.cwd,_.copilotCliVersion,I);if(O.disabledBy)return{platform:"copilot-cli",status:"disabled",method:"hook config",configPath:O.disabledBy,configPaths:[O.disabledBy],errors:I.length>0?I:void 0};let L=Lt(_.environment),J=vn(L,"installed-plugins",...Cr),K=Er(J),ne=vn(L,"settings.json"),oe=Rn(ne,Sn),de=(Pe)=>tn(tn(Pe,"enabledPlugins"),_n),ue=O.repoInlineSources.find((Pe)=>typeof de(Pe?.config)==="boolean"),ve=ue??(oe.kind==="ok"?{path:ne,config:oe.value}:void 0);if(K&&!ue&&oe.kind==="unreadable")return{platform:"copilot-cli",status:"not-inspected"};let xe=K&&ve!==void 0&&de(ve.config)===!1;if(xe&&O.activeConfigPaths.length===0)return{platform:"copilot-cli",status:"disabled",method:"plugin config",configPath:ve.path,errors:[`${_n} is installed but not enabled in Copilot CLI`]};let Se=K&&!xe;if(Se||O.activeConfigPaths.length>0){let Pe=O.activeConfigPaths[0];return{platform:"copilot-cli",status:"configured",method:Se?"plugin config":"hook config",configPath:Pe??(Se?J:void 0),configPaths:O.activeConfigPaths.length>0?O.activeConfigPaths:void 0,errors:I.length>0?I:void 0}}return{platform:"copilot-cli",status:"n/a",errors:I.length>0?I:void 0}}import{existsSync as tm,readFileSync as rm}from"node:fs";import{existsSync as Ea,mkdirSync as Kf,readFileSync as Yf}from"node:fs";import{dirname as Zf,join as Xf}from"node:path";import{renameSync as Jf,writeFileSync as Wf}from"node:fs";function mn(_,I){let O=`${_}.${process.pid}.tmp`;Wf(O,I),Jf(O,_)}var In=Object.fromEntries(It.map((_)=>[_.id,`npx -y cc-safety-net hook ${_.flags[1]}`]));var Nt=In.cursor,Aa=30;function _r(_){return Xf(_.home,".cursor","hooks.json")}function Kn(_){return typeof _==="object"&&_!==null&&!Array.isArray(_)}function $o(){return{command:Nt,timeout:Aa,failClosed:!0}}function Ar(_){return Kn(_)&&_.command===Nt}function Qf(_){return Object.keys(_).length===3&&_.command===Nt&&_.timeout===Aa&&_.failClosed===!0}function em(_){try{return JSON.parse(Yf(_,"utf-8"))}catch(I){if(I instanceof SyntaxError)throw Error(`Failed to parse Cursor hooks config ${_}: ${I.message}`);throw I}}function _a(_){let I=em(_);if(!Kn(I))throw Error(`Cursor hooks config ${_} must be a JSON object`);if(I.version!==1)throw Error(`Cursor hooks config ${_} must set "version": 1`);if(I.hooks!==void 0&&!Kn(I.hooks))throw Error(`Cursor hooks config ${_} "hooks" must be an object`);let O=Kn(I.hooks)?I.hooks.preToolUse:void 0;if(O!==void 0&&!Array.isArray(O))throw Error(`Cursor hooks config ${_} "hooks.preToolUse" must be an array`);return I}function Ia(_){let I=Kn(_.hooks)?_.hooks.preToolUse:void 0;return Array.isArray(I)?I:[]}function nm(_){if(!_.some(Ar))return[..._,$o()];return _.reduce((I,O)=>{if(!Ar(O))return I.result.push(O),I;if(!I.inserted)I.result.push($o()),I.inserted=!0;return I},{result:[],inserted:!1}).result}function Ta(_,I,O){let L=Kn(I.hooks)?I.hooks:{},J={...I,hooks:{...L,preToolUse:O}};mn(_,`${JSON.stringify(J,null,2)}
34
+ `)}function $a(_){let I=_r(_);if(!Ea(I))return Kf(Zf(I),{recursive:!0}),mn(I,`${JSON.stringify({version:1,hooks:{preToolUse:[$o()]}},null,2)}
35
+ `),{path:I,alreadyInstalled:!1};let O=_a(I),L=Ia(O),J=L.filter(Ar);if(Kn(O.hooks)&&Array.isArray(O.hooks.preToolUse)&&J.length===1&&J[0]!==void 0&&Qf(J[0]))return{path:I,alreadyInstalled:!0};return Ta(I,O,nm(L)),{path:I,alreadyInstalled:!1}}function Oa(_){let I=_r(_);if(!Ea(I))return{path:I,alreadyInstalled:!1};let O=_a(I),L=Ia(O),J=L.filter((K)=>!Ar(K));if(J.length===L.length)return{path:I,alreadyInstalled:!1};return Ta(I,O,J),{path:I,alreadyInstalled:!0}}function om(_){if(!_||typeof _!=="object"||Array.isArray(_))return[];let I=_.hooks;if(!I||typeof I!=="object"||Array.isArray(I))return[];let O=I.preToolUse;if(!Array.isArray(O))return[];return O.filter((L)=>!!L&&typeof L==="object"&&!Array.isArray(L)&&L.command===Nt)}function im(_){let I=[];if(_.length>1)I.push("Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates");let O=_[0];if(O&&O.failClosed!==!0)I.push('Managed hook is missing "failClosed": true; reinstall to repair');if(O&&O.timeout!==30)I.push('Managed hook "timeout" is not 30; reinstall to repair');return I}function Da(_){let I=_r(_.environment);if(!tm(I))return{platform:"cursor",status:"n/a",configPath:I};let O;try{O=JSON.parse(rm(I,"utf-8"))}catch(K){return{platform:"cursor",status:"n/a",configPath:I,errors:[`Failed to parse Cursor hooks config ${I}: ${K instanceof Error?K.message:String(K)}`]}}let L=om(O);if(L.length===0)return{platform:"cursor",status:"n/a",configPath:I};let J=im(L);return{platform:"cursor",status:"configured",method:"hook config",configPath:I,errors:J.length>0?J:void 0}}import{readdirSync as sm}from"node:fs";import{join as Oo,resolve as am}from"node:path";var Do="cc-safety-net";function Lo(_){let I=_.env.get("DSH_HOME");return Oo(I?.trim()?am(Ln(I,_.home)):Oo(_.home,".dsh"),"profiles")}function La(_){let I=Lo(_),O=cn(I)?.isDirectory()?sm(I,{withFileTypes:!0}).filter((J)=>J.isDirectory()&&J.name!=="node_modules").map((J)=>{let K=Oo(I,J.name,"package.json");return{name:J.name,configPath:K,manifest:Rn(K)}}):[];return{installed:O.flatMap((J)=>{if(J.manifest.kind!=="ok")return[];let K=J.manifest.value;if(tn(tn(K,"dependencies"),Do)===void 0)return[];let ne=tn(tn(tn(K,"dsh"),"profile"),"bundles");return[{name:J.name,configPath:J.configPath,enabled:Array.isArray(ne)&&ne.includes(Do)}]}),unreadable:O.some((J)=>J.manifest.kind==="unreadable")}}function No(_){return La(_).installed}function Na(_){let I=La(_.environment),O=I.installed.filter((K)=>K.enabled),L=I.installed.filter((K)=>!K.enabled),J=L.map((K)=>`${Do} is installed in the ${K.name} profile but its bundle is disabled`);if(O.length>0)return{platform:"deepseek-harness",status:"configured",method:"dsh bundle",configPaths:O.map((K)=>K.configPath),...J.length>0?{errors:J}:{}};if(L.length>0)return{platform:"deepseek-harness",status:"disabled",method:"dsh bundle",configPaths:L.map((K)=>K.configPath),errors:J};return I.unreadable?{platform:"deepseek-harness",status:"not-inspected"}:{platform:"deepseek-harness",status:"n/a"}}import{existsSync as lm}from"node:fs";import{join as jo}from"node:path";var Fo="gemini-safety-net";function Ho(_){let I=jo(_.home,".gemini","extensions"),O=jo(I,Fo);if(!lm(O))return{platform:"gemini-cli",status:"n/a"};let L=jo(I,"extension-enablement.json"),J=Rn(L);if(J.kind==="unreadable")return{platform:"gemini-cli",status:"not-inspected"};let K=J.kind==="ok"?tn(tn(J.value,Fo),"overrides"):void 0;if(Array.isArray(K)&&K.some((oe)=>typeof oe==="string"&&oe.startsWith("!")))return{platform:"gemini-cli",status:"disabled",method:"extension config",configPath:L,errors:[`${Fo} is disabled in Gemini CLI`]};return{platform:"gemini-cli",status:"configured",method:"extension config",configPath:O}}function ja(_){return Ho(_.environment)}import{existsSync as pm,readFileSync as fm}from"node:fs";import{existsSync as Ha,mkdirSync as cm,readFileSync as Ma,rmSync as dm}from"node:fs";import{dirname as um,join as Fa}from"node:path";var jt=In["grok-build"],$r=30;function Or(_){return Fa(_.env.get("GROK_HOME")??Fa(_.home,".grok"),"hooks","cc-safety-net.json")}function Yn(_){return typeof _==="object"&&_!==null&&!Array.isArray(_)}function Ir(){return{hooks:[{type:"command",command:jt,timeout:$r}]}}function Ua(_){return Yn(_)&&_.command===jt}function Ga(_){return _.flatMap((I)=>{if(!Yn(I)||!Array.isArray(I.hooks))return[I];let O=I.hooks.filter((L)=>!Ua(L));if(O.length===I.hooks.length)return[I];return O.length===0?[]:[{...I,hooks:O}]})}function Ba(_){try{let I=JSON.parse(_);return Yn(I)?I:null}catch{return null}}function qa(_){let I=Yn(_.hooks)?_.hooks.PreToolUse:void 0;return Array.isArray(I)?I:[]}function Tr(_,I,O){let L=Yn(I.hooks)?I.hooks:{};mn(_,`${JSON.stringify({...I,hooks:{...L,PreToolUse:O}},null,2)}
36
+ `)}function Va(_){let I=Or(_);if(!Ha(I))return cm(um(I),{recursive:!0}),Tr(I,{},[Ir()]),{path:I,alreadyInstalled:!1};let O=Ba(Ma(I,"utf-8"));if(!O)return Tr(I,{},[Ir()]),{path:I,alreadyInstalled:!1};let L=qa(O),J=L.filter((K)=>Yn(K)&&Array.isArray(K.hooks)&&K.hooks.some(Ua));if(J.length===1&&JSON.stringify(J[0])===JSON.stringify(Ir()))return{path:I,alreadyInstalled:!0};return Tr(I,O,[...Ga(L),Ir()]),{path:I,alreadyInstalled:!1}}function za(_){let I=Or(_);if(!Ha(I))return{path:I,alreadyInstalled:!1};let O=Ba(Ma(I,"utf-8"));if(!O)return{path:I,alreadyInstalled:!1};let L=qa(O),J=Ga(L);if(JSON.stringify(J)===JSON.stringify(L))return{path:I,alreadyInstalled:!1};let K=Yn(O.hooks)?O.hooks:{};if(J.length===0&&Object.keys(O).length===1&&Object.keys(K).length===1)return dm(I),{path:I,alreadyInstalled:!0};return Tr(I,O,J),{path:I,alreadyInstalled:!0}}function Ft(_){return!!_&&typeof _==="object"&&!Array.isArray(_)}function mm(_){if(!Ft(_)||!Ft(_.hooks))return[];let I=_.hooks.PreToolUse;if(!Array.isArray(I))return[];return I.filter((O)=>Ft(O)&&Array.isArray(O.hooks)&&O.hooks.some((L)=>Ft(L)&&L.command===jt))}function gm(_){let O=(Array.isArray(_.hooks)?_.hooks.filter(Ft):[]).find((L)=>L.command===jt);return[..._.matcher===void 0||_.matcher===""||_.matcher==="*"?[]:['Managed hook has a "matcher" that narrows coverage; reinstall to repair'],...O?.type==="command"?[]:['Managed hook "type" is not "command"; reinstall to repair'],...O?.timeout===$r?[]:[`Managed hook "timeout" is not ${$r}; reinstall to repair`]]}function Ja(_){let I=Or(_.environment);if(!pm(I))return{platform:"grok-build",status:"n/a",configPath:I};let O;try{O=JSON.parse(fm(I,"utf-8"))}catch(K){return{platform:"grok-build",status:"n/a",configPath:I,errors:[`Failed to parse Grok Build hooks config ${I}: ${K instanceof Error?K.message:String(K)}`]}}let L=mm(O)[0];if(!L)return{platform:"grok-build",status:"n/a",configPath:I};let J=gm(L);return{platform:"grok-build",status:"configured",method:"hook config",configPath:I,errors:J.length>0?J:void 0}}import{readFileSync as tl}from"node:fs";import{join as rl}from"node:path";var Pn="cc-safety-net",Mo="# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent",hm=30;function Wa(_){return`${Mo}
37
+ # version: ${_}
38
+ `}function ym(_){return`${Wa(_)}name: ${Pn}
39
+ version: "${_}"
40
40
  description: "Block destructive commands and secret-file access before Hermes runs a tool."
41
41
  author: "cc-safety-net"
42
42
  provides_hooks:
43
43
  - pre_tool_call
44
- `}function J2(P){return`${Fa(P)}"""CC Safety Net guard for Hermes Agent.
44
+ `}function vm(_){return`${Wa(_)}"""CC Safety Net guard for Hermes Agent.
45
45
 
46
46
  Registers pre_tool_call and forwards the tool call to the packaged CC Safety Net
47
47
  adapter (cc-safety-net hook --hermes-agent) over JSON stdin. The adapter prints nothing
@@ -57,8 +57,8 @@ import subprocess
57
57
 
58
58
  HOOK_EVENT = "pre_tool_call"
59
59
  SUPPORTED_TOOLS = ("patch", "read_file", "terminal", "write_file")
60
- ANALYZER = [${jt["hermes-agent"].split(" ").map((A)=>`"${A}"`).join(", ")}]
61
- TIMEOUT_SECONDS = ${V2}
60
+ ANALYZER = [${In["hermes-agent"].split(" ").map((I)=>`"${I}"`).join(", ")}]
61
+ TIMEOUT_SECONDS = ${hm}
62
62
 
63
63
 
64
64
  def _block(detail):
@@ -211,90 +211,91 @@ def _pre_tool_call(tool_name="", args=None, session_id="", task_id="", **_):
211
211
 
212
212
  def register(ctx):
213
213
  ctx.register_hook("pre_tool_call", _pre_tool_call)
214
- `}function Nn(P){return[{name:"__init__.py",content:J2(P)},{name:"plugin.yaml",content:z2(P)}]}import{mkdirSync as W2,readdirSync as K2,readFileSync as Na,rmSync as Io}from"node:fs";import{basename as Y2,dirname as X2,join as Bt}from"node:path";var Z2="__pycache__",Q2=/^[a-z0-9][a-z0-9_-]{0,63}$/;function ef(P){try{return Na(P,"utf-8").trim()}catch{return}}function $o(P){let A=P.env.get("HERMES_HOME")?.trim();if(A&&Y2(X2(A))==="profiles")return A;let q=A||Bt(P.home,".hermes"),V=Bt(q,"active_profile"),ee=ef(V),ne=ee?.toLowerCase();if(!ne||ne==="default")return q;if(!Q2.test(ne))throw Error(`Invalid Hermes profile name "${ee}" in ${V}; run \`hermes profile use <name>\` with a valid profile.`);return Bt(q,"profiles",ne)}function Oo(P){return Bt($o(P),"plugins",It)}function Fo(P){return P.startsWith(To)}function No(P,A){let q=Oo(P),V=Lt(q);if(V&&(V.isSymbolicLink()||!V.isDirectory()))throw Error(`Refusing to ${A} ${q}: not a regular directory. Move or remove it and rerun ${A==="install"?"install":"uninstall"} --hermes-agent.`);return q}function ja(P,A){let q=Lt(P);if(!q)return;if(q.isSymbolicLink()||!q.isFile())throw Error(`Refusing to ${A} ${P}: not a regular file. Move or remove it.`);let V=Na(P,"utf-8");if(!Fo(V))throw Error(`Refusing to ${A} unmanaged file at ${P}. Move or remove it.`);return V}function Ma(P){let A=No(P,"install"),q=Nn(wt());if(q.map((ee)=>ja(Bt(A,ee.name),"overwrite")).every((ee,ne)=>ee===q[ne]?.content))return{path:A,alreadyInstalled:!0};return W2(A,{recursive:!0}),q.forEach((ee)=>{kt(Bt(A,ee.name),ee.content)}),{path:A,alreadyInstalled:!1}}function jo(P){let A=No(P,"remove");if(!Lt(A))return[];return Nn(wt()).filter((q)=>ja(Bt(A,q.name),"remove")!==void 0)}function Ha(P){let A=No(P,"remove");if(!Lt(A))return{path:A,alreadyInstalled:!1};let q=jo(P);if(q.forEach((V)=>{Io(Bt(A,V.name))}),Io(Bt(A,Z2),{recursive:!0,force:!0}),K2(A).length===0)Io(A,{recursive:!0});return{path:A,alreadyInstalled:q.length>0}}var jn="hermes-agent",Ua=/^([^\s#][^:]*):/,tf=/^\s+([A-Za-z_][\w-]*):/,Ga=/^\s+-\s*(.*)$/;function nf(P){return P.trim().replace(/^(["'])(.*)\1$/,"$2")}function rf(P){let A=P.split(/\r?\n/),q=A.findIndex((ne)=>Ua.exec(ne)?.[1]?.trim()==="plugins");if(q===-1)return[];let V=A.slice(q+1),ee=V.findIndex((ne)=>Ua.test(ne));return ee===-1?V:V.slice(0,ee)}function Ba(P,A){let q=rf(P),V=q.findIndex((ce)=>tf.exec(ce)?.[1]===A);if(V===-1)return[];let ee=q.slice(V+1),ne=ee.findIndex((ce)=>!Ga.test(ce));return(ne===-1?ee:ee.slice(0,ne)).map((ce)=>nf(Ga.exec(ce)?.[1]??""))}function of(P){try{return qa(Va($o(P),"config.yaml"),"utf-8")}catch{return}}function Mo(P){let A=of(P)??"";return Ba(A,"enabled").includes(It)&&!Ba(A,"disabled").includes(It)}function za(P){return/^# version:\s*(.+)$/m.exec(P)?.[1]?.trim()}function sf(P,A){let q=Lt(P);if(!q)return{error:`${A.name} is missing from ${P}; run install --hermes-agent`};if(q.isSymbolicLink()||!q.isFile())return{error:`${P} is a symlink or not a regular file; move or remove it`};try{let V=qa(P,"utf-8");if(!Fo(V))return{error:`Unmanaged ${A.name} occupies ${P}; move or remove it`};if(za(V)===wt()&&V!==A.content)return{error:`Modified ${A.name} occupies ${P}; run install --hermes-agent to restore it`};return{content:V}}catch(V){return{error:`Failed to read ${P}: ${V instanceof Error?V.message:String(V)}`}}}function af(P){try{return{path:Oo(P)}}catch(A){return{error:A instanceof Error?A.message:String(A)}}}function Ja(P){let A=af(P.environment);if("error"in A)return{platform:jn,status:"n/a",errors:[A.error]};let q=A.path,V=yr(jn,q);if(V)return V;let ee=Nn(wt()).map((ye)=>sf(Va(q,ye.name),ye)),ne=ee.flatMap((ye)=>("error"in ye)?[ye.error]:[]);if(ne.length>0)return{platform:jn,status:"n/a",configPath:q,errors:ne};let ce=ee.some((ye)=>("content"in ye)&&za(ye.content)!==wt()),he=ce?["Installed Hermes Agent plugin is outdated; run install --hermes-agent to update"]:[];if(!Mo(P.environment))return{platform:jn,status:"disabled",method:"plugin directory",configPath:q,errors:[`${It} is not enabled in Hermes; run \`hermes plugins enable ${It}\``,...he]};return{platform:jn,status:"configured",method:"plugin directory",configPath:q,errors:ce?he:void 0}}import{existsSync as lf,readFileSync as cf}from"node:fs";import{join as Wa}from"node:path";var df=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*--kimi-code(\s|["']|$)/;function uf(P){return Wa(P.env.get("KIMI_CODE_HOME")||Wa(P.home,".kimi-code"),"config.toml")}function Mn(P){let A=uf(P.environment);if(!lf(A))return{platform:"kimi-code",status:"n/a",configPath:A};try{if(!df.test(cf(A,"utf-8")))return{platform:"kimi-code",status:"n/a",configPath:A}}catch(q){return{platform:"kimi-code",status:"n/a",configPath:A,errors:[`Failed to read ${A}: ${q instanceof Error?q.message:String(q)}`]}}return{platform:"kimi-code",status:"configured",method:"hook config",configPath:A}}import{readFileSync as ol}from"node:fs";import{join as Un}from"node:path";var yt="cc-safety-net",Tt="index.js",bn="openclaw.plugin.json",Ln="package.json";var _r="// cc-safety-net managed OpenClaw plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --openclaw";import{existsSync as mf,lstatSync as gf,readdirSync as hf,readFileSync as yf}from"node:fs";import{dirname as Ya,join as Kt}from"node:path";import{fileURLToPath as vf}from"node:url";import{spawn as pf}from"node:child_process";function ff(P){return P.join(" ")}function Ho(P,A,q){return[`Failed to run ${ff(P)}${A===null?"":` (exit ${A})`}.`,q.trim()].filter(Boolean).join(`
215
- `)}function Uo(P){let A={stdout:"",stderr:""};return P.stdout.setEncoding("utf-8"),P.stderr.setEncoding("utf-8"),P.stdout.on("data",(q)=>{A.stdout+=q}),P.stderr.on("data",(q)=>{A.stderr+=q}),A}function St(P,A){return new Promise((q,V)=>{let ee=Qt([...P],process.env),ne=pf(ee.cmd,ee.args,{stdio:["ignore","pipe","pipe"]}),ce=Uo(ne),he=()=>[ce.stdout,ce.stderr].filter(Boolean).join(`
216
- `),ye=A?.timeoutMs??120000,be=setTimeout(()=>{ne.kill(),V(Error(Ho(P,null,`Timed out after ${ye}ms.
217
- ${he()}`.trim())))},ye);ne.on("error",(xe)=>{clearTimeout(be),V(Error(Ho(P,null,`${xe.message}
218
- ${he()}`.trim())))}),ne.on("close",(xe)=>{if(clearTimeout(be),xe!==0){V(Error(Ho(P,xe,he())));return}q(A?.stdoutOnly?ce.stdout:he())})})}async function Go(P){for(let A of P)await St(A)}async function Ka(P){for(let A of P)try{await St(A)}catch(q){console.warn(q instanceof Error?q.message:String(q))}}var Bo=Kt("openclaw",yt),rn=`run \`openclaw plugins enable ${yt}\``,bf="config reload superseded by a newer runtime config source",Lf=[Tt,bn,Ln];function Xa(P){let A=P.env.get("OPENCLAW_HOME")?.trim();return A?en(A,P.home):P.home}function Za(P){let A=Xa(P),q=P.env.get("OPENCLAW_STATE_DIR")?.trim();if(q)return en(q,A);let V=P.env.get("OPENCLAW_CONFIG_PATH")?.trim();return V?Ya(en(V,A)):Kt(A,".openclaw")}function Qa(P){let A=P.env.get("OPENCLAW_CONFIG_PATH")?.trim();return A?en(A,Xa(P)):Kt(Za(P),"openclaw.json")}function Hn(P){return Kt(Za(P),"extensions",yt)}function wf(P){let A=hf(P);if(A.length===0)return!0;if(A.some((ee)=>!Lf.includes(ee)))return!1;let q=Kt(P,Tt),V=Lt(q);return V!==void 0&&!V.isSymbolicLink()&&V.isFile()&&yf(q,"utf-8").startsWith(_r)}function qo(P){let A=Hn(P),q=Lt(A);if(!q)return;if(!q.isSymbolicLink()&&q.isDirectory()&&wf(A))return;throw Error(`Refusing to modify ${A}: it does not hold a cc-safety-net managed OpenClaw plugin. Move or remove it, then run the command again.`)}function el(){let P=Ya(vf(import.meta.url));return[Kt(P,Bo),Kt(P,"..",Bo),Kt(P,"..","..","..","dist",Bo)]}function Vo(P=el()){return P.find((A)=>mf(A)&&gf(A).isDirectory())}function kf(P=el()){let A=Vo(P);if(!A)throw Error("Packaged OpenClaw plugin directory not found. Reinstall cc-safety-net and try again.");return A}function tl(P=kf()){return[["openclaw","plugins","install",P,"--force","--accept-capabilities"]]}function xf(P){let A=(()=>{try{return JSON.parse(P)}catch{return}})(),q=pt(pt(A,"plugin"),"status");return typeof q==="string"?q:void 0}async function Cf(){await St(["openclaw","plugins","enable",yt]).catch((P)=>{if(!(P instanceof Error&&P.message.includes(bf)))throw P})}async function nl(P){let A=async()=>xf(await St(["openclaw","plugins","inspect",yt,"--runtime","--json"],{stdoutOnly:!0})),q=await A(),V=q==="disabled"&&P;if(V)await Cf();let ee=V?await A():q;if(ee==="loaded")return;throw Error(`${ee===void 0?`The ${yt} plugin's load state could not be verified: OpenClaw's runtime inspect report was unreadable.`:ee==="disabled"?`OpenClaw reports the ${yt} plugin with status "disabled"; ${rn}.`:`OpenClaw reports the ${yt} plugin with status "${ee}".`} Run \`openclaw plugins inspect ${yt} --runtime\` for details.`)}var Tr="openclaw";function wn(P,A){let q=Un(P,A),V=Lt(q);if(!V)return{error:`${A} is missing from ${q}; run install --openclaw`};if(V.isSymbolicLink()||!V.isFile())return{error:`${q} is a symlink or not a regular file; move or remove it`};try{return{content:ol(q,"utf-8")}}catch(ee){return{error:`Failed to read ${q}: ${ee instanceof Error?ee.message:String(ee)}`}}}function il(P){try{return JSON.parse(_t(P))}catch{return}}function Sf(P){let A=wn(P,bn);if("error"in A)return A.error;if(pt(il(A.content),"id")===yt)return;return`${Un(P,bn)} is not a valid ${yt} manifest; run install --openclaw`}function Rf(P){let A=wn(P,Ln);if("error"in A)return A.error;let q=pt(pt(il(A.content),"openclaw"),"extensions");if(Array.isArray(q)&&q.includes(`./${Tt}`))return;return`${Un(P,Ln)} does not point OpenClaw at ${Tt}; run install --openclaw`}function rl(P){return Array.isArray(P)?P.filter((A)=>typeof A==="string"):[]}function Pf(P){let A=Qa(P);if(!Lt(A))return`${yt} is not enabled; ${rn}`;let q=(()=>{try{return JSON.parse(_t(ol(A,"utf-8")))}catch{return}})();if(q===void 0)return`Failed to read ${A}; fix it, then ${rn}`;let V=pt(q,"plugins");if(pt(V,"enabled")===!1)return`plugins.enabled is false in ${A}; no OpenClaw plugin loads`;let ee=pt(pt(pt(V,"entries"),yt),"enabled");if(rl(pt(V,"deny")).includes(yt)||ee===!1)return`${yt} is disabled in ${A}; ${rn}`;let ne=rl(pt(V,"allow"));if(ne.length>0&&!ne.includes(yt))return`plugins.allow in ${A} does not list ${yt}; add it, then ${rn}`;if(ne.includes(yt)||ee===!0)return;return`${yt} is not enabled; ${rn}`}function sl(P){return/^\/\/ version:\s*(.+)$/m.exec(P)?.[1]?.trim()}function Ef(P,A,q){if(q===void 0)return[];let V=wn(q,Tt);if(!(("content"in V)&&sl(V.content)===A))return[];return[Tt,bn,Ln].flatMap((ne)=>{let ce=wn(P,ne),he=wn(q,ne);if("error"in ce||"error"in he||ce.content===he.content)return[];return[`Modified ${ne} occupies ${Un(P,ne)}; run install --openclaw to restore it`]})}function al(P){let A=Hn(P.environment),q=yr(Tr,A);if(q)return q;let V=wn(A,Tt),ne=["error"in V?V.error:V.content.startsWith(_r)?void 0:`Unmanaged ${Tt} occupies ${Un(A,Tt)}; move or remove it`,Sf(A),Rf(A)].filter((xe)=>xe!==void 0),ce="content"in V?sl(V.content):void 0,he=ne.length>0?ne:Ef(A,ce,Vo());if(he.length>0)return{platform:Tr,status:"n/a",configPath:A,errors:he};let ye=ce===wt()?[]:["Installed OpenClaw plugin is outdated; run install --openclaw to update"],be=Pf(P.environment);if(be)return{platform:Tr,status:"disabled",method:"plugin directory",configPath:A,errors:[be,...ye]};return{platform:Tr,status:"configured",method:"plugin directory",configPath:A,errors:ye.length>0?ye:void 0}}import{existsSync as Nf,readFileSync as jf}from"node:fs";import{basename as Mf}from"node:path";import{existsSync as Ir,readFileSync as zo,rmSync as Df}from"node:fs";import{join as Mt}from"node:path";import{pathToFileURL as Af}from"node:url";var Gn="cc-safety-net",on=`${Gn}@latest`,Jo=["opencode.json","opencode.jsonc"],_f=60,Tf=250,ll="CCSafetyNetPlugin",If={stringError:"Unterminated string in OpenCode config",bracketError:"Unmatched plugin array in OpenCode config"};function cl(P){return Mt(P.env.get("XDG_CONFIG_HOME")||Mt(P.home,".config"),"opencode")}function Wo(P){return P.env.get("OPENCODE_CONFIG_DIR")||cl(P)}function Ko(P){return Jo.map((A)=>Mt(Wo(P),A))}function Yo(P){return[...new Set([Wo(P),cl(P)])].flatMap((A)=>Jo.map((q)=>Mt(A,q)))}function dl(P){return Mt(P.env.get("XDG_CACHE_HOME")||Mt(P.home,".cache"),"opencode","packages",on)}function ul(P){Df(dl(P),{recursive:!0,force:!0})}async function pl(P){let A=(await St(["opencode","--version"],{stdoutOnly:!0})).trim(),q=/^(?:opencode\s+)?v?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(A),V=Number(q?.[1]),ee=Number(q?.[2]),ne=Number(q?.[3]);if(!q||V!==1&&V!==2||V===1&&(ee<18||ee===18&&ne<29)||V===2&&ee===0&&ne<6)throw Error(`OpenCode 1.18.29+ or 2.0.6+ is required; found ${A||"an unknown version"}.`);if(V===2){for(let ce of Ko(P)){if(!Ir(ce))continue;let he=Zo(zo(ce,"utf-8"),ce);if(["plugin","plugins"].some((be)=>{let xe=pt(he,be);return Array.isArray(xe)&&xe.some((Ie)=>$r(Ie)&&(typeof Ie==="string"?Ie:pt(Ie,"package"))!==on)}))throw Error(`Change the cc-safety-net package spec in ${ce} to ${on}, preserving its options, then retry. Adding another spec would create a duplicate plugin ID.`)}return{commands:[],afterInstall:async()=>{if((await St(["opencode","plugin","add",on],{stdoutOnly:!0})).includes("is already configured in"))await St(["opencode","plugin","update",on]);let he=await gl();if(!/^cc-safety-net\s+\S+\s+cc-safety-net@latest\s*$/m.test(he))throw Error("OpenCode did not load cc-safety-net from cc-safety-net@latest. Run `opencode plugin list` for details.");let ye=["--param",`location[directory]=${process.cwd()}`];await St(["opencode","api","integration.list",...ye]);let be=await St(["opencode","api","plugin.list",...ye],{stdoutOnly:!0}),xe=Xo(be);if(xe)throw Error(xe);if(!fl(be).some(ml))throw Error("OpenCode lists no active cc-safety-net for this directory. Run `opencode api plugin.list` for details.")}}}return ul(P),{commands:[["opencode","plugin","-g","-f",on]],afterInstall:()=>Of(P)}}function fl(P){return $f(P).filter((A)=>pt(A,"id")===Gn||$r(pt(pt(A,"source"),"target"))).map((A)=>pt(A,"state"))}function ml(P){return pt(P,"status")==="active"}function Xo(P){let A=fl(P);if(A.some(ml))return;let q=A.find((V)=>pt(V,"status")==="failed");if(!q)return;return`OpenCode reports cc-safety-net failed: ${String(pt(q,"error")).split(`
219
- `)[0]}`}function $f(P){if(!P)return[];try{let A=pt(JSON.parse(P),"data");return Array.isArray(A)?A:[]}catch{return[]}}async function gl(P=1){let A=await St(["opencode","plugin","list"],{stdoutOnly:!0});if(/^cc-safety-net\s|\scc-safety-net@latest\s*$/m.test(A)||P===_f)return A;return await new Promise((q)=>setTimeout(q,Tf)),gl(P+1)}async function Of(P){let A=Mt(dl(P),"node_modules",Gn),q=Mt(A,"package.json");if(!Ir(q))throw Error(`The OpenCode plugin cache at ${A} is missing its package, so OpenCode would load nothing and fail open. Run \`opencode plugin -g -f ${on}\` for details.`);let V=pt(JSON.parse(zo(q,"utf-8")),"main");if(typeof V!=="string")throw Error(`The cached OpenCode plugin at ${A} declares no "main" entry.`);let ee=Mt(A,V);if(typeof(await import(Af(ee).href))[ll]==="function")return;throw Error(`The cached OpenCode plugin at ${ee} does not export a callable ${ll}, so OpenCode would load nothing and fail open.`)}function Zo(P,A){try{return JSON.parse(_t(P))}catch(q){if(q instanceof SyntaxError)throw Error(`Failed to parse OpenCode config ${A}: ${q.message}`);throw q}}function $r(P){let A=typeof P==="string"?P:pt(P,"package");return typeof A==="string"&&(A===Gn||A.startsWith(`${Gn}@`))}function Qo(P){return["plugin","plugins"].some((A)=>{let q=pt(P,A);return Array.isArray(q)&&q.some($r)})}function Ff(P,A){let V=["plugin","plugins"].flatMap((ee)=>{let ne=ia(P,ee,If);if(!ne)return[];let ce=[],he=0,ye=ne.start+1,be=P.slice(ne.start+1,ne.end).matchAll(/\/\/[^\n]*|\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|[^"\s{}[\],/]+|[{}[\],]/g);for(let xe of be){if(xe[0].startsWith("//")||xe[0].startsWith("/*"))continue;let Ie=ne.start+1+xe.index;if(he===0)ye=Ie;if(xe[0]==="{"||xe[0]==="[")he++;if(xe[0]==="}"||xe[0]==="]")he--;if(he!==0||xe[0]===",")continue;let Xe=Ie+xe[0].length;if($r(JSON.parse(_t(P.slice(ye,Xe)))))ce.push({start:ye,end:Xe})}return ce}).sort((ee,ne)=>ee.start-ne.start).reverse().reduce((ee,ne)=>{let ce=/^(?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)*,/.exec(ee.slice(ne.end));if(ce?.[0].includes("/")){let he=ne.end+ce[0].length-1;return ee.slice(0,ne.start)+ee.slice(ne.end,he)+ee.slice(he+1)}return Lr(ee,ne)},P);return Zo(V,A),V}function hl(P){ul(P);let A=Yo(P),q=A.find((ne)=>Ir(ne)),V=[],ee=[];for(let ne of A){if(!Ir(ne))continue;try{let ce=zo(ne,"utf-8");if(!Qo(Zo(ce,ne)))continue;kt(ne,Ff(ce,ne)),ee.push(ne)}catch(ce){V.push(ce instanceof Error?ce.message:String(ce))}}if(V.length>0)throw Error(V.join(`
220
- `));return{path:ee[0]??q??Mt(Wo(P),Jo[0]),alreadyInstalled:ee.length>0}}function kn(P){let A=[];for(let q of P.openCodeVersion?.startsWith("2.")?Ko(P.environment):Yo(P.environment))if(Nf(q))try{let V=jf(q,"utf-8"),ee=_t(V),ne=JSON.parse(ee);if(Qo(ne)){let ce=Xo(P.openCodePluginListOutput);if(ce)return{platform:"opencode",status:"disabled",method:"opencode api plugin.list",configPath:q,errors:[...A,ce]};return{platform:"opencode",status:"configured",method:"plugin array",configPath:q,errors:A.length>0?A:void 0}}}catch(V){A.push(`Failed to parse ${Mf(q)}: ${V instanceof Error?V.message:String(V)}`)}return{platform:"opencode",status:"n/a",errors:A.length>0?A:void 0}}import{join as yl}from"node:path";function ei(P){let A=P.env.get("PI_CODING_AGENT_DIR");return yl(A?en(A,P.home):yl(P.home,".pi","agent"),"settings.json")}function ti(P){if(typeof P!=="string")return!1;return P==="npm:cc-safety-net"||P.startsWith("npm:cc-safety-net@")}function vl(P){let A=ei(P.environment),q=Ft(A);if(q.kind==="unreadable")return{platform:"pi",status:"not-inspected"};if(q.kind==="missing")return{platform:"pi",status:"n/a"};let V=pt(q.value,"packages");if(!Array.isArray(V))return{platform:"pi",status:"n/a"};let ee=V.find((he)=>ti(typeof he==="string"?he:pt(he,"source")));if(ee===void 0)return{platform:"pi",status:"n/a"};let ne=pt(ee,"extensions");if(Array.isArray(ne)&&ne.some((he)=>typeof he==="string"&&he.startsWith("-")))return{platform:"pi",status:"disabled",method:"package config",configPath:A,errors:["npm:cc-safety-net is installed but its extension is disabled in Pi settings"]};return{platform:"pi",status:"configured",method:"package config",configPath:A}}var Hf={amp:Ks,"antigravity-cli":Ys,"claude-code":Qs,codex:ta,"copilot-cli":ha,cursor:Ca,"gemini-cli":Sa,"grok-build":Oa,"hermes-agent":Ja,"kimi-code":Mn,openclaw:al,opencode:kn,pi:vl};function xn(P,A,q){let V={...q,cwd:A,environment:P};return rr.map((ee)=>Uf(Hf[ee](V)))}function Uf(P){if(P.status==="not-inspected")return{platform:P.platform,detected:!1,configured:!1,inspectionStatus:"not-inspected"};return{platform:P.platform,detected:P.status!=="n/a",configured:P.status==="configured",inspectionStatus:P.status!=="n/a"?"verified":P.errors&&P.errors.length>0?"failed":"not-applicable",method:P.method,configPath:P.configPath,configPaths:P.configPaths,errors:P.errors}}import{join as Gf}from"node:path";var Bf=Object.freeze([{command:"git reset --hard",description:"git reset --hard",expectBlocked:!0},{command:"rm -rf /",description:"rm -rf /",expectBlocked:!0},{command:"rm -rf ./node_modules",description:"rm in cwd (safe)",expectBlocked:!1}]),qf=Object.freeze({state:"ready",diagnostics:Object.freeze([]),ruleMetadata:Object.freeze({}),policy:Object.freeze({rules:Object.freeze([]),transparentWrappers:Object.freeze([]),safety:Object.freeze({}),worktreeMode:!1,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:Object.freeze({}),destructiveCommandAllowPaths:Object.freeze([]),secretProtection:Object.freeze({enabled:!0,disabledRules:Object.freeze([]),denyPaths:Object.freeze([]),allowPaths:Object.freeze([])})})}),Vf={strict:!1,paranoidRm:!1,paranoidInterpreters:!1,worktreeMode:!1,effectiveLevel:"standard",capabilities:{fail_closed:{enabled:!1,source:"preset",sources:[]},paranoid_rm:{enabled:!1,source:"preset",sources:[]},paranoid_interpreters:{enabled:!1,source:"preset",sources:[]}}};function bl(P){let A=Gf(P.tmpdir,"cc-safety-net-self-test"),q=Bf.map((V)=>{let ee=N(P,d("self-test",{command:V.command},{kind:"command",shell:"auto"},{configCwd:A,executionCwd:A},V.command),{guard:{dependencies:{loadPolicySnapshot:()=>qf,getModes:()=>Vf,findPolicyMutation:()=>null}},audit:{agent:"self-test",getSessionId:()=>{return}}}),ne=V.expectBlocked?"blocked":"allowed",ce=ee.decision.kind==="deny"?"blocked":"allowed";return{command:V.command,description:V.description,expected:ne,actual:ce,passed:ne===ce,reason:ee.decision.kind==="deny"?ee.decision.reason:void 0,ruleId:ee.decision.kind==="deny"?ee.decision.ruleId:void 0}});return{passed:q.filter((V)=>V.passed).length,failed:q.filter((V)=>!V.passed).length,total:q.length,results:q}}function ni(P){let A=xt({label:"doctor",booleans:{json:["--json"],skipUpdateCheck:["--skip-update-check"]}},P);if(Ut(A.errors))return null;return{json:A.flags.json,skipUpdateCheck:A.flags.skipUpdateCheck}}async function Ll(P,A={}){let q=await An(!A.json,()=>{let V=zf(P,A);return{ready:V,finish:()=>V}},()=>Dn(),{loadingMessage:"Checking system status…"});if(A.json)console.log(JSON.stringify(q,null,2));else Jf(q);return q.engineSelfTest.failed>0||q.findings.some((V)=>V.severity==="error")?1:0}async function zf(P,A){let q=A.cwd??process.cwd(),V=await pr((at)=>kn({environment:P,cwd:q,openCodeVersion:at}).status!=="n/a",void 0,q),ee=xn(P,q,{ampPluginListOutput:V.ampPluginListOutput,codexPluginListOutput:V.codexPluginListOutput,copilotCliVersion:V.versions["copilot-cli"],openCodeVersion:V.versions.opencode,openCodePluginListOutput:V.openCodePluginListOutput}),ne=us(P,q),ce=ps(P),he=E(P,{cwd:q}),ye=he.policy,be=R(ye,P.env),xe=H(ye,be.capabilities),Ie=ar(P,7),Xe=qs(P,q),et=A.skipUpdateCheck?{currentVersion:wt(),latestVersion:null,updateAvailable:!1}:await Wt(),Re={hooks:ee,engineSelfTest:bl(P),userConfig:ne.userConfig,projectConfig:ne.projectConfig,configState:Ne(he),effectiveRules:ne.effectiveRules,environment:ce,effectiveSafety:{selectedPreset:ye.safety.level??"standard",level:be.effectiveLevel,capabilities:be.capabilities,ruleOverrides:ye.destructiveCommandRuleOverrides,weakenedRuleOverrides:Object.entries(xe).filter(([,at])=>at.source==="rule_override"&&at.override==="off"&&at.inheritedEnabled&&at.changesInherited).map(([at])=>at),ruleCounts:{stored:Object.keys(ye.destructiveCommandRuleOverrides).length,effective:Object.values(xe).filter((at)=>at.changesInherited).length},...he.policyScopes?{policyScopes:he.policyScopes}:{}},...Xe.length>0?{v2Leftovers:Xe}:{},posture:Rs(P,ne.userConfig.path),activity:Ie,update:et,system:V};return{...Re,findings:ms(Re)}}function Jf(P){console.log(),console.log(hs(P.hooks)),console.log(),console.log(ys(P.engineSelfTest)),console.log(),console.log(vs(P)),console.log(),console.log(bs(P.environment)),console.log(),console.log(Ls(P)),console.log(),console.log(ws(P.findings)),console.log(),console.log(ks(P.activity)),console.log(),console.log(Cs(P.system)),console.log(),console.log(xs(P.update)),console.log(Ss(P))}import{existsSync as Wf}from"node:fs";var Kf=/^[A-Za-z0-9_@%+=:,./-]+$/,wl="Usage: cc-safety-net explain [--json] [--cwd <path>] <command>";function ri(P){let A=xt({label:"explain",booleans:{json:["--json"]},values:{cwd:["--cwd"]},positionals:"tail"},P);if(Ut(A.errors))return console.error(wl),console.error("Pass -- before a command that starts with dashes."),null;if(A.values.cwd!==void 0&&!Wf(A.values.cwd))return console.error(`Error: --cwd path does not exist: ${A.values.cwd}`),null;let q=A.positionals.length===1?A.positionals[0]:A.positionals.map((V)=>Kf.test(V)?V:`'${V.replaceAll("'","'\\''")}'`).join(" ");if(!q)return console.error("Error: No command provided"),console.error(wl),null;return{json:A.flags.json,cwd:A.values.cwd,command:q}}function kl(P){if(P)return{dh:"=",dv:"|",dtl:"+",dtr:"+",dbl:"+",dbr:"+",h:"-",v:"|",tl:"+",tr:"+",bl:"+",br:"+",sh:"="};return{dh:"═",dv:"║",dtl:"╔",dtr:"╗",dbl:"╚",dbr:"╝",h:"─",v:"│",tl:"┌",tr:"┐",bl:"└",br:"┘",sh:"━"}}function xl(P,A){let V=A-18;return[`${P.dtl}${P.dh.repeat(A)}${P.dtr}`,`${P.dv} Command Analysis${" ".repeat(V)}${P.dv}`,`${P.dbl}${P.dh.repeat(A)}${P.dbr}`]}function oi(P){return JSON.stringify(P)}function Cl(P,A=0){return`[${P.map((V,ee)=>gs(V,ee,A)).join(",")}]`}function Bn(P,A,q=70){let V=P.split(" "),ee=[],ne="";for(let ce of V)if(ne&&ne.length+ce.length+1>q)ee.push(ne),ne=ce;else ne=ne?`${ne} ${ce}`:ce;if(ne)ee.push(ne);return ee.map((ce,he)=>he===0?ce:`${A}${ce}`)}function Sl(P,A,q){let V=[];switch(P.type){case"parse":return null;case"env-strip":return V.push(""),V.push(`STEP ${A} ${q.h} Strip environment variables`),V.push(` Removed: ${P.envVars.map((ee)=>`${ee}=<redacted>`).join(", ")}`),V.push(` Tokens: ${oi(P.output)}`),{lines:V,incrementStep:!0};case"leading-tokens-stripped":return V.push(""),V.push(`STEP ${A} ${q.h} Strip wrappers`),V.push(` Removed: ${P.removed.join(", ")}`),V.push(` Tokens: ${oi(P.output)}`),{lines:V,incrementStep:!0};case"shell-wrapper":return V.push(""),V.push(`STEP ${A} ${q.h} Detect shell wrapper`),V.push(` Wrapper: ${P.wrapper} -c`),V.push(` Inner: ${P.innerCommand}`),{lines:V,incrementStep:!0};case"interpreter":{if(V.push(""),V.push(`STEP ${A} ${q.h} Detect interpreter`),V.push(` Interpreter: ${P.interpreter}`),V.push(` Code: ${P.codeArg}`),P.paranoidBlocked)V.push(" Result: ✗ BLOCKED (paranoid mode)");return{lines:V,incrementStep:!0}}case"busybox":return V.push(""),V.push(`STEP ${A} ${q.h} Busybox wrapper`),V.push(` Subcommand: ${P.subcommand}`),{lines:V,incrementStep:!0};case"transparent-wrapper":return V.push(""),V.push(`STEP ${A} ${q.h} Transparent wrapper`),V.push(` Wrapper: ${P.wrapper}`),V.push(` Tokens: ${oi(P.output)}`),{lines:V,incrementStep:!0};case"recurse":return{lines:[],incrementStep:!1};case"rule-check":{if(V.push(""),V.push(`STEP ${A} ${q.h} Match rules`),V.push(` Rule: ${P.rule}()`),P.matched)V.push(" Result: MATCHED");else V.push(" Result: No match");return{lines:V,incrementStep:!0}}case"worktree-relaxation":return V.push(""),V.push(`STEP ${A} ${q.h} Worktree relaxation`),V.push(` Mode: ${o.worktree.name}`),V.push(` Git cwd: ${P.gitCwd}`),V.push(" Result: Allowed local discard in linked worktree"),{lines:V,incrementStep:!0};case"temp-root-relaxation":return V.push(""),V.push(`STEP ${A} ${q.h} Temp-root relaxation`),V.push(` Git cwd: ${P.gitCwd}`),V.push(" Result: Allowed git discard in a temp-root repository"),{lines:V,incrementStep:!0};case"tmpdir-check":return null;case"fallback-scan":{if(P.embeddedCommandFound)return V.push(""),V.push(`STEP ${A} ${q.h} Fallback scan`),V.push(` Found: ${P.embeddedCommandFound}`),{lines:V,incrementStep:!0};return null}case"custom-rules-check":{if(P.rulesChecked){if(V.push(""),V.push(`STEP ${A} ${q.h} Custom rules`),P.matched)V.push(" Result: MATCHED");else V.push(" Result: No match");return{lines:V,incrementStep:!0}}return null}case"cwd-change":return null;case"dangerous-text":{if(P.matched)return V.push(""),V.push(`STEP ${A} ${q.h} Dangerous text check`),V.push(` Token: ${P.token}`),V.push(" Result: MATCHED"),{lines:V,incrementStep:!0};return null}case"strict-unparseable":return V.push(""),V.push(`STEP ${A} ${q.h} Strict mode check`),V.push(` Command: ${P.rawCommand}`),V.push(" Result: ✗ UNPARSEABLE"),{lines:V,incrementStep:!0};case"segment-skipped":return null;case"error":return V.push(""),V.push(`ERROR: ${P.message}`),{lines:V,incrementStep:!1};default:return P}}function ii(P,A){let q=kl(A?.asciiOnly??!1),V=58,ee=[],ne=1;ee.push(...xl(q,58)),ee.push("");let ce=P.trace.steps.find((Re)=>Re.type==="error");if(ce&&ce.type==="error"){ee.push("ERROR"),ee.push(` ${ce.message}`),ee.push(""),ee.push("RESULT"),ee.push(` Status: ${P.result==="blocked"?dt.red("BLOCKED"):dt.green("ALLOWED")}`),ee.push(""),ee.push("CONFIG");let Re=P.configSource??"none";return ee.push(` Path: ${Re}`),ee.join(`
221
- `)}let he=P.trace.steps.find((Re)=>Re.type==="parse");if(he&&he.type==="parse"){ee.push("INPUT"),ee.push(` ${he.input}`),ee.push(""),ee.push(`STEP ${ne} ${q.h} Split shell commands`),ne++;for(let Re=0;Re<he.segments.length;Re++){let at=he.segments[Re];if(at){let ct=Math.random();ee.push(` Segment ${Re+1}: ${Cl(at,ct)}`)}}}let ye=P.trace.segments,be=ye.length>1;for(let Re of ye){if(be){ee.push("");let ft="";if(he&&he.type==="parse"){let io=he.segments[Re.index];if(io)ft=io.join(" ")}let mt=54,gt=ft,ut=` Segment ${Re.index+1}: `,vt=" ";if(ft){if(ut.length+ft.length+vt.length>mt){let Xd=mt-ut.length-vt.length;gt=`${ft.substring(0,Xd-1)}…`}}let At=ft?`${ut}${gt}${vt}`:` Segment ${Re.index+1} `,Kd=ft?`${ut}${dt.cyan(gt)}${vt}`:At,Hi=58-At.length,Ui=Math.floor(Hi/2),Yd=Hi-Ui;ee.push(`${q.sh.repeat(Ui)}${Kd}${q.sh.repeat(Yd)}`)}if(Re.steps.find((ft)=>ft.type==="segment-skipped")){ee.push(""),ee.push(" (skipped — prior segment blocked)");continue}let ct=!1,lt=!1;for(let ft of Re.steps){let mt=Sl(ft,ne,q);if(mt){if(lt=!0,ft.type==="recurse"){ee.push("");let gt=" RECURSING ",ut=58-gt.length-4;ee.push(` ${q.tl}${q.h}${gt}${q.h.repeat(ut)}`),ee.push(` ${q.v}`),ct=!0;continue}for(let gt of mt.lines)if(ct)ee.push(` ${q.v} ${gt}`);else ee.push(gt);if(mt.incrementStep)ne++}}if(ct)ee.push(` ${q.v}`),ee.push(` ${q.bl}${q.h.repeat(56)}`);if(!lt)ee.push(""),ee.push(` ${dt.green("✓")} Allowed (no matching rules)`)}if(ee.push(""),ee.push("RESULT"),P.result==="blocked"){if(ee.push(` Status: ${dt.red("BLOCKED")}`),P.customRule){if(ee.push(` Rule: ${P.customRule.id}`),P.customRule.rulebook)ee.push(` Rulebook: ${P.customRule.rulebook.name} ${P.customRule.rulebook.version}`);if(P.customRule.source)ee.push(` Source: ${P.customRule.source}`);if(P.customRule.override)ee.push(` Override: reason ${P.customRule.override.reason}`)}if(P.reason){let Re=Bn(P.reason," ");ee.push(` Reason: ${Re[0]}`);for(let at=1;at<Re.length;at++)ee.push(Re[at]??"")}}else ee.push(` Status: ${dt.green("ALLOWED")}`);ee.push(""),ee.push("CONFIG");let xe=P.configSource??"none",Ie=P.configValid?"":" (invalid)";ee.push(` Path: ${xe}${Ie}`);let Xe=P.safetyPresetScope;ee.push(` Safety preset: ${P.selectedPreset??"standard"}${Xe?` (${cr(Xe)})`:""}`),ee.push(` Effective capabilities: ${P.effectiveLevel}`);let et=Object.entries(P.destructiveCommandRuleOverrides??{});if(ee.push(` Rule customizations: ${et.length}`),P.ruleActivation)ee.push(` Rule activation: ${P.ruleActivation.id} — ${P.ruleActivation.enabled?"on":"off"} via ${P.ruleActivation.source}`);return ee.join(`
222
- `)}function si(P){return JSON.stringify(P,null,2)}import{resolve as em}from"node:path";var Yf=["AKIA","ASIA","ghp_","gho_","ghu_","ghs_","ghr_","github_pat_","glpat-","xox","npm_","pypi-","rk_","sk-","sk_","gsk_","xai-","pplx-","bastn_","tgp_v1_","flp_","wfr_","fw_","fwp_","tp-","psk-"];function Rl(P){let A=0,q={allocateSegment(){return A++},getNextSegmentIndex(){return A},recordGlobal(V){P.record({kind:"step",scope:"global",step:V})},recordSegment(V,ee=q.currentSegmentIndex){if(ee===void 0)return;P.record({kind:"step",scope:"segment",segmentIndex:ee,step:V})}};return q}function Pl(P={}){let A=[],q=P.maxEvents??512,V={maxTextLength:P.maxTextLength??2048,maxListLength:P.maxListLength??128,maxObjectProperties:P.maxObjectProperties??P.maxListLength??128,maxDepth:P.maxDepth??16},ee,ne=new Set;return{record(ce){if(ee)return;if(!ce||A.length>=q)return;try{A.push(ci(Xf(ce,V,ne)))}catch{}},finish(){if(ee)return ee;return ee=ci({events:Object.freeze(A)}),ee}}}function Xf(P,A,q){if(P.kind!=="step")throw TypeError("invalid trace event");let{scope:V,step:ee}=P;Or(ee,q,A);let ne=ai(ee,A,q);if(V==="global")return{kind:"step",scope:"global",step:ne};if(V!=="segment")throw TypeError("invalid trace event scope");return{kind:"step",scope:"segment",segmentIndex:P.segmentIndex,step:ne}}function Or(P,A,q,V=0,ee=new WeakSet){if(typeof P==="string"){let he=P.slice(0,q.maxTextLength);if(!Ge(he))return;for(let ye of Ze(he))for(let be of ye.match(/[^\s"'()$]+/g)??[])A.add(El(be));return}if(!P||typeof P!=="object"||V>=q.maxDepth||ee.has(P))return;if(ee.add(P),Array.isArray(P)){let he=Math.min(P.length,q.maxListLength);for(let ye=0;ye<he;ye++)Or(P[ye],A,q,V+1,ee);return}let ne=0,ce=new Set;for(let he in P){if(!Object.hasOwn(P,he))continue;if(ne>=q.maxObjectProperties)break;ne++,Or(he,A,q);let ye=li(he,q,A);if(ce.has(ye))continue;ce.add(ye),Or(P[he],A,q,V+1,ee)}}function ai(P,A,q,V=0,ee=new WeakSet){if(typeof P==="string")return li(P,A,q);if(!P||typeof P!=="object")return P;if(V>=A.maxDepth)return;if(ee.has(P))return;if(ee.add(P),Array.isArray(P)){let he=[],ye=Math.min(P.length,A.maxListLength);for(let be=0;be<ye;be++)he.push(ai(P[be],A,q,V+1,ee));return he}let ne={},ce=0;for(let he in P){if(!Object.hasOwn(P,he))continue;if(ce>=A.maxObjectProperties)break;ce++;let ye=li(he,A,q);if(Object.hasOwn(ne,ye))continue;Object.defineProperty(ne,ye,{value:ai(P[he],A,q,V+1,ee),enumerable:!0,configurable:!0,writable:!0})}return ne}function li(P,A,q){let V=P.slice(0,A.maxTextLength),ee=Ge(V)?Ue(V):V,ne=q.size>0?Qf(ee,q):ee;return(Zf(ne)?ke(ne):ne).slice(0,A.maxTextLength)}function Zf(P){return P.includes("PRIVATE KEY")||P.includes("://")||P.includes("eyJ")||P.includes(":")&&/(?:authorization|cookie|x-api-key|api-key|(?:^|\s)(?:-u|--user)(?:\s|=))/i.test(P)||P.length>=14&&Yf.some((A)=>P.includes(A))||P.length>=49&&/\b[a-f0-9]{32}\.[A-Za-z0-9]{16}\b/.test(P)}function Qf(P,A){return P.replace(/[^\s"'()$]+/g,(q)=>A.has(El(q))?"<redacted>":q)}function El(P){let A=2166136261,q=2166136261;for(let V=0;V<P.length;V++)A=Math.imul(A^P.charCodeAt(V),16777619),q=Math.imul(q^P.charCodeAt(P.length-V-1),16777619);return`${A>>>0}:${q>>>0}:${P.length}`}function ci(P){if(P&&typeof P==="object"&&!Object.isFrozen(P)){for(let A of Object.values(P))ci(A);Object.freeze(P)}return P}function qn(P,A={},q){let V=em(A.cwd??process.cwd()),ee=A.policySnapshot??E(q,{cwd:V,userConfigDir:A.userConfigDir}),ne=R(ee.policy,q.env),ce=Fe({policySnapshot:ee,effectiveCapabilities:ne.capabilities,strict:ne.strict,paranoidRm:ne.paranoidRm,paranoidInterpreters:ne.paranoidInterpreters,worktreeMode:ne.worktreeMode}),he={effectiveLevel:ce.effectiveLevel,selectedPreset:ee.policy.safety.level??"standard",...ee.policyScopes?{safetyPresetScope:ee.policyScopes.levelScope}:{},effectiveCapabilities:ce.effectiveCapabilities,destructiveCommandRuleOverrides:ee.policy.destructiveCommandRuleOverrides},{configSource:ye,configValid:be}=nm(q,{cwd:V,userConfigDir:A.userConfigDir});if(!P||!P.trim())return{trace:{steps:[{type:"error",message:"No command provided"}],segments:[]},result:"allowed",configSource:ye,configValid:be,...he};let xe=h(P,"auto");if(xe.status==="limited")throw new y;let Ie=xe.dialect==="powershell"?h(P,"posix"):xe,Xe=st(Ie),et=Pl(),Re=Rl(et);Re.recordGlobal({type:"parse",input:P,segments:Xe.map((At)=>[...At])});let at=d("Bash",{command:P},{kind:"command",shell:"auto"},{configCwd:V,executionCwd:V},P),ct=B(at,{environment:q,trace:Re,dependencies:{loadPolicySnapshot:()=>ee}}),lt=ct.decision.kind==="deny"?ct.decision:null;if(lt&&(ct.stage==="policy-protection"||ct.stage==="secret-protection")){let At=tm(lt);return{trace:{steps:[],segments:[{index:0,steps:[{type:"rule-check",rule:At.rule,matched:!0,reason:lt.reason}]}]},result:"blocked",reason:k(lt.reason),segment:k(Dl(lt,P)),...At.ruleId?{ruleId:k(At.ruleId)}:{},configSource:ye,configValid:be,...he}}let ft=Re.getNextSegmentIndex();if(lt&&ft>0&&ft<Xe.length)Re.recordSegment({type:"segment-skipped",index:ft,reason:"prior-segment-blocked"},ft);let mt=et.finish(),gt=lt?.ruleId??rm(at,ee,ne,q),ut=G.find((At)=>At.id===gt&&At.activationCapability),vt=ut?ce.policy.effectiveDestructiveCommandRules[ut.id]:void 0;return{trace:im(mt),result:lt?"blocked":"allowed",reason:lt?k(lt.reason):void 0,segment:lt?k(Dl(lt,P)):void 0,ruleId:lt?.ruleId?k(lt.ruleId):void 0,customRule:om(sm(lt?.ruleId,ee)),configSource:ye,configValid:be,...he,...ut&&vt?{ruleActivation:{id:ut.id,...vt}}:{}}}function Dl(P,A){return P.evidence?.segment??A}function tm(P){if(P.reason===$e)return{ruleId:"policy-protection",rule:"policy-protection:findPolicyConfigMutationTargetInSemanticFacts"};if(P.reason===Me)return{ruleId:"policy-apply-protection",rule:"policy-apply-protection:findPolicyApplyInvocationInSemanticFacts"};if(P.reason===x)return{ruleId:"git-metadata-protection",rule:"git-metadata-protection:findGitMetadataMutationTargetInSemanticFacts"};return{ruleId:P.ruleId,rule:"secret-protection:findSensitiveTargetInSemanticFacts"}}function nm(P,A){let q=M(A.cwd),V=j(P,A),ee=J(P,{cwd:A.cwd,userConfigDir:A.userConfigDir});try{if(n(ee.projectConfigTarget)!==null){if(Jt(ee.projectConfigTarget).errors.length===0)return{configSource:q,configValid:!0};return{configSource:q,configValid:!1}}}catch(ne){if(ne instanceof r)return{configSource:q,configValid:!1};throw ne}try{if(n(ee.userConfigTarget)!==null){let ne=Jt(ee.userConfigTarget);return{configSource:V,configValid:ne.errors.length===0}}return{configSource:null,configValid:!0}}catch(ne){if(ne instanceof r)return{configSource:V,configValid:!1};throw ne}}function rm(P,A,q,V){let ee=A.policy,ne=Ee({...ee,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:{...ee.destructiveCommandRuleOverrides,...Object.fromEntries(G.flatMap((he)=>he.activationCapability?[[he.id,"on"]]:[]))}},A.state==="degraded"?{diagnostics:A.diagnostics,reason:A.reason}:void 0),ce=B(P,{environment:V,dependencies:{loadPolicySnapshot:()=>ne,getModes:()=>({...q,strict:!0,paranoidRm:!0,paranoidInterpreters:!0}),findSensitiveTarget:()=>null}});return ce.decision.kind==="deny"?ce.decision.ruleId:void 0}function om(P){if(!P)return;return{id:k(P.id),...P.rulebook?{rulebook:{name:k(P.rulebook.name),version:k(P.rulebook.version)}}:{},...P.source?{source:k(P.source)}:{},...P.override?{override:{type:"reason",reason:k(P.override.reason)}}:{}}}function im(P){let A=P.events.flatMap((V)=>V.kind==="step"&&V.scope==="global"?[V.step]:[]),q=new Map;for(let V of P.events){if(V.kind!=="step"||V.scope!=="segment")continue;let ee=q.get(V.segmentIndex)??{index:V.segmentIndex,steps:[]};ee.steps.push(V.step),q.set(V.segmentIndex,ee)}return{steps:A,segments:[...q.values()]}}function sm(P,A){let q=P?.replace(/^custom\./,"");if(!q||!A.policy.rules.some((V)=>V.name===q))return;return A.ruleMetadata[q]??Object.freeze({id:q})}function Al(P){return new Promise((A)=>{process.stdout.write(`${P}
223
- `,()=>A())})}async function _l(P,A){let q=ri(A);if(!q)return 1;try{let V=qn(q.command,{cwd:q.cwd},P),ee=!!process.env.NO_COLOR||!process.stdout.isTTY;return await Al(q.json?si(V):ii(V,{asciiOnly:ee})),0}catch(V){let ee=am(V instanceof p?V.cause:V);if(ee===void 0)throw V;if(q.json)return await Al(JSON.stringify({error:ee})),1;return console.error(ee),1}}function am(P){if(P instanceof y)return P.message;if(P instanceof f)return P.message;if(P instanceof s&&a[P.kind].errorCode==="path-canonicalization-limit")return"Path canonicalization work limit exceeded.";return}var Tl="2.4.14",Ot=" ",sn="cc-safety-net";function Il(P){return P.argument?`${P.flags} ${P.argument}`:P.flags}function lm(P){return Math.max(...P.map((A)=>Il(A).length))}function cm(P){return Math.max(...P.map((A)=>A.usage.length))}function dm(P){return Math.max(...P.map((A)=>`${sn} ${A.usage}`.length))}function um(P,A){let q=`${sn} ${P.usage}`;return`${Ot}${q.padEnd(A+2)}${P.description}`}function qt(P,A){return`${Ot}${P.padEnd(Math.max(40,P.length+2))}${A}`}function Cn(P,A=console.log){let q=[];if(q.push(`${sn} ${P.name}`),q.push(""),q.push(`${Ot}${P.description}`),q.push(""),q.push("USAGE:"),q.push(`${Ot}${sn} ${P.usage}`),q.push(""),P.subcommands&&P.subcommands.length>0){q.push("SUBCOMMANDS:");let V=cm(P.subcommands);for(let ee of P.subcommands)q.push(`${Ot}${ee.usage.padEnd(V+2)}${ee.description}`);q.push("")}if(P.options.length>0){q.push("OPTIONS:");let V=lm(P.options);for(let ee of P.options){let ne=Il(ee),ce=ee.default?`${ee.description} (default: ${ee.default})`:ee.description;q.push(`${Ot}${ne.padEnd(V+2)}${ce}`)}q.push("")}if(P.examples&&P.examples.length>0){q.push("EXAMPLES:");for(let V of P.examples)q.push(`${Ot}${V}`)}A(q.join(`
224
- `))}function di(){let P=dm(ir),A=[];A.push(`${sn} v${Tl}`),A.push(""),A.push("Blocks destructive commands and secret access."),A.push(""),A.push("COMMANDS:");for(let q of ir)A.push(um(q,P));A.push(""),A.push("GLOBAL OPTIONS:"),A.push(`${Ot}-h, --help Show help (use with command for command-specific help)`),A.push(`${Ot}-V, --version Show version`),A.push(""),A.push("HELP:"),A.push(`${Ot}${sn} help <command> Show help for a specific command`),A.push(`${Ot}${sn} <command> --help Show help for a specific command`),A.push(""),A.push("ENVIRONMENT VARIABLES:"),A.push(qt(`${o.level.name}=standard|strict|paranoid`,"Set session safety level")),A.push(qt(`${o.worktree.name}=1`,"Allow local git discards in linked worktrees")),A.push(qt(`${o.debug.name}=1`,"Print diagnostic messages to stderr")),A.push(qt(`${o.auditScope.name}=all|blocked`,"Record all command decisions, or denials only")),A.push(qt("CC_SAFETY_NET_HOME","Override rule config home directory")),A.push(""),A.push("LEGACY ENVIRONMENT VARIABLES (STILL SUPPORTED):"),A.push(qt(`${o.strict.name}=1`,"Force safety.overrides.fail_closed on")),A.push(qt(`${o.paranoid.name}=1`,"Force paranoid_rm and paranoid_interpreters on")),A.push(qt(`${o.paranoidRm.name}=1`,"Force safety.overrides.paranoid_rm on")),A.push(qt(`${o.paranoidInterpreters.name}=1`,"Force safety.overrides.paranoid_interpreters on")),A.push(""),A.push("Documentation: https://ccsafetynet.com/docs"),console.log(A.join(`
225
- `))}function $l(){console.log(Tl)}function Vn(P,A=console.log){let q=sr(P);if(!q)return!1;if(q.name.toLowerCase()!==P.toLowerCase())return!1;return Cn(q,A),!0}import{existsSync as Br,readFileSync as Ac}from"node:fs";import{join as Gr}from"node:path";import*as Yt from"node:readline";function pm(P){return P==="install"?"Install":"Uninstall"}function fm(P){return P==="install"?"Installing":"Uninstalling"}function mm(P){return P==="install"?"into":"from"}function Nl(P){return P?.available===!0}function gm(P,A){let q=new Set(A);return P.filter((V)=>q.has(V.target)).map((V)=>V.target)}function Ol(P,A,q){if(P.every((V)=>!V.available))return A;return Array.from({length:P.length},(V,ee)=>ee+1).map((V)=>(A+V*q+P.length)%P.length).find((V)=>Nl(P[V]))}function hm(P,A,q){if(q.ctrl&&q.name==="c")return"interrupt";if(q.name==="escape"||A==="q")return"abort";if(P==="install"&&(A==="u"||A==="U"))return"update";if(q.name==="up"||A==="k")return"up";if(q.name==="down"||A==="j")return"down";if(q.name==="space"||A===" ")return"toggle";if(q.name==="return"||q.name==="enter")return"confirm";return null}function ym(P){return{cursor:P.findIndex((A)=>A.available),selected:[]}}function vm(P,A,q){if(q==="confirm"||q==="update"||q==="abort"||q==="interrupt")return{state:P,done:q};if(q==="up")return{state:{...P,cursor:Ol(A,P.cursor,-1)}};if(q==="down")return{state:{...P,cursor:Ol(A,P.cursor,1)}};let V=A[P.cursor];if(!Nl(V))return{state:P};let ee=P.selected.includes(V.target)?P.selected.filter((ne)=>ne!==V.target):gm(A,[...P.selected,V.target]);return{state:{...P,selected:ee}}}var jl="◉",Ml="◯",Hl=">",Ul=" ";function bm(P,A,q,V={}){let ee=V.color!==!1,ne=ee?dt.dim:(ye)=>ye,ce=ee?dt.green:(ye)=>ye,he=ee?dt.bold:(ye)=>ye;return["",`${pm(P)} CC Safety Net ${mm(P)}:`,"",...A.map((ye,be)=>{let xe=q.selected.includes(ye.target),Ie=be===q.cursor,Xe=xe?jl:Ml,et=Ie?Hl:Ul,Re=ye.available?"":` (${ye.unavailableReason??"not installed"})`,at=`${Xe} ${ye.label}${Re}`,ct=!ye.available?ne(at):xe?ce(at):Ie?he(at):at;return`${et} ${ct}`}),"",P==="install"?"Space: select Enter: confirm u: update installed Up/Down: move q/Esc: cancel":A.some((ye)=>ye.available)?"Space: select Enter: confirm Up/Down: move q/Esc: cancel":`No selectable integrations found for ${P}. q/Esc: close`].join(`
226
- `)}var Fl=["global-hook","plugin"];function Lm(P,A,q={}){let V=q.color!==!1?dt.bold:(ne)=>ne;return["","Install the Kimi Code integration as:","",...[`Global hook — ${A?"already installed; selecting it reports the current state":"write the hook into ~/.kimi-code/config.toml now"}`,"Native Kimi plugin — print the steps to run inside Kimi Code"].map((ne,ce)=>{let he=ce===P,ye=`${he?jl:Ml} ${ne}`;return`${he?Hl:Ul} ${he?V(ye):ye}`}),"","Enter: confirm Up/Down: move q/Esc: cancel"].join(`
227
- `)}function Gl(P){let{input:A,output:q}=P;Yt.emitKeypressEvents(A);let V=A.isRaw===!0;A.setRawMode(!0),A.resume();let ee=0,ne=()=>{if(ee===0)return;Yt.moveCursor(q,0,-ee),Yt.cursorTo(q,0),Yt.clearScreenDown(q)},ce=()=>{ne();let he=P.render();q.write(`${he}
228
- `),ee=he.split(`
229
- `).length};return new Promise((he)=>{let ye=(xe)=>{A.off("keypress",be),A.setRawMode(V),A.pause(),ne(),he(xe)};function be(xe,Ie){P.onKey(xe,Ie,{finish:ye,draw:ce})}A.on("keypress",be),ce()})}function Bl(P={}){let A=0;return Gl({input:P.input??process.stdin,output:P.output??process.stdout,render:()=>Lm(A,P.globalHookInstalled===!0),onKey:(q,V,ee)=>{if(V.ctrl&&V.name==="c"){ee.finish(null),(P.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(V.name==="escape"||q==="q")return ee.finish(null);if(V.name==="return"||V.name==="enter")return ee.finish(Fl[A]);if(V.name==="up"||V.name==="down"||q==="k"||q==="j")A=(A+1)%Fl.length,ee.draw()}})}function ui(P=process.stdin,A=process.stdout){return Boolean(P.isTTY&&A.isTTY&&typeof P.setRawMode==="function")}function ql(P,A,q={}){let V=q.output??process.stdout,ee=ym(A);return Gl({input:q.input??process.stdin,output:V,render:()=>bm(P,A,ee),onKey:(ne,ce,he)=>{let ye=hm(P,ne,ce);if(!ye)return;let be=vm(ee,A,ye);if(ee=be.state,be.done==="interrupt"){he.finish(null),(q.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(be.done==="abort")return he.finish(null);if(be.done==="update")return he.finish("update");if(be.done==="confirm"){if(ee.selected.length===0){V.write("\x07"),he.draw();return}he.finish([...ee.selected]),V.write(`${fm(P)} selected integrations...
230
- `);return}he.draw()}})}import{existsSync as Vl,lstatSync as km,mkdirSync as xm,mkdtempSync as Cm,readdirSync as Sm,readFileSync as Rn,rmSync as Nr}from"node:fs";import{basename as Rm,dirname as Pm,join as Dt}from"node:path";import{fileURLToPath as Em}from"node:url";var pi="// cc-safety-net managed Amp plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --amp",an="cc-safety-net",ln="cc-safety-net/index.ts";import{spawn as wm}from"node:child_process";var fi=(P,A)=>{let q=Qt([...P],process.env);return new Promise((V)=>{let ee=wm(q.cmd,q.args,{cwd:A,stdio:["ignore","pipe","pipe"]}),ne=Uo(ee),ce=!1,he=setTimeout(()=>{ce=!0,ee.kill()},120000);ee.on("error",(ye)=>{clearTimeout(he),V({status:null,errorCode:ye.code,stdout:ne.stdout,stderr:[ye.message,ne.stderr].filter(Boolean).join(`
231
- `)})}),ee.on("close",(ye)=>{clearTimeout(he),V({status:ce?null:ye,errorCode:ce?"ETIMEDOUT":void 0,stdout:ne.stdout,stderr:ne.stderr})})})};var Sn="cc-safety-net.ts",mi=Dt("amp",ln);function Dm(P){return Dt(P.home,".config","amp","plugins","cc-safety-net.ts")}function Am(){let P=Pm(Em(import.meta.url)),A=Dt(P,mi),q=Dt(P,"..",mi),V=Dt(P,"..","..","..","dist",mi);return[A,q,V]}function _m(P=Am()){let A=P.find((q)=>Vl(q)&&km(q).isFile());if(!A)throw Error("Packaged Amp plugin artifact not found. Reinstall cc-safety-net and try again.");return A}function zl(P){try{return JSON.parse(P)}catch{return}}function jr(P){return P.subarray(0,Buffer.byteLength(pi)).toString("utf-8")===pi}async function zn(P,A,q){let V=await P(A,q);if(V.status===0)return V;throw Error([`Failed to run ${A.join(" ")}${V.status===null?"":` (exit ${V.status})`}.`,[V.stdout,V.stderr].filter(Boolean).join(`
214
+ `}function Ht(_){return[{name:"__init__.py",content:vm(_)},{name:"plugin.yaml",content:ym(_)}]}import{mkdirSync as bm,readdirSync as wm,readFileSync as Ka,rmSync as Uo}from"node:fs";import{basename as km,dirname as xm,join as Nn}from"node:path";var Sm="__pycache__",Cm=/^[a-z0-9][a-z0-9_-]{0,63}$/;function Rm(_){try{return Ka(_,"utf-8").trim()}catch{return}}function Go(_){let I=_.env.get("HERMES_HOME")?.trim();if(I&&km(xm(I))==="profiles")return I;let O=I||Nn(_.home,".hermes"),L=Nn(O,"active_profile"),J=Rm(L),K=J?.toLowerCase();if(!K||K==="default")return O;if(!Cm.test(K))throw Error(`Invalid Hermes profile name "${J}" in ${L}; run \`hermes profile use <name>\` with a valid profile.`);return Nn(O,"profiles",K)}function Bo(_){return Nn(Go(_),"plugins",Pn)}function qo(_){return _.startsWith(Mo)}function Vo(_,I){let O=Bo(_),L=cn(O);if(L&&(L.isSymbolicLink()||!L.isDirectory()))throw Error(`Refusing to ${I} ${O}: not a regular directory. Move or remove it and rerun ${I==="install"?"install":"uninstall"} --hermes-agent.`);return O}function Ya(_,I){let O=cn(_);if(!O)return;if(O.isSymbolicLink()||!O.isFile())throw Error(`Refusing to ${I} ${_}: not a regular file. Move or remove it.`);let L=Ka(_,"utf-8");if(!qo(L))throw Error(`Refusing to ${I} unmanaged file at ${_}. Move or remove it.`);return L}function Za(_){let I=Vo(_,"install"),O=Ht(fn());if(O.map((J)=>Ya(Nn(I,J.name),"overwrite")).every((J,K)=>J===O[K]?.content))return{path:I,alreadyInstalled:!0};return bm(I,{recursive:!0}),O.forEach((J)=>{mn(Nn(I,J.name),J.content)}),{path:I,alreadyInstalled:!1}}function zo(_){let I=Vo(_,"remove");if(!cn(I))return[];return Ht(fn()).filter((O)=>Ya(Nn(I,O.name),"remove")!==void 0)}function Xa(_){let I=Vo(_,"remove");if(!cn(I))return{path:I,alreadyInstalled:!1};let O=zo(_);if(O.forEach((L)=>{Uo(Nn(I,L.name))}),Uo(Nn(I,Sm),{recursive:!0,force:!0}),wm(I).length===0)Uo(I,{recursive:!0});return{path:I,alreadyInstalled:O.length>0}}var Mt="hermes-agent",Qa=/^([^\s#][^:]*):/,Pm=/^\s+([A-Za-z_][\w-]*):/,el=/^\s+-\s*(.*)$/;function Em(_){return _.trim().replace(/^(["'])(.*)\1$/,"$2")}function Am(_){let I=_.split(/\r?\n/),O=I.findIndex((K)=>Qa.exec(K)?.[1]?.trim()==="plugins");if(O===-1)return[];let L=I.slice(O+1),J=L.findIndex((K)=>Qa.test(K));return J===-1?L:L.slice(0,J)}function nl(_,I){let O=Am(_),L=O.findIndex((ne)=>Pm.exec(ne)?.[1]===I);if(L===-1)return[];let J=O.slice(L+1),K=J.findIndex((ne)=>!el.test(ne));return(K===-1?J:J.slice(0,K)).map((ne)=>Em(el.exec(ne)?.[1]??""))}function _m(_){try{return tl(rl(Go(_),"config.yaml"),"utf-8")}catch{return}}function Jo(_){let I=_m(_)??"";return nl(I,"enabled").includes(Pn)&&!nl(I,"disabled").includes(Pn)}function ol(_){return/^# version:\s*(.+)$/m.exec(_)?.[1]?.trim()}function Im(_,I){let O=cn(_);if(!O)return{error:`${I.name} is missing from ${_}; run install --hermes-agent`};if(O.isSymbolicLink()||!O.isFile())return{error:`${_} is a symlink or not a regular file; move or remove it`};try{let L=tl(_,"utf-8");if(!qo(L))return{error:`Unmanaged ${I.name} occupies ${_}; move or remove it`};if(ol(L)===fn()&&L!==I.content)return{error:`Modified ${I.name} occupies ${_}; run install --hermes-agent to restore it`};return{content:L}}catch(L){return{error:`Failed to read ${_}: ${L instanceof Error?L.message:String(L)}`}}}function Tm(_){try{return{path:Bo(_)}}catch(I){return{error:I instanceof Error?I.message:String(I)}}}function il(_){let I=Tm(_.environment);if("error"in I)return{platform:Mt,status:"n/a",errors:[I.error]};let O=I.path,L=wr(Mt,O);if(L)return L;let J=Ht(fn()).map((de)=>Im(rl(O,de.name),de)),K=J.flatMap((de)=>("error"in de)?[de.error]:[]);if(K.length>0)return{platform:Mt,status:"n/a",configPath:O,errors:K};let ne=J.some((de)=>("content"in de)&&ol(de.content)!==fn()),oe=ne?["Installed Hermes Agent plugin is outdated; run install --hermes-agent to update"]:[];if(!Jo(_.environment))return{platform:Mt,status:"disabled",method:"plugin directory",configPath:O,errors:[`${Pn} is not enabled in Hermes; run \`hermes plugins enable ${Pn}\``,...oe]};return{platform:Mt,status:"configured",method:"plugin directory",configPath:O,errors:ne?oe:void 0}}import{existsSync as $m,readFileSync as Om}from"node:fs";import{join as sl}from"node:path";var Dm=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*--kimi-code(\s|["']|$)/;function Lm(_){return sl(_.env.get("KIMI_CODE_HOME")||sl(_.home,".kimi-code"),"config.toml")}function Ut(_){let I=Lm(_.environment);if(!$m(I))return{platform:"kimi-code",status:"n/a",configPath:I};try{if(!Dm.test(Om(I,"utf-8")))return{platform:"kimi-code",status:"n/a",configPath:I}}catch(O){return{platform:"kimi-code",status:"n/a",configPath:I,errors:[`Failed to read ${I}: ${O instanceof Error?O.message:String(O)}`]}}return{platform:"kimi-code",status:"configured",method:"hook config",configPath:I}}import{readFileSync as hl}from"node:fs";import{join as Bt}from"node:path";var dn="cc-safety-net",Cn="index.js",kt="openclaw.plugin.json",xt="package.json";var Dr="// cc-safety-net managed OpenClaw plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --openclaw";import{existsSync as Fm,lstatSync as Hm,readdirSync as Mm,readFileSync as Um}from"node:fs";import{dirname as ll,join as Bn}from"node:path";import{fileURLToPath as Gm}from"node:url";import{spawn as Nm}from"node:child_process";function jm(_){return _.join(" ")}function Wo(_,I,O){return[`Failed to run ${jm(_)}${I===null?"":` (exit ${I})`}.`,O.trim()].filter(Boolean).join(`
215
+ `)}function Ko(_){let I={stdout:"",stderr:""};return _.stdout.setEncoding("utf-8"),_.stderr.setEncoding("utf-8"),_.stdout.on("data",(O)=>{I.stdout+=O}),_.stderr.on("data",(O)=>{I.stderr+=O}),I}function yn(_,I){return new Promise((O,L)=>{let J=Wn([..._],process.env),K=Nm(J.cmd,J.args,{stdio:["ignore","pipe","pipe"]}),ne=Ko(K),oe=()=>[ne.stdout,ne.stderr].filter(Boolean).join(`
216
+ `),de=I?.timeoutMs??120000,ue=setTimeout(()=>{K.kill(),L(Error(Wo(_,null,`Timed out after ${de}ms.
217
+ ${oe()}`.trim())))},de);K.on("error",(ve)=>{clearTimeout(ue),L(Error(Wo(_,null,`${ve.message}
218
+ ${oe()}`.trim())))}),K.on("close",(ve)=>{if(clearTimeout(ue),ve!==0){L(Error(Wo(_,ve,oe())));return}O(I?.stdoutOnly?ne.stdout:oe())})})}async function Yo(_){for(let I of _)await yn(I)}async function al(_){for(let I of _)try{await yn(I)}catch(O){console.warn(O instanceof Error?O.message:String(O))}}var Zo=Bn("openclaw",dn),Zn=`run \`openclaw plugins enable ${dn}\``,Bm="config reload superseded by a newer runtime config source",qm=[Cn,kt,xt];function cl(_){let I=_.env.get("OPENCLAW_HOME")?.trim();return I?Ln(I,_.home):_.home}function dl(_){let I=cl(_),O=_.env.get("OPENCLAW_STATE_DIR")?.trim();if(O)return Ln(O,I);let L=_.env.get("OPENCLAW_CONFIG_PATH")?.trim();return L?ll(Ln(L,I)):Bn(I,".openclaw")}function ul(_){let I=_.env.get("OPENCLAW_CONFIG_PATH")?.trim();return I?Ln(I,cl(_)):Bn(dl(_),"openclaw.json")}function Gt(_){return Bn(dl(_),"extensions",dn)}function Vm(_){let I=Mm(_);if(I.length===0)return!0;if(I.some((J)=>!qm.includes(J)))return!1;let O=Bn(_,Cn),L=cn(O);return L!==void 0&&!L.isSymbolicLink()&&L.isFile()&&Um(O,"utf-8").startsWith(Dr)}function Xo(_){let I=Gt(_),O=cn(I);if(!O)return;if(!O.isSymbolicLink()&&O.isDirectory()&&Vm(I))return;throw Error(`Refusing to modify ${I}: it does not hold a cc-safety-net managed OpenClaw plugin. Move or remove it, then run the command again.`)}function pl(){let _=ll(Gm(import.meta.url));return[Bn(_,Zo),Bn(_,"..",Zo),Bn(_,"..","..","..","dist",Zo)]}function Qo(_=pl()){return _.find((I)=>Fm(I)&&Hm(I).isDirectory())}function zm(_=pl()){let I=Qo(_);if(!I)throw Error("Packaged OpenClaw plugin directory not found. Reinstall cc-safety-net and try again.");return I}function fl(_=zm()){return[["openclaw","plugins","install",_,"--force","--accept-capabilities"]]}function Jm(_){let I=(()=>{try{return JSON.parse(_)}catch{return}})(),O=tn(tn(I,"plugin"),"status");return typeof O==="string"?O:void 0}async function Wm(){await yn(["openclaw","plugins","enable",dn]).catch((_)=>{if(!(_ instanceof Error&&_.message.includes(Bm)))throw _})}async function ml(_){let I=async()=>Jm(await yn(["openclaw","plugins","inspect",dn,"--runtime","--json"],{stdoutOnly:!0})),O=await I(),L=O==="disabled"&&_;if(L)await Wm();let J=L?await I():O;if(J==="loaded")return;throw Error(`${J===void 0?`The ${dn} plugin's load state could not be verified: OpenClaw's runtime inspect report was unreadable.`:J==="disabled"?`OpenClaw reports the ${dn} plugin with status "disabled"; ${Zn}.`:`OpenClaw reports the ${dn} plugin with status "${J}".`} Run \`openclaw plugins inspect ${dn} --runtime\` for details.`)}var Lr="openclaw";function St(_,I){let O=Bt(_,I),L=cn(O);if(!L)return{error:`${I} is missing from ${O}; run install --openclaw`};if(L.isSymbolicLink()||!L.isFile())return{error:`${O} is a symlink or not a regular file; move or remove it`};try{return{content:hl(O,"utf-8")}}catch(J){return{error:`Failed to read ${O}: ${J instanceof Error?J.message:String(J)}`}}}function yl(_){try{return JSON.parse(Sn(_))}catch{return}}function Km(_){let I=St(_,kt);if("error"in I)return I.error;if(tn(yl(I.content),"id")===dn)return;return`${Bt(_,kt)} is not a valid ${dn} manifest; run install --openclaw`}function Ym(_){let I=St(_,xt);if("error"in I)return I.error;let O=tn(tn(yl(I.content),"openclaw"),"extensions");if(Array.isArray(O)&&O.includes(`./${Cn}`))return;return`${Bt(_,xt)} does not point OpenClaw at ${Cn}; run install --openclaw`}function gl(_){return Array.isArray(_)?_.filter((I)=>typeof I==="string"):[]}function Zm(_){let I=ul(_);if(!cn(I))return`${dn} is not enabled; ${Zn}`;let O=(()=>{try{return JSON.parse(Sn(hl(I,"utf-8")))}catch{return}})();if(O===void 0)return`Failed to read ${I}; fix it, then ${Zn}`;let L=tn(O,"plugins");if(tn(L,"enabled")===!1)return`plugins.enabled is false in ${I}; no OpenClaw plugin loads`;let J=tn(tn(tn(L,"entries"),dn),"enabled");if(gl(tn(L,"deny")).includes(dn)||J===!1)return`${dn} is disabled in ${I}; ${Zn}`;let K=gl(tn(L,"allow"));if(K.length>0&&!K.includes(dn))return`plugins.allow in ${I} does not list ${dn}; add it, then ${Zn}`;if(K.includes(dn)||J===!0)return;return`${dn} is not enabled; ${Zn}`}function vl(_){return/^\/\/ version:\s*(.+)$/m.exec(_)?.[1]?.trim()}function Xm(_,I,O){if(O===void 0)return[];let L=St(O,Cn);if(!(("content"in L)&&vl(L.content)===I))return[];return[Cn,kt,xt].flatMap((K)=>{let ne=St(_,K),oe=St(O,K);if("error"in ne||"error"in oe||ne.content===oe.content)return[];return[`Modified ${K} occupies ${Bt(_,K)}; run install --openclaw to restore it`]})}function bl(_){let I=Gt(_.environment),O=wr(Lr,I);if(O)return O;let L=St(I,Cn),K=["error"in L?L.error:L.content.startsWith(Dr)?void 0:`Unmanaged ${Cn} occupies ${Bt(I,Cn)}; move or remove it`,Km(I),Ym(I)].filter((ve)=>ve!==void 0),ne="content"in L?vl(L.content):void 0,oe=K.length>0?K:Xm(I,ne,Qo());if(oe.length>0)return{platform:Lr,status:"n/a",configPath:I,errors:oe};let de=ne===fn()?[]:["Installed OpenClaw plugin is outdated; run install --openclaw to update"],ue=Zm(_.environment);if(ue)return{platform:Lr,status:"disabled",method:"plugin directory",configPath:I,errors:[ue,...de]};return{platform:Lr,status:"configured",method:"plugin directory",configPath:I,errors:de.length>0?de:void 0}}import{existsSync as ag,readFileSync as lg}from"node:fs";import{basename as cg}from"node:path";import{existsSync as Nr,readFileSync as ei,rmSync as Qm}from"node:fs";import{join as Tn}from"node:path";import{pathToFileURL as eg}from"node:url";var qt="cc-safety-net",Xn=`${qt}@latest`,ni=["opencode.json","opencode.jsonc"],ng=60,tg=250,wl="CCSafetyNetPlugin",rg={stringError:"Unterminated string in OpenCode config",bracketError:"Unmatched plugin array in OpenCode config"};function kl(_){return Tn(_.env.get("XDG_CONFIG_HOME")||Tn(_.home,".config"),"opencode")}function ti(_){return _.env.get("OPENCODE_CONFIG_DIR")||kl(_)}function ri(_){return ni.map((I)=>Tn(ti(_),I))}function oi(_){return[...new Set([ti(_),kl(_)])].flatMap((I)=>ni.map((O)=>Tn(I,O)))}function xl(_){return Tn(_.env.get("XDG_CACHE_HOME")||Tn(_.home,".cache"),"opencode","packages",Xn)}function Sl(_){Qm(xl(_),{recursive:!0,force:!0})}async function Cl(_){let I=(await yn(["opencode","--version"],{stdoutOnly:!0})).trim(),O=/^(?:opencode\s+)?v?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(I),L=Number(O?.[1]),J=Number(O?.[2]),K=Number(O?.[3]);if(!O||L!==1&&L!==2||L===1&&(J<18||J===18&&K<29)||L===2&&J===0&&K<6)throw Error(`OpenCode 1.18.29+ or 2.0.6+ is required; found ${I||"an unknown version"}.`);if(L===2){for(let ne of ri(_)){if(!Nr(ne))continue;let oe=si(ei(ne,"utf-8"),ne);if(["plugin","plugins"].some((ue)=>{let ve=tn(oe,ue);return Array.isArray(ve)&&ve.some((xe)=>jr(xe)&&(typeof xe==="string"?xe:tn(xe,"package"))!==Xn)}))throw Error(`Change the cc-safety-net package spec in ${ne} to ${Xn}, preserving its options, then retry. Adding another spec would create a duplicate plugin ID.`)}return{commands:[],afterInstall:async()=>{if((await yn(["opencode","plugin","add",Xn],{stdoutOnly:!0})).includes("is already configured in"))await yn(["opencode","plugin","update",Xn]);let oe=await El();if(!/^cc-safety-net\s+\S+\s+cc-safety-net@latest\s*$/m.test(oe))throw Error("OpenCode did not load cc-safety-net from cc-safety-net@latest. Run `opencode plugin list` for details.");let de=["--param",`location[directory]=${process.cwd()}`];await yn(["opencode","api","integration.list",...de]);let ue=await yn(["opencode","api","plugin.list",...de],{stdoutOnly:!0}),ve=ii(ue);if(ve)throw Error(ve);if(!Rl(ue).some(Pl))throw Error("OpenCode lists no active cc-safety-net for this directory. Run `opencode api plugin.list` for details.")}}}return Sl(_),{commands:[["opencode","plugin","-g","-f",Xn]],afterInstall:()=>ig(_)}}function Rl(_){return og(_).filter((I)=>tn(I,"id")===qt||jr(tn(tn(I,"source"),"target"))).map((I)=>tn(I,"state"))}function Pl(_){return tn(_,"status")==="active"}function ii(_){let I=Rl(_);if(I.some(Pl))return;let O=I.find((L)=>tn(L,"status")==="failed");if(!O)return;return`OpenCode reports cc-safety-net failed: ${String(tn(O,"error")).split(`
219
+ `)[0]}`}function og(_){if(!_)return[];try{let I=tn(JSON.parse(_),"data");return Array.isArray(I)?I:[]}catch{return[]}}async function El(_=1){let I=await yn(["opencode","plugin","list"],{stdoutOnly:!0});if(/^cc-safety-net\s|\scc-safety-net@latest\s*$/m.test(I)||_===ng)return I;return await new Promise((O)=>setTimeout(O,tg)),El(_+1)}async function ig(_){let I=Tn(xl(_),"node_modules",qt),O=Tn(I,"package.json");if(!Nr(O))throw Error(`The OpenCode plugin cache at ${I} is missing its package, so OpenCode would load nothing and fail open. Run \`opencode plugin -g -f ${Xn}\` for details.`);let L=tn(JSON.parse(ei(O,"utf-8")),"main");if(typeof L!=="string")throw Error(`The cached OpenCode plugin at ${I} declares no "main" entry.`);let J=Tn(I,L);if(typeof(await import(eg(J).href))[wl]==="function")return;throw Error(`The cached OpenCode plugin at ${J} does not export a callable ${wl}, so OpenCode would load nothing and fail open.`)}function si(_,I){try{return JSON.parse(Sn(_))}catch(O){if(O instanceof SyntaxError)throw Error(`Failed to parse OpenCode config ${I}: ${O.message}`);throw O}}function jr(_){let I=typeof _==="string"?_:tn(_,"package");return typeof I==="string"&&(I===qt||I.startsWith(`${qt}@`))}function ai(_){return["plugin","plugins"].some((I)=>{let O=tn(_,I);return Array.isArray(O)&&O.some(jr)})}function sg(_,I){let L=["plugin","plugins"].flatMap((J)=>{let K=ga(_,J,rg);if(!K)return[];let ne=[],oe=0,de=K.start+1,ue=_.slice(K.start+1,K.end).matchAll(/\/\/[^\n]*|\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|[^"\s{}[\],/]+|[{}[\],]/g);for(let ve of ue){if(ve[0].startsWith("//")||ve[0].startsWith("/*"))continue;let xe=K.start+1+ve.index;if(oe===0)de=xe;if(ve[0]==="{"||ve[0]==="[")oe++;if(ve[0]==="}"||ve[0]==="]")oe--;if(oe!==0||ve[0]===",")continue;let Se=xe+ve[0].length;if(jr(JSON.parse(Sn(_.slice(de,Se)))))ne.push({start:de,end:Se})}return ne}).sort((J,K)=>J.start-K.start).reverse().reduce((J,K)=>{let ne=/^(?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)*,/.exec(J.slice(K.end));if(ne?.[0].includes("/")){let oe=K.end+ne[0].length-1;return J.slice(0,K.start)+J.slice(K.end,oe)+J.slice(oe+1)}return Sr(J,K)},_);return si(L,I),L}function Al(_){Sl(_);let I=oi(_),O=I.find((K)=>Nr(K)),L=[],J=[];for(let K of I){if(!Nr(K))continue;try{let ne=ei(K,"utf-8");if(!ai(si(ne,K)))continue;mn(K,sg(ne,K)),J.push(K)}catch(ne){L.push(ne instanceof Error?ne.message:String(ne))}}if(L.length>0)throw Error(L.join(`
220
+ `));return{path:J[0]??O??Tn(ti(_),ni[0]),alreadyInstalled:J.length>0}}function Ct(_){let I=[];for(let O of _.openCodeVersion?.startsWith("2.")?ri(_.environment):oi(_.environment))if(ag(O))try{let L=lg(O,"utf-8"),J=Sn(L),K=JSON.parse(J);if(ai(K)){let ne=ii(_.openCodePluginListOutput);if(ne)return{platform:"opencode",status:"disabled",method:"opencode api plugin.list",configPath:O,errors:[...I,ne]};return{platform:"opencode",status:"configured",method:"plugin array",configPath:O,errors:I.length>0?I:void 0}}}catch(L){I.push(`Failed to parse ${cg(O)}: ${L instanceof Error?L.message:String(L)}`)}return{platform:"opencode",status:"n/a",errors:I.length>0?I:void 0}}import{join as _l}from"node:path";function li(_){let I=_.env.get("PI_CODING_AGENT_DIR");return _l(I?Ln(I,_.home):_l(_.home,".pi","agent"),"settings.json")}function ci(_){if(typeof _!=="string")return!1;return _==="npm:cc-safety-net"||_.startsWith("npm:cc-safety-net@")}function Il(_){let I=li(_.environment),O=Rn(I);if(O.kind==="unreadable")return{platform:"pi",status:"not-inspected"};if(O.kind==="missing")return{platform:"pi",status:"n/a"};let L=tn(O.value,"packages");if(!Array.isArray(L))return{platform:"pi",status:"n/a"};let J=L.find((oe)=>ci(typeof oe==="string"?oe:tn(oe,"source")));if(J===void 0)return{platform:"pi",status:"n/a"};let K=tn(J,"extensions");if(Array.isArray(K)&&K.some((oe)=>typeof oe==="string"&&oe.startsWith("-")))return{platform:"pi",status:"disabled",method:"package config",configPath:I,errors:["npm:cc-safety-net is installed but its extension is disabled in Pi settings"]};return{platform:"pi",status:"configured",method:"package config",configPath:I}}var dg={amp:ia,"antigravity-cli":sa,"claude-code":ca,codex:ua,"copilot-cli":Pa,cursor:Da,"deepseek-harness":Na,"gemini-cli":ja,"grok-build":Ja,"hermes-agent":il,"kimi-code":Ut,openclaw:bl,opencode:Ct,pi:Il};function Rt(_,I,O){let L={...O,cwd:I,environment:_};return sr.map((J)=>ug(dg[J](L)))}function ug(_){if(_.status==="not-inspected")return{platform:_.platform,detected:!1,configured:!1,inspectionStatus:"not-inspected"};return{platform:_.platform,detected:_.status!=="n/a",configured:_.status==="configured",inspectionStatus:_.status!=="n/a"?"verified":_.errors&&_.errors.length>0?"failed":"not-applicable",method:_.method,configPath:_.configPath,configPaths:_.configPaths,errors:_.errors}}import{join as pg}from"node:path";var fg=Object.freeze([{command:"git reset --hard",description:"git reset --hard",expectBlocked:!0},{command:"rm -rf /",description:"rm -rf /",expectBlocked:!0},{command:"rm -rf ./node_modules",description:"rm in cwd (safe)",expectBlocked:!1}]),mg=Object.freeze({state:"ready",diagnostics:Object.freeze([]),ruleMetadata:Object.freeze({}),policy:Object.freeze({rules:Object.freeze([]),transparentWrappers:Object.freeze([]),safety:Object.freeze({}),worktreeMode:!1,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:Object.freeze({}),destructiveCommandAllowPaths:Object.freeze([]),secretProtection:Object.freeze({enabled:!0,disabledRules:Object.freeze([]),denyPaths:Object.freeze([]),allowPaths:Object.freeze([])})})}),gg={strict:!1,paranoidRm:!1,paranoidInterpreters:!1,worktreeMode:!1,effectiveLevel:"standard",capabilities:{fail_closed:{enabled:!1,source:"preset",sources:[]},paranoid_rm:{enabled:!1,source:"preset",sources:[]},paranoid_interpreters:{enabled:!1,source:"preset",sources:[]}}};function Tl(_){let I=pg(_.tmpdir,"cc-safety-net-self-test"),O=fg.map((L)=>{let J=M(_,l("self-test",{command:L.command},{kind:"command",shell:"auto"},{configCwd:I,executionCwd:I},L.command),{guard:{dependencies:{loadPolicySnapshot:()=>mg,getModes:()=>gg,findPolicyMutation:()=>null}},audit:{agent:"self-test",getSessionId:()=>{return}}}),K=L.expectBlocked?"blocked":"allowed",ne=J.decision.kind==="deny"?"blocked":"allowed";return{command:L.command,description:L.description,expected:K,actual:ne,passed:K===ne,reason:J.decision.kind==="deny"?J.decision.reason:void 0,ruleId:J.decision.kind==="deny"?J.decision.ruleId:void 0}});return{passed:O.filter((L)=>L.passed).length,failed:O.filter((L)=>!L.passed).length,total:O.length,results:O}}function di(_){let I=gn({label:"doctor",booleans:{json:["--json"],skipUpdateCheck:["--skip-update-check"]}},_);if(On(I.errors))return null;return{json:I.flags.json,skipUpdateCheck:I.flags.skipUpdateCheck}}async function $l(_,I={}){let O=await $t(!I.json,()=>{let L=hg(_,I);return{ready:L,finish:()=>L}},()=>Tt(),{loadingMessage:"Checking system status…"});if(I.json)console.log(JSON.stringify(O,null,2));else yg(O);return O.engineSelfTest.failed>0||O.findings.some((L)=>L.severity==="error")?1:0}async function hg(_,I){let O=I.cwd??process.cwd(),L=await gr((Le)=>Ct({environment:_,cwd:O,openCodeVersion:Le}).status!=="n/a",void 0,O),J=Rt(_,O,{ampPluginListOutput:L.ampPluginListOutput,codexPluginListOutput:L.codexPluginListOutput,copilotCliVersion:L.versions["copilot-cli"],openCodeVersion:L.versions.opencode,openCodePluginListOutput:L.openCodePluginListOutput}),K=ks(_,O),ne=xs(_),oe=E(_,{cwd:O}),de=oe.policy,ue=R(de,_.env),ve=B(de,ue.capabilities),xe=dr(_,7),Se=ea(_,O),Pe=I.skipUpdateCheck?{currentVersion:fn(),latestVersion:null,updateAvailable:!1}:await Gn(),we={hooks:J,engineSelfTest:Tl(_),userConfig:K.userConfig,projectConfig:K.projectConfig,configState:$e(oe),effectiveRules:K.effectiveRules,environment:ne,effectiveSafety:{selectedPreset:de.safety.level??"standard",level:ue.effectiveLevel,capabilities:ue.capabilities,ruleOverrides:de.destructiveCommandRuleOverrides,weakenedRuleOverrides:Object.entries(ve).filter(([,Le])=>Le.source==="rule_override"&&Le.override==="off"&&Le.inheritedEnabled&&Le.changesInherited).map(([Le])=>Le),ruleCounts:{stored:Object.keys(de.destructiveCommandRuleOverrides).length,effective:Object.values(ve).filter((Le)=>Le.changesInherited).length},...oe.policyScopes?{policyScopes:oe.policyScopes}:{}},...Se.length>0?{v2Leftovers:Se}:{},posture:Ns(_,K.userConfig.path),activity:xe,update:Pe,system:L};return{...we,findings:Cs(we)}}function yg(_){console.log(),console.log(Ps(_.hooks)),console.log(),console.log(Es(_.engineSelfTest)),console.log(),console.log(As(_)),console.log(),console.log(_s(_.environment)),console.log(),console.log(Is(_)),console.log(),console.log(Ts(_.findings)),console.log(),console.log($s(_.activity)),console.log(),console.log(Ds(_.system)),console.log(),console.log(Os(_.update)),console.log(Ls(_))}import{existsSync as vg}from"node:fs";var bg=/^[A-Za-z0-9_@%+=:,./-]+$/,Ol="Usage: cc-safety-net explain [--json] [--cwd <path>] <command>";function ui(_){let I=gn({label:"explain",booleans:{json:["--json"]},values:{cwd:["--cwd"]},positionals:"tail"},_);if(On(I.errors))return console.error(Ol),console.error("Pass -- before a command that starts with dashes."),null;if(I.values.cwd!==void 0&&!vg(I.values.cwd))return console.error(`Error: --cwd path does not exist: ${I.values.cwd}`),null;let O=I.positionals.length===1?I.positionals[0]:I.positionals.map((L)=>bg.test(L)?L:`'${L.replaceAll("'","'\\''")}'`).join(" ");if(!O)return console.error("Error: No command provided"),console.error(Ol),null;return{json:I.flags.json,cwd:I.values.cwd,command:O}}function Dl(_){if(_)return{dh:"=",dv:"|",dtl:"+",dtr:"+",dbl:"+",dbr:"+",h:"-",v:"|",tl:"+",tr:"+",bl:"+",br:"+",sh:"="};return{dh:"═",dv:"║",dtl:"╔",dtr:"╗",dbl:"╚",dbr:"╝",h:"─",v:"│",tl:"┌",tr:"┐",bl:"└",br:"┘",sh:"━"}}function Ll(_,I){let L=I-18;return[`${_.dtl}${_.dh.repeat(I)}${_.dtr}`,`${_.dv} Command Analysis${" ".repeat(L)}${_.dv}`,`${_.dbl}${_.dh.repeat(I)}${_.dbr}`]}function pi(_){return JSON.stringify(_)}function Nl(_,I=0){return`[${_.map((L,J)=>Rs(L,J,I)).join(",")}]`}function Vt(_,I,O=70){let L=_.split(" "),J=[],K="";for(let ne of L)if(K&&K.length+ne.length+1>O)J.push(K),K=ne;else K=K?`${K} ${ne}`:ne;if(K)J.push(K);return J.map((ne,oe)=>oe===0?ne:`${I}${ne}`)}function jl(_,I,O){let L=[];switch(_.type){case"parse":return null;case"env-strip":return L.push(""),L.push(`STEP ${I} ${O.h} Strip environment variables`),L.push(` Removed: ${_.envVars.map((J)=>`${J}=<redacted>`).join(", ")}`),L.push(` Tokens: ${pi(_.output)}`),{lines:L,incrementStep:!0};case"leading-tokens-stripped":return L.push(""),L.push(`STEP ${I} ${O.h} Strip wrappers`),L.push(` Removed: ${_.removed.join(", ")}`),L.push(` Tokens: ${pi(_.output)}`),{lines:L,incrementStep:!0};case"shell-wrapper":return L.push(""),L.push(`STEP ${I} ${O.h} Detect shell wrapper`),L.push(` Wrapper: ${_.wrapper} -c`),L.push(` Inner: ${_.innerCommand}`),{lines:L,incrementStep:!0};case"interpreter":{if(L.push(""),L.push(`STEP ${I} ${O.h} Detect interpreter`),L.push(` Interpreter: ${_.interpreter}`),L.push(` Code: ${_.codeArg}`),_.paranoidBlocked)L.push(" Result: ✗ BLOCKED (paranoid mode)");return{lines:L,incrementStep:!0}}case"busybox":return L.push(""),L.push(`STEP ${I} ${O.h} Busybox wrapper`),L.push(` Subcommand: ${_.subcommand}`),{lines:L,incrementStep:!0};case"transparent-wrapper":return L.push(""),L.push(`STEP ${I} ${O.h} Transparent wrapper`),L.push(` Wrapper: ${_.wrapper}`),L.push(` Tokens: ${pi(_.output)}`),{lines:L,incrementStep:!0};case"recurse":return{lines:[],incrementStep:!1};case"rule-check":{if(L.push(""),L.push(`STEP ${I} ${O.h} Match rules`),L.push(` Rule: ${_.rule}()`),_.matched)L.push(" Result: MATCHED");else L.push(" Result: No match");return{lines:L,incrementStep:!0}}case"worktree-relaxation":return L.push(""),L.push(`STEP ${I} ${O.h} Worktree relaxation`),L.push(` Mode: ${o.worktree.name}`),L.push(` Git cwd: ${_.gitCwd}`),L.push(" Result: Allowed local discard in linked worktree"),{lines:L,incrementStep:!0};case"temp-root-relaxation":return L.push(""),L.push(`STEP ${I} ${O.h} Temp-root relaxation`),L.push(` Git cwd: ${_.gitCwd}`),L.push(" Result: Allowed git discard in a temp-root repository"),{lines:L,incrementStep:!0};case"tmpdir-check":return null;case"fallback-scan":{if(_.embeddedCommandFound)return L.push(""),L.push(`STEP ${I} ${O.h} Fallback scan`),L.push(` Found: ${_.embeddedCommandFound}`),{lines:L,incrementStep:!0};return null}case"custom-rules-check":{if(_.rulesChecked){if(L.push(""),L.push(`STEP ${I} ${O.h} Custom rules`),_.matched)L.push(" Result: MATCHED");else L.push(" Result: No match");return{lines:L,incrementStep:!0}}return null}case"cwd-change":return null;case"dangerous-text":{if(_.matched)return L.push(""),L.push(`STEP ${I} ${O.h} Dangerous text check`),L.push(` Token: ${_.token}`),L.push(" Result: MATCHED"),{lines:L,incrementStep:!0};return null}case"strict-unparseable":return L.push(""),L.push(`STEP ${I} ${O.h} Strict mode check`),L.push(` Command: ${_.rawCommand}`),L.push(" Result: ✗ UNPARSEABLE"),{lines:L,incrementStep:!0};case"segment-skipped":return null;case"error":return L.push(""),L.push(`ERROR: ${_.message}`),{lines:L,incrementStep:!1};default:return _}}function fi(_,I){let O=Dl(I?.asciiOnly??!1),L=58,J=[],K=1;J.push(...Ll(O,58)),J.push("");let ne=_.trace.steps.find((we)=>we.type==="error");if(ne&&ne.type==="error"){J.push("ERROR"),J.push(` ${ne.message}`),J.push(""),J.push("RESULT"),J.push(` Status: ${_.result==="blocked"?nn.red("BLOCKED"):nn.green("ALLOWED")}`),J.push(""),J.push("CONFIG");let we=_.configSource??"none";return J.push(` Path: ${we}`),J.join(`
221
+ `)}let oe=_.trace.steps.find((we)=>we.type==="parse");if(oe&&oe.type==="parse"){J.push("INPUT"),J.push(` ${oe.input}`),J.push(""),J.push(`STEP ${K} ${O.h} Split shell commands`),K++;for(let we=0;we<oe.segments.length;we++){let Le=oe.segments[we];if(Le){let en=Math.random();J.push(` Segment ${we+1}: ${Nl(Le,en)}`)}}}let de=_.trace.segments,ue=de.length>1;for(let we of de){if(ue){J.push("");let on="";if(oe&&oe.type==="parse"){let lo=oe.segments[we.index];if(lo)on=lo.join(" ")}let sn=54,an=on,rn=` Segment ${we.index+1}: `,un=" ";if(on){if(rn.length+on.length+un.length>sn){let bu=sn-rn.length-un.length;an=`${on.substring(0,bu-1)}…`}}let xn=on?`${rn}${an}${un}`:` Segment ${we.index+1} `,yu=on?`${rn}${nn.cyan(an)}${un}`:xn,Yi=58-xn.length,Zi=Math.floor(Yi/2),vu=Yi-Zi;J.push(`${O.sh.repeat(Zi)}${yu}${O.sh.repeat(vu)}`)}if(we.steps.find((on)=>on.type==="segment-skipped")){J.push(""),J.push(" (skipped — prior segment blocked)");continue}let en=!1,Ve=!1;for(let on of we.steps){let sn=jl(on,K,O);if(sn){if(Ve=!0,on.type==="recurse"){J.push("");let an=" RECURSING ",rn=58-an.length-4;J.push(` ${O.tl}${O.h}${an}${O.h.repeat(rn)}`),J.push(` ${O.v}`),en=!0;continue}for(let an of sn.lines)if(en)J.push(` ${O.v} ${an}`);else J.push(an);if(sn.incrementStep)K++}}if(en)J.push(` ${O.v}`),J.push(` ${O.bl}${O.h.repeat(56)}`);if(!Ve)J.push(""),J.push(` ${nn.green("✓")} Allowed (no matching rules)`)}if(J.push(""),J.push("RESULT"),_.result==="blocked"){if(J.push(` Status: ${nn.red("BLOCKED")}`),_.customRule){if(J.push(` Rule: ${_.customRule.id}`),_.customRule.rulebook)J.push(` Rulebook: ${_.customRule.rulebook.name} ${_.customRule.rulebook.version}`);if(_.customRule.source)J.push(` Source: ${_.customRule.source}`);if(_.customRule.override)J.push(` Override: reason ${_.customRule.override.reason}`)}if(_.reason){let we=Vt(_.reason," ");J.push(` Reason: ${we[0]}`);for(let Le=1;Le<we.length;Le++)J.push(we[Le]??"")}}else J.push(` Status: ${nn.green("ALLOWED")}`);J.push(""),J.push("CONFIG");let ve=_.configSource??"none",xe=_.configValid?"":" (invalid)";J.push(` Path: ${ve}${xe}`);let Se=_.safetyPresetScope;J.push(` Safety preset: ${_.selectedPreset??"standard"}${Se?` (${pr(Se)})`:""}`),J.push(` Effective capabilities: ${_.effectiveLevel}`);let Pe=Object.entries(_.destructiveCommandRuleOverrides??{});if(J.push(` Rule customizations: ${Pe.length}`),_.ruleActivation)J.push(` Rule activation: ${_.ruleActivation.id} — ${_.ruleActivation.enabled?"on":"off"} via ${_.ruleActivation.source}`);return J.join(`
222
+ `)}function mi(_){return JSON.stringify(_,null,2)}import{resolve as Cg}from"node:path";var wg=["AKIA","ASIA","ghp_","gho_","ghu_","ghs_","ghr_","github_pat_","glpat-","xox","npm_","pypi-","rk_","sk-","sk_","gsk_","xai-","pplx-","bastn_","tgp_v1_","flp_","wfr_","fw_","fwp_","tp-","psk-"];function Fl(_){let I=0,O={allocateSegment(){return I++},getNextSegmentIndex(){return I},recordGlobal(L){_.record({kind:"step",scope:"global",step:L})},recordSegment(L,J=O.currentSegmentIndex){if(J===void 0)return;_.record({kind:"step",scope:"segment",segmentIndex:J,step:L})}};return O}function Hl(_={}){let I=[],O=_.maxEvents??512,L={maxTextLength:_.maxTextLength??2048,maxListLength:_.maxListLength??128,maxObjectProperties:_.maxObjectProperties??_.maxListLength??128,maxDepth:_.maxDepth??16},J,K=new Set;return{record(ne){if(J)return;if(!ne||I.length>=O)return;try{I.push(yi(kg(ne,L,K)))}catch{}},finish(){if(J)return J;return J=yi({events:Object.freeze(I)}),J}}}function kg(_,I,O){if(_.kind!=="step")throw TypeError("invalid trace event");let{scope:L,step:J}=_;Fr(J,O,I);let K=gi(J,I,O);if(L==="global")return{kind:"step",scope:"global",step:K};if(L!=="segment")throw TypeError("invalid trace event scope");return{kind:"step",scope:"segment",segmentIndex:_.segmentIndex,step:K}}function Fr(_,I,O,L=0,J=new WeakSet){if(typeof _==="string"){let oe=_.slice(0,O.maxTextLength);if(!Be(oe))return;for(let de of tt(oe))for(let ue of de.match(/[^\s"'()$]+/g)??[])I.add(Ml(ue));return}if(!_||typeof _!=="object"||L>=O.maxDepth||J.has(_))return;if(J.add(_),Array.isArray(_)){let oe=Math.min(_.length,O.maxListLength);for(let de=0;de<oe;de++)Fr(_[de],I,O,L+1,J);return}let K=0,ne=new Set;for(let oe in _){if(!Object.hasOwn(_,oe))continue;if(K>=O.maxObjectProperties)break;K++,Fr(oe,I,O);let de=hi(oe,O,I);if(ne.has(de))continue;ne.add(de),Fr(_[oe],I,O,L+1,J)}}function gi(_,I,O,L=0,J=new WeakSet){if(typeof _==="string")return hi(_,I,O);if(!_||typeof _!=="object")return _;if(L>=I.maxDepth)return;if(J.has(_))return;if(J.add(_),Array.isArray(_)){let oe=[],de=Math.min(_.length,I.maxListLength);for(let ue=0;ue<de;ue++)oe.push(gi(_[ue],I,O,L+1,J));return oe}let K={},ne=0;for(let oe in _){if(!Object.hasOwn(_,oe))continue;if(ne>=I.maxObjectProperties)break;ne++;let de=hi(oe,I,O);if(Object.hasOwn(K,de))continue;Object.defineProperty(K,de,{value:gi(_[oe],I,O,L+1,J),enumerable:!0,configurable:!0,writable:!0})}return K}function hi(_,I,O){let L=_.slice(0,I.maxTextLength),J=Be(L)?We(L):L,K=O.size>0?Sg(J,O):J;return(xg(K)?_e(K):K).slice(0,I.maxTextLength)}function xg(_){return _.includes("PRIVATE KEY")||_.includes("://")||_.includes("eyJ")||_.includes(":")&&/(?:authorization|cookie|x-api-key|api-key|(?:^|\s)(?:-u|--user)(?:\s|=))/i.test(_)||_.length>=14&&wg.some((I)=>_.includes(I))||_.length>=49&&/\b[a-f0-9]{32}\.[A-Za-z0-9]{16}\b/.test(_)}function Sg(_,I){return _.replace(/[^\s"'()$]+/g,(O)=>I.has(Ml(O))?"<redacted>":O)}function Ml(_){let I=2166136261,O=2166136261;for(let L=0;L<_.length;L++)I=Math.imul(I^_.charCodeAt(L),16777619),O=Math.imul(O^_.charCodeAt(_.length-L-1),16777619);return`${I>>>0}:${O>>>0}:${_.length}`}function yi(_){if(_&&typeof _==="object"&&!Object.isFrozen(_)){for(let I of Object.values(_))yi(I);Object.freeze(_)}return _}function zt(_,I={},O){let L=Cg(I.cwd??process.cwd()),J=I.policySnapshot??E(O,{cwd:L,userConfigDir:I.userConfigDir}),K=R(J.policy,O.env),ne=je({policySnapshot:J,effectiveCapabilities:K.capabilities,strict:K.strict,paranoidRm:K.paranoidRm,paranoidInterpreters:K.paranoidInterpreters,worktreeMode:K.worktreeMode}),oe={effectiveLevel:ne.effectiveLevel,selectedPreset:J.policy.safety.level??"standard",...J.policyScopes?{safetyPresetScope:J.policyScopes.levelScope}:{},effectiveCapabilities:ne.effectiveCapabilities,destructiveCommandRuleOverrides:J.policy.destructiveCommandRuleOverrides},{configSource:de,configValid:ue}=Pg(O,{cwd:L,userConfigDir:I.userConfigDir});if(!_||!_.trim())return{trace:{steps:[{type:"error",message:"No command provided"}],segments:[]},result:"allowed",configSource:de,configValid:ue,...oe};let ve=h(_,"auto");if(ve.status==="limited")throw new y;let xe=ve.dialect==="powershell"?h(_,"posix"):ve,Se=ut(xe),Pe=Hl(),we=Fl(Pe);we.recordGlobal({type:"parse",input:_,segments:Se.map((xn)=>[...xn])});let Le=l("Bash",{command:_},{kind:"command",shell:"auto"},{configCwd:L,executionCwd:L},_),en=V(Le,{environment:O,trace:we,dependencies:{loadPolicySnapshot:()=>J}}),Ve=en.decision.kind==="deny"?en.decision:null;if(Ve&&(en.stage==="policy-protection"||en.stage==="secret-protection")){let xn=Rg(Ve);return{trace:{steps:[],segments:[{index:0,steps:[{type:"rule-check",rule:xn.rule,matched:!0,reason:Ve.reason}]}]},result:"blocked",reason:k(Ve.reason),segment:k(Ul(Ve,_)),...xn.ruleId?{ruleId:k(xn.ruleId)}:{},configSource:de,configValid:ue,...oe}}let on=we.getNextSegmentIndex();if(Ve&&on>0&&on<Se.length)we.recordSegment({type:"segment-skipped",index:on,reason:"prior-segment-blocked"},on);let sn=Pe.finish(),an=Ve?.ruleId??Eg(Le,J,K,O),rn=W.find((xn)=>xn.id===an&&xn.activationCapability),un=rn?ne.policy.effectiveDestructiveCommandRules[rn.id]:void 0;return{trace:_g(sn),result:Ve?"blocked":"allowed",reason:Ve?k(Ve.reason):void 0,segment:Ve?k(Ul(Ve,_)):void 0,ruleId:Ve?.ruleId?k(Ve.ruleId):void 0,customRule:Ag(Ig(Ve?.ruleId,J)),configSource:de,configValid:ue,...oe,...rn&&un?{ruleActivation:{id:rn.id,...un}}:{}}}function Ul(_,I){return _.evidence?.segment??I}function Rg(_){if(_.reason===Ge)return{ruleId:"policy-protection",rule:"policy-protection:findPolicyConfigMutationTargetInSemanticFacts"};if(_.reason===Ue)return{ruleId:"policy-apply-protection",rule:"policy-apply-protection:findPolicyApplyInvocationInSemanticFacts"};if(_.reason===x)return{ruleId:"git-metadata-protection",rule:"git-metadata-protection:findGitMetadataMutationTargetInSemanticFacts"};return{ruleId:_.ruleId,rule:"secret-protection:findSensitiveTargetInSemanticFacts"}}function Pg(_,I){let O=U(I.cwd),L=G(_,I),J=Z(_,{cwd:I.cwd,userConfigDir:I.userConfigDir});try{if(n(J.projectConfigTarget)!==null){if(Un(J.projectConfigTarget).errors.length===0)return{configSource:O,configValid:!0};return{configSource:O,configValid:!1}}}catch(K){if(K instanceof r)return{configSource:O,configValid:!1};throw K}try{if(n(J.userConfigTarget)!==null){let K=Un(J.userConfigTarget);return{configSource:L,configValid:K.errors.length===0}}return{configSource:null,configValid:!0}}catch(K){if(K instanceof r)return{configSource:L,configValid:!1};throw K}}function Eg(_,I,O,L){let J=I.policy,K=Te({...J,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:{...J.destructiveCommandRuleOverrides,...Object.fromEntries(W.flatMap((oe)=>oe.activationCapability?[[oe.id,"on"]]:[]))}},I.state==="degraded"?{diagnostics:I.diagnostics,reason:I.reason}:void 0),ne=V(_,{environment:L,dependencies:{loadPolicySnapshot:()=>K,getModes:()=>({...O,strict:!0,paranoidRm:!0,paranoidInterpreters:!0}),findSensitiveTarget:()=>null}});return ne.decision.kind==="deny"?ne.decision.ruleId:void 0}function Ag(_){if(!_)return;return{id:k(_.id),..._.rulebook?{rulebook:{name:k(_.rulebook.name),version:k(_.rulebook.version)}}:{},..._.source?{source:k(_.source)}:{},..._.override?{override:{type:"reason",reason:k(_.override.reason)}}:{}}}function _g(_){let I=_.events.flatMap((L)=>L.kind==="step"&&L.scope==="global"?[L.step]:[]),O=new Map;for(let L of _.events){if(L.kind!=="step"||L.scope!=="segment")continue;let J=O.get(L.segmentIndex)??{index:L.segmentIndex,steps:[]};J.steps.push(L.step),O.set(L.segmentIndex,J)}return{steps:I,segments:[...O.values()]}}function Ig(_,I){let O=_?.replace(/^custom\./,"");if(!O||!I.policy.rules.some((L)=>L.name===O))return;return I.ruleMetadata[O]??Object.freeze({id:O})}function Gl(_){return new Promise((I)=>{process.stdout.write(`${_}
223
+ `,()=>I())})}async function Bl(_,I){let O=ui(I);if(!O)return 1;try{let L=zt(O.command,{cwd:O.cwd},_),J=!!process.env.NO_COLOR||!process.stdout.isTTY;return await Gl(O.json?mi(L):fi(L,{asciiOnly:J})),0}catch(L){let J=Tg(L instanceof p?L.cause:L);if(J===void 0)throw L;if(O.json)return await Gl(JSON.stringify({error:J})),1;return console.error(J),1}}function Tg(_){if(_ instanceof y)return _.message;if(_ instanceof f)return _.message;if(_ instanceof s&&a[_.kind].errorCode==="path-canonicalization-limit")return"Path canonicalization work limit exceeded.";return}var ql="2.5.0",An=" ",Qn="cc-safety-net";function Vl(_){return _.argument?`${_.flags} ${_.argument}`:_.flags}function $g(_){return Math.max(..._.map((I)=>Vl(I).length))}function Og(_){return Math.max(..._.map((I)=>I.usage.length))}function Dg(_){return Math.max(..._.map((I)=>`${Qn} ${I.usage}`.length))}function Lg(_,I){let O=`${Qn} ${_.usage}`;return`${An}${O.padEnd(I+2)}${_.description}`}function jn(_,I){return`${An}${_.padEnd(Math.max(40,_.length+2))}${I}`}function Pt(_,I=console.log){let O=[];if(O.push(`${Qn} ${_.name}`),O.push(""),O.push(`${An}${_.description}`),O.push(""),O.push("USAGE:"),O.push(`${An}${Qn} ${_.usage}`),O.push(""),_.subcommands&&_.subcommands.length>0){O.push("SUBCOMMANDS:");let L=Og(_.subcommands);for(let J of _.subcommands)O.push(`${An}${J.usage.padEnd(L+2)}${J.description}`);O.push("")}if(_.options.length>0){O.push("OPTIONS:");let L=$g(_.options);for(let J of _.options){let K=Vl(J),ne=J.default?`${J.description} (default: ${J.default})`:J.description;O.push(`${An}${K.padEnd(L+2)}${ne}`)}O.push("")}if(_.examples&&_.examples.length>0){O.push("EXAMPLES:");for(let L of _.examples)O.push(`${An}${L}`)}I(O.join(`
224
+ `))}function vi(){let _=Dg(lr),I=[];I.push(`${Qn} v${ql}`),I.push(""),I.push("Blocks destructive commands and secret access."),I.push(""),I.push("COMMANDS:");for(let O of lr)I.push(Lg(O,_));I.push(""),I.push("GLOBAL OPTIONS:"),I.push(`${An}-h, --help Show help (use with command for command-specific help)`),I.push(`${An}-V, --version Show version`),I.push(""),I.push("HELP:"),I.push(`${An}${Qn} help <command> Show help for a specific command`),I.push(`${An}${Qn} <command> --help Show help for a specific command`),I.push(""),I.push("ENVIRONMENT VARIABLES:"),I.push(jn(`${o.level.name}=standard|strict|paranoid`,"Set session safety level")),I.push(jn(`${o.worktree.name}=1`,"Allow local git discards in linked worktrees")),I.push(jn(`${o.debug.name}=1`,"Print diagnostic messages to stderr")),I.push(jn(`${o.auditScope.name}=all|blocked`,"Record all command decisions, or denials only")),I.push(jn("CC_SAFETY_NET_HOME","Override rule config home directory")),I.push(""),I.push("LEGACY ENVIRONMENT VARIABLES (STILL SUPPORTED):"),I.push(jn(`${o.strict.name}=1`,"Force safety.overrides.fail_closed on")),I.push(jn(`${o.paranoid.name}=1`,"Force paranoid_rm and paranoid_interpreters on")),I.push(jn(`${o.paranoidRm.name}=1`,"Force safety.overrides.paranoid_rm on")),I.push(jn(`${o.paranoidInterpreters.name}=1`,"Force safety.overrides.paranoid_interpreters on")),I.push(""),I.push("Documentation: https://ccsafetynet.com/docs"),console.log(I.join(`
225
+ `))}function zl(){console.log(ql)}function Jt(_,I=console.log){let O=cr(_);if(!O)return!1;if(O.name.toLowerCase()!==_.toLowerCase())return!1;return Pt(O,I),!0}import{existsSync as zr,readFileSync as Xc}from"node:fs";import{join as Vr}from"node:path";import*as qn from"node:readline";function Ng(_){return _==="install"?"Install":"Uninstall"}function jg(_){return _==="install"?"Installing":"Uninstalling"}function Fg(_){return _==="install"?"into":"from"}function Kl(_){return _?.available===!0}function Hg(_,I){let O=new Set(I);return _.filter((L)=>O.has(L.target)).map((L)=>L.target)}function Jl(_,I,O){if(_.every((L)=>!L.available))return I;return Array.from({length:_.length},(L,J)=>J+1).map((L)=>(I+L*O+_.length)%_.length).find((L)=>Kl(_[L]))}function Mg(_,I,O){if(O.ctrl&&O.name==="c")return"interrupt";if(O.name==="escape"||I==="q")return"abort";if(_==="install"&&(I==="u"||I==="U"))return"update";if(O.name==="up"||I==="k")return"up";if(O.name==="down"||I==="j")return"down";if(O.name==="space"||I===" ")return"toggle";if(O.name==="return"||O.name==="enter")return"confirm";return null}function Ug(_){return{cursor:_.findIndex((I)=>I.available),selected:[]}}function Gg(_,I,O){if(O==="confirm"||O==="update"||O==="abort"||O==="interrupt")return{state:_,done:O};if(O==="up")return{state:{..._,cursor:Jl(I,_.cursor,-1)}};if(O==="down")return{state:{..._,cursor:Jl(I,_.cursor,1)}};let L=I[_.cursor];if(!Kl(L))return{state:_};let J=_.selected.includes(L.target)?_.selected.filter((K)=>K!==L.target):Hg(I,[..._.selected,L.target]);return{state:{..._,selected:J}}}var Yl="◉",Zl="◯",Xl=">",Ql=" ";function Bg(_,I,O,L={}){let J=L.color!==!1,K=J?nn.dim:(de)=>de,ne=J?nn.green:(de)=>de,oe=J?nn.bold:(de)=>de;return["",`${Ng(_)} CC Safety Net ${Fg(_)}:`,"",...I.map((de,ue)=>{let ve=O.selected.includes(de.target),xe=ue===O.cursor,Se=ve?Yl:Zl,Pe=xe?Xl:Ql,we=de.available?"":` (${de.unavailableReason??"not installed"})`,Le=`${Se} ${de.label}${we}`,en=!de.available?K(Le):ve?ne(Le):xe?oe(Le):Le;return`${Pe} ${en}`}),"",_==="install"?"Space: select Enter: confirm u: update installed Up/Down: move q/Esc: cancel":I.some((de)=>de.available)?"Space: select Enter: confirm Up/Down: move q/Esc: cancel":`No selectable integrations found for ${_}. q/Esc: close`].join(`
226
+ `)}var Wl=["global-hook","plugin"];function qg(_,I,O={}){let L=O.color!==!1?nn.bold:(K)=>K;return["","Install the Kimi Code integration as:","",...[`Global hook — ${I?"already installed; selecting it reports the current state":"write the hook into ~/.kimi-code/config.toml now"}`,"Native Kimi plugin — print the steps to run inside Kimi Code"].map((K,ne)=>{let oe=ne===_,de=`${oe?Yl:Zl} ${K}`;return`${oe?Xl:Ql} ${oe?L(de):de}`}),"","Enter: confirm Up/Down: move q/Esc: cancel"].join(`
227
+ `)}function ec(_){let{input:I,output:O}=_;qn.emitKeypressEvents(I);let L=I.isRaw===!0;I.setRawMode(!0),I.resume();let J=0,K=()=>{if(J===0)return;qn.moveCursor(O,0,-J),qn.cursorTo(O,0),qn.clearScreenDown(O)},ne=()=>{K();let oe=_.render();O.write(`${oe}
228
+ `),J=oe.split(`
229
+ `).length};return new Promise((oe)=>{let de=(ve)=>{I.off("keypress",ue),I.setRawMode(L),I.pause(),K(),oe(ve)};function ue(ve,xe){_.onKey(ve,xe,{finish:de,draw:ne})}I.on("keypress",ue),ne()})}function nc(_={}){let I=0;return ec({input:_.input??process.stdin,output:_.output??process.stdout,render:()=>qg(I,_.globalHookInstalled===!0),onKey:(O,L,J)=>{if(L.ctrl&&L.name==="c"){J.finish(null),(_.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(L.name==="escape"||O==="q")return J.finish(null);if(L.name==="return"||L.name==="enter")return J.finish(Wl[I]);if(L.name==="up"||L.name==="down"||O==="k"||O==="j")I=(I+1)%Wl.length,J.draw()}})}function bi(_=process.stdin,I=process.stdout){return Boolean(_.isTTY&&I.isTTY&&typeof _.setRawMode==="function")}function tc(_,I,O={}){let L=O.output??process.stdout,J=Ug(I);return ec({input:O.input??process.stdin,output:L,render:()=>Bg(_,I,J),onKey:(K,ne,oe)=>{let de=Mg(_,K,ne);if(!de)return;let ue=Gg(J,I,de);if(J=ue.state,ue.done==="interrupt"){oe.finish(null),(O.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(ue.done==="abort")return oe.finish(null);if(ue.done==="update")return oe.finish("update");if(ue.done==="confirm"){if(J.selected.length===0){L.write("\x07"),oe.draw();return}oe.finish([...J.selected]),L.write(`${jg(_)} selected integrations...
230
+ `);return}oe.draw()}})}import{existsSync as rc,lstatSync as zg,mkdirSync as Jg,mkdtempSync as Wg,readdirSync as Kg,readFileSync as At,rmSync as Mr}from"node:fs";import{basename as Yg,dirname as Zg,join as kn}from"node:path";import{fileURLToPath as Xg}from"node:url";var wi="// cc-safety-net managed Amp plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --amp",nt="cc-safety-net",ot="cc-safety-net/index.ts";import{spawn as Vg}from"node:child_process";var ki=(_,I)=>{let O=Wn([..._],process.env);return new Promise((L)=>{let J=Vg(O.cmd,O.args,{cwd:I,stdio:["ignore","pipe","pipe"]}),K=Ko(J),ne=!1,oe=setTimeout(()=>{ne=!0,J.kill()},120000);J.on("error",(de)=>{clearTimeout(oe),L({status:null,errorCode:de.code,stdout:K.stdout,stderr:[de.message,K.stderr].filter(Boolean).join(`
231
+ `)})}),J.on("close",(de)=>{clearTimeout(oe),L({status:ne?null:de,errorCode:ne?"ETIMEDOUT":void 0,stdout:K.stdout,stderr:K.stderr})})})};var Et="cc-safety-net.ts",xi=kn("amp",ot);function Qg(_){return kn(_.home,".config","amp","plugins","cc-safety-net.ts")}function eh(){let _=Zg(Xg(import.meta.url)),I=kn(_,xi),O=kn(_,"..",xi),L=kn(_,"..","..","..","dist",xi);return[I,O,L]}function nh(_=eh()){let I=_.find((O)=>rc(O)&&zg(O).isFile());if(!I)throw Error("Packaged Amp plugin artifact not found. Reinstall cc-safety-net and try again.");return I}function oc(_){try{return JSON.parse(_)}catch{return}}function Ur(_){return _.subarray(0,Buffer.byteLength(wi)).toString("utf-8")===wi}async function Wt(_,I,O){let L=await _(I,O);if(L.status===0)return L;throw Error([`Failed to run ${I.join(" ")}${L.status===null?"":` (exit ${L.status})`}.`,[L.stdout,L.stderr].filter(Boolean).join(`
232
232
  `).trim()].filter(Boolean).join(`
233
- `))}async function Jl(P){let A=await P(["amp","plugins","repositories","--json"]);if(A.status===null)throw Error(`${A.errorCode==="ENOENT"?'Amp CLI not found. Install the amp CLI, sign in with "amp login", and rerun install --amp.':`amp plugins repositories --json did not finish (${A.errorCode??"terminated"}). Check that the amp CLI responds and rerun install --amp.`}
234
- ${A.stderr}`.trim());if(A.status!==0)throw Error(`Failed to run amp plugins repositories --json (exit ${A.status}). Sign in with "amp login" and rerun install --amp.
235
- ${[A.stdout,A.stderr].filter(Boolean).join(`
236
- `)}`.trim());let q=zl(A.stdout),V=(Array.isArray(q)?q:[]).filter((ee)=>pt(ee,"scope")==="user"&&pt(ee,"exists")===!0&&pt(ee,"viewerCanWrite")===!0).map((ee)=>pt(ee,"cloneRef")).find((ee)=>typeof ee==="string"&&ee.length>0);if(!V)throw Error('Your Amp account has no writable Personal Plugins repository. Sign in with "amp login", open Amp once to create it, and rerun install --amp.');return V}async function Wl(P,A,q){let V=Cm(Dt(A.tmpdir,"cc-safety-net-amp-"));try{return await zn(P,["amp","clone","user-plugins",V]),await q(V)}finally{Nr(V,{recursive:!0,force:!0})}}function gi(P){return`rerun ${P==="overwrite"?"install":"uninstall"} --amp`}function Kl(P,A,q){let V=Dt(P,A),ee=Lt(V);if(!ee)return;if(ee.isSymbolicLink()||!ee.isFile())throw Error(`Refusing to ${q} ${A} in your Amp personal plugins repository: not a regular file. Remove it there and ${gi(q)}.`);let ne=Rn(V);if(jr(ne))return ne;throw Error(`Refusing to ${q} unmanaged file ${A} in your Amp personal plugins repository. Remove it there and ${gi(q)}.`)}function Yl(P,A){let q=Dt(P,an),V=Lt(q);if(!V)return;if(V.isSymbolicLink()||!V.isDirectory())throw Error(`Refusing to ${A} ${an} in your Amp personal plugins repository: not a regular directory. Remove it there and ${gi(A)}.`);return Kl(P,ln,A)}function Tm(P){let A=Dt(P,Sn),q=Lt(A);if(!q||q.isSymbolicLink()||!q.isFile())return;let V=Rn(A);return jr(V)?V:void 0}async function Xl(P,A,q,V){if(await zn(P,q,A),(await zn(P,["git","status","--porcelain"],A)).stdout.trim()==="")return!1;return await zn(P,["git","-c","commit.gpgsign=false","-c","user.name=cc-safety-net","-c","user.email=cc-safety-net@localhost","commit","-m",V],A),await zn(P,["git","push","origin","HEAD"],A),!0}function Fr(P,A){Im(P,A),$m(P,A)}function Zl(P,A){if(A==="keep")return;throw Error(`Local Amp plugin ${P} is not a managed copy and masks the personal plugin. Remove it and rerun install --amp.`)}function Im(P,A){let q=Dm(P),V=Lt(q);if(!V)return;if(!V.isSymbolicLink()&&V.isFile()&&jr(Rn(q))){Nr(q);return}Zl(q,A)}function $m(P,A){let q=Dt(P.home,".config","amp","plugins",an),V=Lt(q);if(!V)return;if(!V.isSymbolicLink()&&V.isDirectory()&&Om(q)){Nr(q,{recursive:!0});return}Zl(q,A)}function Om(P){let A=Rm(ln);if(Sm(P).join("\x00")!==A)return!1;let q=Dt(P,A),V=Lt(q);return!!V&&!V.isSymbolicLink()&&V.isFile()&&jr(Rn(q))}function Fm(P){let A=u(P);if(!Vl(A))return"";let q=zl(Rn(A,"utf-8"));if(!q||typeof q!=="object"||Array.isArray(q))return"";return`;globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__ = ${JSON.stringify(C(q,P.home))};
237
- `}async function Ql(P,A=_m(),q=fi){let V=Buffer.concat([Rn(A),Buffer.from(Fm(P),"utf-8")]),ee=await Jl(q);return Wl(q,P,async(ne)=>{let ce=`${ee}/${an}`,he=Yl(ne,"overwrite"),ye=Kl(ne,Sn,"overwrite");if(he?.equals(V)&&!ye)return Fr(P,"fail"),{path:ce,alreadyInstalled:!0};if(xm(Dt(ne,an),{recursive:!0}),kt(Dt(ne,ln),V),ye)Nr(Dt(ne,Sn));let be=await Xl(q,ne,["git","add","--",ln,...ye?[Sn]:[]],`chore: update cc-safety-net plugin to v${wt()}`);return Fr(P,"fail"),{path:ce,alreadyInstalled:!be}})}async function ec(P,A=fi){let q=await Jl(A);return Wl(A,P,async(V)=>{let ee=Yl(V,"remove"),ne=Tm(V),ce=`${q}/${ne&&!ee?Sn:an}`;if(!ee&&!ne)return Fr(P,"keep"),{path:ce,alreadyInstalled:!1};return await Xl(A,V,["git","rm","--",...ee?[ln]:[],...ne?[Sn]:[]],`chore: remove cc-safety-net plugin v${wt()}`),Fr(P,"keep"),{path:ce,alreadyInstalled:!0}})}import{existsSync as tc,mkdirSync as Nm,readFileSync as jm}from"node:fs";import{dirname as Mm}from"node:path";var hi=jt["antigravity-cli"],cn="cc-safety-net";function dn(P){return Boolean(P)&&typeof P==="object"&&!Array.isArray(P)}function Hr(){return{PreToolUse:[{hooks:[{type:"command",command:hi,timeout:30}]}]}}function nc(P){try{let A=JSON.parse(jm(P,"utf-8"));if(!A||typeof A!=="object"||Array.isArray(A))throw Error("Antigravity hooks config must be a JSON object");return A}catch(A){if(A instanceof SyntaxError)throw Error(`Failed to parse Antigravity hooks config ${P}: ${A.message}`);throw A}}function rc(P){let A=P[cn];if(A===void 0){let V=Hr();return P[cn]=V,{definition:V,preToolUse:V.PreToolUse??[]}}if(!dn(A))throw Error(`Antigravity hooks config entry "${cn}" must be an object`);let q=Array.isArray(A.PreToolUse)?A.PreToolUse:[];return A.PreToolUse=q,{definition:A,preToolUse:q}}function oc(P){if(!Array.isArray(P.PreToolUse))return!1;return P.PreToolUse.some((A)=>dn(A)&&Array.isArray(A.hooks)&&A.hooks.some((q)=>dn(q)&&q.command===hi))}function Hm(P){return Object.values(P).some((A)=>dn(A)&&A.enabled!==!1&&oc(A))}function Um(P){if(P[cn]===void 0)return!1;let A=rc(P);if(A.definition.enabled!==!1||!oc(A.definition))return!1;return A.definition.enabled=!0,!0}function Gm(P){if(P[cn]===void 0){P[cn]=Hr();return}let A=rc(P);A.definition.enabled=!0,A.preToolUse.push(Hr().PreToolUse?.[0]??{hooks:[]})}function Bm(P){let A=!1;for(let q of Object.values(P)){if(!dn(q)||!Array.isArray(q.PreToolUse))continue;q.PreToolUse=q.PreToolUse.flatMap((V)=>{if(!dn(V)||!Array.isArray(V.hooks))return[V];let ee=V.hooks.filter((ne)=>!dn(ne)||ne.command!==hi);if(ee.length!==V.hooks.length)A=!0;return ee.length===0?[]:[{...V,hooks:ee}]})}return A}function Mr(P,A){kt(P,`${JSON.stringify(A,null,2)}
238
- `)}function ic(P){let A=_n(P.home);if(Nm(Mm(A),{recursive:!0}),!tc(A))return Mr(A,{[cn]:Hr()}),{path:A,alreadyInstalled:!1};let q=nc(A);if(Hm(q))return{path:A,alreadyInstalled:!0};if(Um(q))return Mr(A,q),{path:A,alreadyInstalled:!1};return Gm(q),Mr(A,q),{path:A,alreadyInstalled:!1}}function sc(P){let A=_n(P.home);if(!tc(A))return{path:A,alreadyInstalled:!1};let q=nc(A);if(!Bm(q))return{path:A,alreadyInstalled:!1};return Mr(A,q),{path:A,alreadyInstalled:!0}}import{existsSync as qm,readdirSync as Vm,rmSync as zm}from"node:fs";import{join as Jm}from"node:path";function ac(P,A=process.platform,q){if(!qm(P))return;let V=A==="win32"?/^bunx-\d+-cc-safety-net@/:new RegExp(`^bunx-${process.getuid?.()??0}-cc-safety-net@`);Vm(P).filter((ee)=>ee!==q&&V.test(ee)).forEach((ee)=>{zm(Jm(P,ee),{recursive:!0,force:!0})})}import{spawn as Wm}from"node:child_process";var Ht=$t.map((P)=>({target:P.id,flag:P.flag,label:bt(P.id),probeCommand:P.probeCommand}));function yi(P){let A=new Set(P);return Ht.map((q)=>q.target).filter((q)=>A.has(q))}async function lc(P,A){for(let q of P)await A(q)}var Km=5000;function vi(P,A=Km){return new Promise((q)=>{let V=Qt([...P],process.env),ee=Wm(V.cmd,V.args,{env:process.env,stdio:"ignore"}),ne=!1,ce=(ye)=>{if(ne)return;ne=!0,clearTimeout(he),q(ye)},he=setTimeout(()=>{ee.kill(),ce(!1)},A);ee.on("error",()=>ce(!1)),ee.on("close",(ye)=>ce(ye===0))})}function cc(P=vi,A={}){let q=new Set(A.configuredTargets??[]);return Promise.all(Ht.map(async(V)=>({target:V.target,flag:V.flag,label:V.label,...uc(A.action,await P(V.probeCommand),q.has(V.target))})))}function dc(P,A){let q=new Set(A.configuredTargets??[]);return P.map((V)=>({...V,...uc(A.action,V.available,q.has(V.target))}))}function uc(P,A,q){if(P==="uninstall")return q?{available:!0}:{available:!1,unavailableReason:"not installed"};if(P==="install"&&q)return{available:!1,unavailableReason:"already installed"};if(!A)return{available:!1,unavailableReason:"CLI not installed"};return{available:!0}}import{existsSync as pc,readdirSync as Ym,rmSync as Xm}from"node:fs";import{join as Pn}from"node:path";function Ur(P,A=process.platform){let q=Pn(P.env.get("npm_config_cache")||(A==="win32"?Pn(P.env.get("LOCALAPPDATA")||Pn(P.home,"AppData","Local"),"npm-cache"):Pn(P.home,".npm")),"_npx");if(!pc(q))return;Ym(q).filter((V)=>pc(Pn(q,V,"node_modules","cc-safety-net"))).forEach((V)=>{Xm(Pn(q,V),{recursive:!0,force:!0})})}import{existsSync as vc,mkdirSync as Qm,readFileSync as bc}from"node:fs";import{dirname as eg,join as yc}from"node:path";function Zm(P,A){if(P[A]!=="#")return A;let q=P.indexOf(`
239
- `,A+1);return q===-1?P.length:q+1}function bi(P,A,q){let V=new RegExp(`^(\\s*)${A}\\s*=\\s*\\[`),ee=0;for(let ne of P.split(`
240
- `)){if(/^\s*\[/.test(ne))return;let ce=V.exec(ne);if(ce){let he=ee+ce[0].lastIndexOf("[");return{start:he,end:So(P,he,{skipComment:Zm,...q})}}ee+=ne.length+1}return}function fc(P,A,q){let V=P.slice(0,A.end).trimEnd(),ee=oa(P,A.end),ne=ee===""?" ":`${ee} `,ce=!V.endsWith("[")&&!V.endsWith(",");return`${V}${ce?",":""}
241
- ${ne}${q}${P.slice(A.end)}`}function mc(P,A,q){let V=P.indexOf(q,A.start);if(V===-1||V>A.end)return P;return Lr(P,{start:V,end:V+q.length})}function gc(P,A){let q=new RegExp(`^\\s*${A}\\s*=\\s*\\[\\s*]\\s*(?:#.*)?$`),V=P.split(`
242
- `),ee=V.findIndex((he)=>/^\s*\[/.test(he)),ne=ee===-1?V:V.slice(0,ee),ce=ee===-1?[]:V.slice(ee);return[...ne.filter((he)=>!q.test(he)),...ce].join(`
243
- `)}function hc(P,A,q){let V=new RegExp(`^\\s*\\[\\[${A}]]\\s*$`,"m");return P.split(/(?=^\s*\[)/m).filter((ee)=>!V.test(ee)||!ee.includes(q)).join("").trimEnd()}var Jn=jt["kimi-code"],Li=`[[hooks]]
233
+ `))}async function ic(_){let I=await _(["amp","plugins","repositories","--json"]);if(I.status===null)throw Error(`${I.errorCode==="ENOENT"?'Amp CLI not found. Install the amp CLI, sign in with "amp login", and rerun install --amp.':`amp plugins repositories --json did not finish (${I.errorCode??"terminated"}). Check that the amp CLI responds and rerun install --amp.`}
234
+ ${I.stderr}`.trim());if(I.status!==0)throw Error(`Failed to run amp plugins repositories --json (exit ${I.status}). Sign in with "amp login" and rerun install --amp.
235
+ ${[I.stdout,I.stderr].filter(Boolean).join(`
236
+ `)}`.trim());let O=oc(I.stdout),L=(Array.isArray(O)?O:[]).filter((J)=>tn(J,"scope")==="user"&&tn(J,"exists")===!0&&tn(J,"viewerCanWrite")===!0).map((J)=>tn(J,"cloneRef")).find((J)=>typeof J==="string"&&J.length>0);if(!L)throw Error('Your Amp account has no writable Personal Plugins repository. Sign in with "amp login", open Amp once to create it, and rerun install --amp.');return L}async function sc(_,I,O){let L=Wg(kn(I.tmpdir,"cc-safety-net-amp-"));try{return await Wt(_,["amp","clone","user-plugins",L]),await O(L)}finally{Mr(L,{recursive:!0,force:!0})}}function Si(_){return`rerun ${_==="overwrite"?"install":"uninstall"} --amp`}function ac(_,I,O){let L=kn(_,I),J=cn(L);if(!J)return;if(J.isSymbolicLink()||!J.isFile())throw Error(`Refusing to ${O} ${I} in your Amp personal plugins repository: not a regular file. Remove it there and ${Si(O)}.`);let K=At(L);if(Ur(K))return K;throw Error(`Refusing to ${O} unmanaged file ${I} in your Amp personal plugins repository. Remove it there and ${Si(O)}.`)}function lc(_,I){let O=kn(_,nt),L=cn(O);if(!L)return;if(L.isSymbolicLink()||!L.isDirectory())throw Error(`Refusing to ${I} ${nt} in your Amp personal plugins repository: not a regular directory. Remove it there and ${Si(I)}.`);return ac(_,ot,I)}function th(_){let I=kn(_,Et),O=cn(I);if(!O||O.isSymbolicLink()||!O.isFile())return;let L=At(I);return Ur(L)?L:void 0}async function cc(_,I,O,L){if(await Wt(_,O,I),(await Wt(_,["git","status","--porcelain"],I)).stdout.trim()==="")return!1;return await Wt(_,["git","-c","commit.gpgsign=false","-c","user.name=cc-safety-net","-c","user.email=cc-safety-net@localhost","commit","-m",L],I),await Wt(_,["git","push","origin","HEAD"],I),!0}function Hr(_,I){rh(_,I),oh(_,I)}function dc(_,I){if(I==="keep")return;throw Error(`Local Amp plugin ${_} is not a managed copy and masks the personal plugin. Remove it and rerun install --amp.`)}function rh(_,I){let O=Qg(_),L=cn(O);if(!L)return;if(!L.isSymbolicLink()&&L.isFile()&&Ur(At(O))){Mr(O);return}dc(O,I)}function oh(_,I){let O=kn(_.home,".config","amp","plugins",nt),L=cn(O);if(!L)return;if(!L.isSymbolicLink()&&L.isDirectory()&&ih(O)){Mr(O,{recursive:!0});return}dc(O,I)}function ih(_){let I=Yg(ot);if(Kg(_).join("\x00")!==I)return!1;let O=kn(_,I),L=cn(O);return!!L&&!L.isSymbolicLink()&&L.isFile()&&Ur(At(O))}function sh(_){let I=d(_);if(!rc(I))return"";let O=oc(At(I,"utf-8"));if(!O||typeof O!=="object"||Array.isArray(O))return"";return`;globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__ = ${JSON.stringify(C(O,_.home))};
237
+ `}async function uc(_,I=nh(),O=ki){let L=Buffer.concat([At(I),Buffer.from(sh(_),"utf-8")]),J=await ic(O);return sc(O,_,async(K)=>{let ne=`${J}/${nt}`,oe=lc(K,"overwrite"),de=ac(K,Et,"overwrite");if(oe?.equals(L)&&!de)return Hr(_,"fail"),{path:ne,alreadyInstalled:!0};if(Jg(kn(K,nt),{recursive:!0}),mn(kn(K,ot),L),de)Mr(kn(K,Et));let ue=await cc(O,K,["git","add","--",ot,...de?[Et]:[]],`chore: update cc-safety-net plugin to v${fn()}`);return Hr(_,"fail"),{path:ne,alreadyInstalled:!ue}})}async function pc(_,I=ki){let O=await ic(I);return sc(I,_,async(L)=>{let J=lc(L,"remove"),K=th(L),ne=`${O}/${K&&!J?Et:nt}`;if(!J&&!K)return Hr(_,"keep"),{path:ne,alreadyInstalled:!1};return await cc(I,L,["git","rm","--",...J?[ot]:[],...K?[Et]:[]],`chore: remove cc-safety-net plugin v${fn()}`),Hr(_,"keep"),{path:ne,alreadyInstalled:!0}})}import{existsSync as fc,mkdirSync as ah,readFileSync as lh}from"node:fs";import{dirname as ch}from"node:path";var Ci=In["antigravity-cli"],dt="cc-safety-net";function pt(_){return Boolean(_)&&typeof _==="object"&&!Array.isArray(_)}function Br(){return{PreToolUse:[{hooks:[{type:"command",command:Ci,timeout:30}]}]}}function mc(_){try{let I=JSON.parse(lh(_,"utf-8"));if(!I||typeof I!=="object"||Array.isArray(I))throw Error("Antigravity hooks config must be a JSON object");return I}catch(I){if(I instanceof SyntaxError)throw Error(`Failed to parse Antigravity hooks config ${_}: ${I.message}`);throw I}}function gc(_){let I=_[dt];if(I===void 0){let L=Br();return _[dt]=L,{definition:L,preToolUse:L.PreToolUse??[]}}if(!pt(I))throw Error(`Antigravity hooks config entry "${dt}" must be an object`);let O=Array.isArray(I.PreToolUse)?I.PreToolUse:[];return I.PreToolUse=O,{definition:I,preToolUse:O}}function hc(_){if(!Array.isArray(_.PreToolUse))return!1;return _.PreToolUse.some((I)=>pt(I)&&Array.isArray(I.hooks)&&I.hooks.some((O)=>pt(O)&&O.command===Ci))}function dh(_){return Object.values(_).some((I)=>pt(I)&&I.enabled!==!1&&hc(I))}function uh(_){if(_[dt]===void 0)return!1;let I=gc(_);if(I.definition.enabled!==!1||!hc(I.definition))return!1;return I.definition.enabled=!0,!0}function ph(_){if(_[dt]===void 0){_[dt]=Br();return}let I=gc(_);I.definition.enabled=!0,I.preToolUse.push(Br().PreToolUse?.[0]??{hooks:[]})}function fh(_){let I=!1;for(let O of Object.values(_)){if(!pt(O)||!Array.isArray(O.PreToolUse))continue;O.PreToolUse=O.PreToolUse.flatMap((L)=>{if(!pt(L)||!Array.isArray(L.hooks))return[L];let J=L.hooks.filter((K)=>!pt(K)||K.command!==Ci);if(J.length!==L.hooks.length)I=!0;return J.length===0?[]:[{...L,hooks:J}]})}return I}function Gr(_,I){mn(_,`${JSON.stringify(I,null,2)}
238
+ `)}function yc(_){let I=Ot(_.home);if(ah(ch(I),{recursive:!0}),!fc(I))return Gr(I,{[dt]:Br()}),{path:I,alreadyInstalled:!1};let O=mc(I);if(dh(O))return{path:I,alreadyInstalled:!0};if(uh(O))return Gr(I,O),{path:I,alreadyInstalled:!1};return ph(O),Gr(I,O),{path:I,alreadyInstalled:!1}}function vc(_){let I=Ot(_.home);if(!fc(I))return{path:I,alreadyInstalled:!1};let O=mc(I);if(!fh(O))return{path:I,alreadyInstalled:!1};return Gr(I,O),{path:I,alreadyInstalled:!0}}import{existsSync as Ei,readlinkSync as hh}from"node:fs";import{join as Vn}from"node:path";import{spawn as mh}from"node:child_process";var $n=En.map((_)=>({target:_.id,flag:_.flag,label:pn(_.id),probeCommand:_.probeCommand}));function Ri(_){let I=new Set(_);return $n.map((O)=>O.target).filter((O)=>I.has(O))}async function bc(_,I){for(let O of _)await I(O)}var gh=5000;function Kt(_,I=gh){return new Promise((O)=>{let L=Wn([..._],process.env),J=mh(L.cmd,L.args,{env:process.env,stdio:"ignore"}),K=!1,ne=(de)=>{if(K)return;K=!0,clearTimeout(oe),O(de)},oe=setTimeout(()=>{J.kill(),ne(!1)},I);J.on("error",()=>ne(!1)),J.on("close",(de)=>ne(de===0))})}function wc(_=Kt,I={}){let O=new Set(I.configuredTargets??[]);return Promise.all($n.map(async(L)=>({target:L.target,flag:L.flag,label:L.label,...xc(I.action,await _(L.probeCommand),O.has(L.target))})))}function kc(_,I){let O=new Set(I.configuredTargets??[]);return _.map((L)=>({...L,...xc(I.action,L.available,O.has(L.target))}))}function xc(_,I,O){if(_==="uninstall")return O?{available:!0}:{available:!1,unavailableReason:"not installed"};if(_==="install"&&O)return{available:!1,unavailableReason:"already installed"};if(!I)return{available:!1,unavailableReason:"CLI not installed"};return{available:!0}}var Fn="cc-safety-net",Pc=["npx","-y","@deepseek-ai/dsh"],Sc="DeepSeek Harness",Cc=["@deepseek-ai","dsh-desktop"],Ec="Quit DeepSeek Harness Desktop, then run this command again: Desktop plugins can only change while it is closed.",Pi=(_)=>`DeepSeek Harness Desktop is not in its default location, so ${_} ${Fn} from its Plugins page.`,Ac=(_,I)=>Ei(Vn(Lo(_),I,"package.json"));function Ai(_,I){let O=I.platform??process.platform,L=Ac(_,"desktop"),J=O==="darwin"?[Vn(_.home,"Applications"),I.systemApplications??"/Applications"].map((K)=>Vn(K,`${Sc}.app`,"Contents","Resources","runtime","cli","bin","dsh")):O==="win32"?[Vn(_.env.get("LOCALAPPDATA")||Vn(_.home,"AppData","Local"),"Programs",Sc,"resources","runtime","cli","bin","dsh.cmd")]:[];return{profile:L,cli:L?J.find((K)=>Ei(K)):void 0}}function _c(_,I=process.platform){if(I==="win32")return Ei(Vn(_.env.get("APPDATA")||Vn(_.home,"AppData","Roaming"),...Cc,"lockfile"));let O=yh(Vn(_.home,"Library","Application Support",...Cc,"SingletonLock")),L=Number(/-(\d+)$/.exec(O??"")?.[1]);return Number.isInteger(L)&&L>0&&vh(L)}function yh(_){try{return hh(_)}catch{return}}function vh(_){try{return process.kill(_,0),!0}catch(I){return I.code==="EPERM"}}async function Ic(_,I={}){let O=Ai(_,I);if(O.cli&&_c(_,I.platform))throw Error(Ec);let L=!O.cli||Ac(_,"web")||await(I.probe??Kt)(uo),J=[...O.cli?[{profile:"desktop",label:"Desktop",dsh:[O.cli]}]:[],...L?[{profile:"web",label:"web",dsh:Pc}]:[]];return{commands:J.map((K)=>[...K.dsh,"plugin","--profile",K.profile,"add",Fn]),afterInstall:async()=>{let K=new Set(No(_).filter((oe)=>oe.enabled).map((oe)=>oe.name)),ne=J.filter((oe)=>!K.has(oe.profile));if(ne.length>0)throw Error(`DeepSeek Harness installed ${Fn} in the ${Rc(ne)} but did not enable it. Enable it from the Plugins page, or update ${Fn} if your registry served a release without DeepSeek Harness support.`)},message:[`Added ${Fn} to the DeepSeek Harness ${Rc(J)}.`,...O.profile&&!O.cli?[Pi("add")]:[]].join(`
239
+ `)}}function Rc(_){return`${_.map((I)=>I.label).join(" and ")} profile${_.length>1?"s":""}`}function Tc(_,I={}){let O=new Set(No(_).map((K)=>K.name));if(!O.has("desktop")&&!O.has("web"))throw Error(`${Fn} is not installed in the DeepSeek Harness web or Desktop profile`);let L=O.has("desktop")?Ai(_,I).cli:void 0,J=O.has("desktop")&&!L;if(J&&!O.has("web"))throw Error(Pi("remove"));if(L&&_c(_,I.platform))throw Error(Ec);return{commands:[...L?[[L,"plugin","--profile","desktop","remove",Fn]]:[],...O.has("web")?[[...Pc,"plugin","--profile","web","remove",Fn]]:[]],...J?{afterUninstall:()=>{throw Error(`Removed ${Fn} from the DeepSeek Harness web profile, but ${Pi("remove")}`)}}:{}}}function $c(_,I,O={}){let L=Ai(I,O).cli!==void 0;return _.map((J)=>J.target==="deepseek-harness"&&L?{...J,available:!0,unavailableReason:void 0}:J)}import{existsSync as bh,readdirSync as wh,rmSync as kh}from"node:fs";import{join as xh}from"node:path";function Oc(_,I=process.platform,O){if(!bh(_))return;let L=I==="win32"?/^bunx-\d+-cc-safety-net@/:new RegExp(`^bunx-${process.getuid?.()??0}-cc-safety-net@`);wh(_).filter((J)=>J!==O&&L.test(J)).forEach((J)=>{kh(xh(_,J),{recursive:!0,force:!0})})}import{existsSync as Dc,readdirSync as Sh,rmSync as Ch}from"node:fs";import{join as _t}from"node:path";function qr(_,I=process.platform){let O=_t(_.env.get("npm_config_cache")||(I==="win32"?_t(_.env.get("LOCALAPPDATA")||_t(_.home,"AppData","Local"),"npm-cache"):_t(_.home,".npm")),"_npx");if(!Dc(O))return;Sh(O).filter((L)=>Dc(_t(O,L,"node_modules","cc-safety-net"))).forEach((L)=>{Ch(_t(O,L),{recursive:!0,force:!0})})}import{existsSync as Mc,mkdirSync as Ph,readFileSync as Uc}from"node:fs";import{dirname as Eh,join as Hc}from"node:path";function Rh(_,I){if(_[I]!=="#")return I;let O=_.indexOf(`
240
+ `,I+1);return O===-1?_.length:O+1}function _i(_,I,O){let L=new RegExp(`^(\\s*)${I}\\s*=\\s*\\[`),J=0;for(let K of _.split(`
241
+ `)){if(/^\s*\[/.test(K))return;let ne=L.exec(K);if(ne){let oe=J+ne[0].lastIndexOf("[");return{start:oe,end:_o(_,oe,{skipComment:Rh,...O})}}J+=K.length+1}return}function Lc(_,I,O){let L=_.slice(0,I.end).trimEnd(),J=ma(_,I.end),K=J===""?" ":`${J} `,ne=!L.endsWith("[")&&!L.endsWith(",");return`${L}${ne?",":""}
242
+ ${K}${O}${_.slice(I.end)}`}function Nc(_,I,O){let L=_.indexOf(O,I.start);if(L===-1||L>I.end)return _;return Sr(_,{start:L,end:L+O.length})}function jc(_,I){let O=new RegExp(`^\\s*${I}\\s*=\\s*\\[\\s*]\\s*(?:#.*)?$`),L=_.split(`
243
+ `),J=L.findIndex((oe)=>/^\s*\[/.test(oe)),K=J===-1?L:L.slice(0,J),ne=J===-1?[]:L.slice(J);return[...K.filter((oe)=>!O.test(oe)),...ne].join(`
244
+ `)}function Fc(_,I,O){let L=new RegExp(`^\\s*\\[\\[${I}]]\\s*$`,"m");return _.split(/(?=^\s*\[)/m).filter((J)=>!L.test(J)||!J.includes(O)).join("").trimEnd()}var Yt=In["kimi-code"],Ii=`[[hooks]]
244
245
  event = "PreToolUse"
245
- command = "${Jn}"`,Lc=`{ event = "PreToolUse", command = "${Jn}" }`,wc={stringError:"Unterminated string in Kimi Code config",bracketError:"Unmatched hooks array in Kimi Code config"};function kc(P){return yc(P.env.get("KIMI_CODE_HOME")??yc(P.home,".kimi-code"),"config.toml")}function tg(P){let A=bi(P,"hooks",wc);if(A&&P.slice(A.start+1,A.end).trim())return fc(P,A,Lc);let q=gc(P,"hooks").trimEnd();if(q==="")return`${Li}
246
- `;return`${q}
247
-
248
- ${Li}
249
- `}function xc(P){let A=kc(P);if(Qm(eg(A),{recursive:!0}),!vc(A))return kt(A,`${Li}
250
- `),{path:A,alreadyInstalled:!1};let q=bc(A,"utf-8");if(q.includes(Jn))return{path:A,alreadyInstalled:!0};return kt(A,tg(q)),{path:A,alreadyInstalled:!1}}function Cc(P){let A=kc(P);if(!vc(A))return{path:A,alreadyInstalled:!1};let q=bc(A,"utf-8");if(!q.includes(Jn))return{path:A,alreadyInstalled:!1};let V=bi(q,"hooks",wc),ee=V?mc(q,V,Lc):`${hc(q,"hooks",Jn)}
251
- `;return kt(A,ee),{path:A,alreadyInstalled:!0}}var wi="safety-net@cc-marketplace",Sc=new Set(["claude-code","codex","copilot-cli","gemini-cli","hermes-agent","openclaw","opencode","pi"]),Rc=new Set(["antigravity-cli","cursor","grok-build","hermes-agent","kimi-code"]);function ki(P){return/^\s*safety-net@cc-marketplace[^a-z0-9-][^\n]*installed,/m.test(P??"")}function _c(P){return/^\s*cc-safety-net[^a-z0-9-][^\n]*installed,/m.test(P??"")}function ng(P){return/^Marketplace `cc-marketplace`\s*$/m.test(P??"")}var Tc={"claude-code":{installCommands:(P)=>{let A=br(P,"cc-safety-net@cc-marketplace");return{commands:[...A?[["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","update","cc-safety-net@cc-marketplace"]]:[["claude","plugin","marketplace","add","kenryu42/cc-marketplace"],["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","install","cc-safety-net@cc-marketplace"]],...xo(P).status==="disabled"?[["claude","plugin","enable","cc-safety-net@cc-marketplace"]]:[]],cleanupCommands:br(P,wi)?[["claude","plugin","uninstall",wi]]:[],update:A}},uninstallCommands:[["claude","plugin","uninstall","cc-safety-net@cc-marketplace"],["claude","plugin","marketplace","remove","cc-marketplace"]]},codex:{installCommands:async(P,A)=>{let q=A??await St(["codex","plugin","list"]),V=_c(q);return{commands:[V||ng(q)?["codex","plugin","marketplace","upgrade","cc-marketplace"]:["codex","plugin","marketplace","add","kenryu42/cc-marketplace"],["codex","plugin","add","cc-safety-net@cc-marketplace"]],cleanupCommands:ki(q)?[["codex","plugin","remove","safety-net@cc-marketplace"]]:[],update:V}},uninstallCommands:[["codex","plugin","remove","cc-safety-net@cc-marketplace"],["codex","plugin","marketplace","remove","cc-marketplace"]],postInstallMessage:ea},"copilot-cli":{installCommands:async()=>{let P=await St(["copilot","plugin","list"]),A=[...ua(P)?[["copilot","plugin","uninstall","copilot-safety-net"]]:[],...pa(P)?[["copilot","plugin","uninstall",la]]:[]];if(ca(P))return{commands:[["copilot","plugin","marketplace","update","cc-marketplace"],["copilot","plugin","update",Nt]],cleanupCommands:A,update:!0};return{commands:[da(await St(["copilot","plugin","marketplace","list"]))?["copilot","plugin","marketplace","update","cc-marketplace"]:["copilot","plugin","marketplace","add","kenryu42/cc-marketplace"],["copilot","plugin","install",Nt]],cleanupCommands:A}},uninstallCommands:[["copilot","plugin","uninstall","cc-safety-net@cc-marketplace"],["copilot","plugin","marketplace","remove","cc-marketplace"]]},"gemini-cli":{installCommands:(P)=>{let A=_o(P);if(A.status==="configured")return{commands:[["gemini","extensions","update","gemini-safety-net"]],update:!0};if(A.status==="disabled")return{commands:[["gemini","extensions","update","gemini-safety-net"],["gemini","extensions","enable","gemini-safety-net"]],update:!0};return{commands:[["gemini","extensions","install","https://github.com/kenryu42/gemini-safety-net","--consent"]]}},uninstallCommands:[["gemini","extensions","uninstall","gemini-safety-net"]]},openclaw:{beforeInstall:qo,installCommands:(P)=>{let A=!Br(Gr(Hn(P),Tt));return{commands:tl(),afterInstall:()=>nl(A)}},uninstallCommands:[["openclaw","plugins","uninstall",yt,"--force"]],postInstallMessage:["Restart the OpenClaw Gateway to apply the change.","If plugins.allow is set in openclaw.json, it must also list cc-safety-net."].join(`
252
- `)},opencode:{installCommands:pl},pi:{installCommands:[["pi","install","npm:cc-safety-net"]],uninstallCommands:[["pi","uninstall","npm:cc-safety-net"]]}};function Ic(P,A=(q)=>q){try{let q=JSON.parse(A(Ac(P,"utf-8")));if(!q||typeof q!=="object"||Array.isArray(q))throw Error(`Settings file ${P} must be a JSON object`);return q}catch(q){if(q instanceof SyntaxError)throw Error(`Failed to parse ${P}: ${q.message}`);throw q}}function rg(P){let A=Gr(In(P),"settings.json");if(!Br(A))return;let q=Ic(A,_t),V=q.enabledPlugins;if(!V||typeof V!=="object"||Array.isArray(V))return;if(V[Nt]!==!1)return;let ee=Ac(A,"utf-8"),ne=ee.replace(new RegExp(`("${Nt}"\\s*:\\s*)false`),"$1true");return V[Nt]=!0,kt(A,ne!==ee?ne:`${JSON.stringify(q,null,2)}
253
- `),`Enabled ${Nt} plugin in ${A}`}function og(P){let A=ei(P);if(!Br(A))return;let q=Ic(A);if(!Array.isArray(q.packages))return;let V=q.packages.find((ee)=>!!ee&&typeof ee==="object"&&!Array.isArray(ee)&&ti(ee.source)&&("extensions"in ee));if(!V)return;return delete V.extensions,kt(A,`${JSON.stringify(q,null,2)}
254
- `),`Enabled npm:cc-safety-net extensions in ${A}`}function Pc(P,A){let q=xt({label:A,booleans:Object.fromEntries(Ht.map((ne)=>[ne.target,[ne.flag]]))},P),V=q.errors[0];if(V)throw Error(V);let ee=Ht.filter((ne)=>q.flags[ne.target]).map((ne)=>ne.target);if(ee.length!==1)throw Error(`Choose exactly one ${A} target: ${Ht.map((ne)=>ne.flag).join(", ")}`);return ee[0]}async function $c(P,A=hn){let[q,V,ee]=await Promise.all([A(["amp","plugins","list"],30000),A(["codex","plugin","list"],30000),A(["copilot","--binary-version"])]);return{codexPluginListOutput:V,hooks:xn(P,process.cwd(),{ampPluginListOutput:q,codexPluginListOutput:V,copilotCliVersion:ee})}}async function ig(P,A,q=hn){let V=await $c(P,q);return V.hooks.filter((ee)=>A==="install"?ee.configured:ee.detected||ee.inspectionStatus==="not-inspected").filter((ee)=>ee.platform!=="codex"||!ki(V.codexPluginListOutput)||_c(V.codexPluginListOutput)).map((ee)=>ee.platform)}function sg(P,A,q,V){if(q.length>0)return{finish:async()=>[Pc(q,A)]};if(!V.selectTargets&&!ui(V.input,V.output))return{finish:async()=>[Pc(q,A)]};let ee=V.detectConfiguredTargets??(()=>ig(P,A,V.fetchVersion)),ne=Promise.all([cc(V.probeTargets),ee()]);return{ready:ne,finish:async()=>{let[ce,he]=await ne,ye=dc(ce,{action:A,configuredTargets:he}),be=V.selectTargets?await V.selectTargets(A,Dc(A,ye)):await ql(A,Dc(A,ye),{input:V.input,output:V.output});if(be==="update")return be;if(!be||be.length===0)return null;return yi(be)}}}async function ag(P,A,q=!1,V){let ee=Tc[P];ee.beforeInstall?.(A);let ne=typeof ee.installCommands==="function"?await ee.installCommands(A,V):{commands:ee.installCommands};return await Go(ne.commands),await Ka(ne.cleanupCommands??[]),await ne.afterInstall?.(),[`${ne.update||q?"Updated":"Installed"} ${bt(P)} integration`,ee.postInstallMessage].filter(Boolean).join(`
255
- `)}async function lg(P){let A=Tc[P];if(!A.uninstallCommands)throw Error(`${bt(P)} uninstall is not supported`);return await Go(A.uninstallCommands),`Uninstalled ${bt(P)} integration`}function cg(P){let A=hl(P);return A.alreadyInstalled?`Uninstalled OpenCode plugin from ${A.path}`:`OpenCode plugin not installed in ${A.path}`}var Oc={"antigravity-cli":{install:ic,uninstall:sc},cursor:{install:ka,uninstall:xa},"grok-build":{install:Ia,uninstall:$a},"kimi-code":{install:xc,uninstall:Cc}};function dg(P,A,q,V=!1){if(P==="install"&&!V)Ur(q);let ee=Oc[A][P](q),ne=bt(A),ce=P!=="install"?"Uninstalled":V?"Updated":"Installed";return P==="install"&&ee.alreadyInstalled?V?`${ne} hook up to date in ${ee.path}`:`${ne} hook already installed in ${ee.path}`:P==="uninstall"&&!ee.alreadyInstalled?`${ne} hook not installed in ${ee.path}`:`${ce} ${ne} hook ${P==="install"?"in":"from"} ${ee.path}`}var Fc={amp:{install:Ql,uninstall:ec,restartNote:'Amp personal plugins apply to every Amp session, including Orb threads. Restart Amp or run "plugins: reload" to apply the change.'},"hermes-agent":{install:Ma,uninstall:Ha,afterInstall:async(P)=>{let A=Mo(P);return await St(["hermes","plugins","enable",It,"--no-allow-tool-override"]),!A},beforeUninstall:async(P)=>{jo(P);try{await St(["hermes","plugins","disable",It])}catch(A){console.warn(`${A instanceof Error?A.message:String(A)}
256
- Removing the plugin files anyway; ${It} may still be listed in the Hermes config.`)}},restartNote:"Restart Hermes to apply the change."}};async function ug(P,A,q,V=!1){let ee=Fc[A];if(P==="uninstall")await ee.beforeUninstall?.(q);let ne=P==="install"?await ee.install(q):await ee.uninstall(q),ce=P==="install"&&await ee.afterInstall?.(q),he=bt(A),ye=!ce&&(P==="install"&&ne.alreadyInstalled||P==="uninstall"&&!ne.alreadyInstalled);return[ye?P==="install"?`${he} plugin ${V?"up to date":"already installed"} at ${ne.path}`:`${he} plugin not installed at ${ne.path}`:`${P!=="install"?"Uninstalled":V?"Updated":"Installed"} ${he} plugin ${P==="install"?"at":"from"} ${ne.path}`,ye?void 0:ee.restartNote].filter(Boolean).join(`
257
- `)}var pg={"copilot-cli":{afterInstall:rg},"hermes-agent":{beforeInstall:(P,A)=>{if(!A)Ur(P)}},openclaw:{beforeUninstall:qo},pi:{afterInstall:og}};function fg(P){return P in Oc}function mg(P){return P in Fc}var Ec=["Install CC Safety Net as a native Kimi Code plugin:",""," 1. Start Kimi Code and run: /plugins install https://github.com/kenryu42/cc-safety-net"," Confirm the trust prompt; it defaults to cancel."," 2. Run /reload, or start a new session.","","Note: Kimi Code hooks are fail-open. When the hook process cannot start, crashes, or times","out, Kimi Code allows the tool call."].join(`
258
- `);function gg(P){if(Mn({environment:P,cwd:process.cwd()}).status!=="configured")return Ec;return[Ec,"",dt.red(["CAUTION: the global Kimi Code hook is installed and will run alongside the plugin.","After the plugin is active, remove it with: cc-safety-net uninstall --kimi-code"].join(`
246
+ command = "${Yt}"`,Gc=`{ event = "PreToolUse", command = "${Yt}" }`,Bc={stringError:"Unterminated string in Kimi Code config",bracketError:"Unmatched hooks array in Kimi Code config"};function qc(_){return Hc(_.env.get("KIMI_CODE_HOME")??Hc(_.home,".kimi-code"),"config.toml")}function Ah(_){let I=_i(_,"hooks",Bc);if(I&&_.slice(I.start+1,I.end).trim())return Lc(_,I,Gc);let O=jc(_,"hooks").trimEnd();if(O==="")return`${Ii}
247
+ `;return`${O}
248
+
249
+ ${Ii}
250
+ `}function Vc(_){let I=qc(_);if(Ph(Eh(I),{recursive:!0}),!Mc(I))return mn(I,`${Ii}
251
+ `),{path:I,alreadyInstalled:!1};let O=Uc(I,"utf-8");if(O.includes(Yt))return{path:I,alreadyInstalled:!0};return mn(I,Ah(O)),{path:I,alreadyInstalled:!1}}function zc(_){let I=qc(_);if(!Mc(I))return{path:I,alreadyInstalled:!1};let O=Uc(I,"utf-8");if(!O.includes(Yt))return{path:I,alreadyInstalled:!1};let L=_i(O,"hooks",Bc),J=L?Nc(O,L,Gc):`${Fc(O,"hooks",Yt)}
252
+ `;return mn(I,J),{path:I,alreadyInstalled:!0}}var Ti="safety-net@cc-marketplace",Jc=new Set(["claude-code","codex","copilot-cli","gemini-cli","hermes-agent","openclaw","opencode","pi"]),Wc=new Set(["antigravity-cli","cursor","grok-build","hermes-agent","kimi-code"]);function $i(_){return/^\s*safety-net@cc-marketplace[^a-z0-9-][^\n]*installed,/m.test(_??"")}function Qc(_){return/^\s*cc-safety-net[^a-z0-9-][^\n]*installed,/m.test(_??"")}function _h(_){return/^Marketplace `cc-marketplace`\s*$/m.test(_??"")}var ed={"claude-code":{installCommands:(_)=>{let I=xr(_,"cc-safety-net@cc-marketplace");return{commands:[...I?[["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","update","cc-safety-net@cc-marketplace"]]:[["claude","plugin","marketplace","add","kenryu42/cc-marketplace"],["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","install","cc-safety-net@cc-marketplace"]],...Eo(_).status==="disabled"?[["claude","plugin","enable","cc-safety-net@cc-marketplace"]]:[]],cleanupCommands:xr(_,Ti)?[["claude","plugin","uninstall",Ti]]:[],update:I}},uninstallCommands:[["claude","plugin","uninstall","cc-safety-net@cc-marketplace"],["claude","plugin","marketplace","remove","cc-marketplace"]]},codex:{installCommands:async(_,I)=>{let O=I??await yn(["codex","plugin","list"]),L=Qc(O);return{commands:[L||_h(O)?["codex","plugin","marketplace","upgrade","cc-marketplace"]:["codex","plugin","marketplace","add","kenryu42/cc-marketplace"],["codex","plugin","add","cc-safety-net@cc-marketplace"]],cleanupCommands:$i(O)?[["codex","plugin","remove","safety-net@cc-marketplace"]]:[],update:L}},uninstallCommands:[["codex","plugin","remove","cc-safety-net@cc-marketplace"],["codex","plugin","marketplace","remove","cc-marketplace"]],postInstallMessage:da},"copilot-cli":{installCommands:async()=>{let _=await yn(["copilot","plugin","list"]),I=[...ka(_)?[["copilot","plugin","uninstall","copilot-safety-net"]]:[],...xa(_)?[["copilot","plugin","uninstall",va]]:[]];if(ba(_))return{commands:[["copilot","plugin","marketplace","update","cc-marketplace"],["copilot","plugin","update",_n]],cleanupCommands:I,update:!0};return{commands:[wa(await yn(["copilot","plugin","marketplace","list"]))?["copilot","plugin","marketplace","update","cc-marketplace"]:["copilot","plugin","marketplace","add","kenryu42/cc-marketplace"],["copilot","plugin","install",_n]],cleanupCommands:I}},uninstallCommands:[["copilot","plugin","uninstall","cc-safety-net@cc-marketplace"],["copilot","plugin","marketplace","remove","cc-marketplace"]]},"gemini-cli":{installCommands:(_)=>{let I=Ho(_);if(I.status==="configured")return{commands:[["gemini","extensions","update","gemini-safety-net"]],update:!0};if(I.status==="disabled")return{commands:[["gemini","extensions","update","gemini-safety-net"],["gemini","extensions","enable","gemini-safety-net"]],update:!0};return{commands:[["gemini","extensions","install","https://github.com/kenryu42/gemini-safety-net","--consent"]]}},uninstallCommands:[["gemini","extensions","uninstall","gemini-safety-net"]]},openclaw:{beforeInstall:Xo,installCommands:(_)=>{let I=!zr(Vr(Gt(_),Cn));return{commands:fl(),afterInstall:()=>ml(I)}},uninstallCommands:[["openclaw","plugins","uninstall",dn,"--force"]],postInstallMessage:["Restart the OpenClaw Gateway to apply the change.","If plugins.allow is set in openclaw.json, it must also list cc-safety-net."].join(`
253
+ `)},opencode:{installCommands:Cl},pi:{installCommands:[["pi","install","npm:cc-safety-net"]],uninstallCommands:[["pi","uninstall","npm:cc-safety-net"]]},"deepseek-harness":{installCommands:(_)=>Ic(_),uninstallCommands:(_)=>Tc(_)}};function nd(_,I=(O)=>O){try{let O=JSON.parse(I(Xc(_,"utf-8")));if(!O||typeof O!=="object"||Array.isArray(O))throw Error(`Settings file ${_} must be a JSON object`);return O}catch(O){if(O instanceof SyntaxError)throw Error(`Failed to parse ${_}: ${O.message}`);throw O}}function Ih(_){let I=Vr(Lt(_),"settings.json");if(!zr(I))return;let O=nd(I,Sn),L=O.enabledPlugins;if(!L||typeof L!=="object"||Array.isArray(L))return;if(L[_n]!==!1)return;let J=Xc(I,"utf-8"),K=J.replace(new RegExp(`("${_n}"\\s*:\\s*)false`),"$1true");return L[_n]=!0,mn(I,K!==J?K:`${JSON.stringify(O,null,2)}
254
+ `),`Enabled ${_n} plugin in ${I}`}function Th(_){let I=li(_);if(!zr(I))return;let O=nd(I);if(!Array.isArray(O.packages))return;let L=O.packages.find((J)=>!!J&&typeof J==="object"&&!Array.isArray(J)&&ci(J.source)&&("extensions"in J));if(!L)return;return delete L.extensions,mn(I,`${JSON.stringify(O,null,2)}
255
+ `),`Enabled npm:cc-safety-net extensions in ${I}`}function Kc(_,I){let O=gn({label:I,booleans:Object.fromEntries($n.map((K)=>[K.target,[K.flag]]))},_),L=O.errors[0];if(L)throw Error(L);let J=$n.filter((K)=>O.flags[K.target]).map((K)=>K.target);if(J.length!==1)throw Error(`Choose exactly one ${I} target: ${$n.map((K)=>K.flag).join(", ")}`);return J[0]}async function td(_,I=vt){let[O,L,J]=await Promise.all([I(["amp","plugins","list"],30000),I(["codex","plugin","list"],30000),I(["copilot","--binary-version"])]);return{codexPluginListOutput:L,hooks:Rt(_,process.cwd(),{ampPluginListOutput:O,codexPluginListOutput:L,copilotCliVersion:J})}}async function $h(_,I,O=vt){let L=await td(_,O);return L.hooks.filter((J)=>I==="install"?J.configured:J.detected||J.inspectionStatus==="not-inspected").filter((J)=>J.platform!=="codex"||!$i(L.codexPluginListOutput)||Qc(L.codexPluginListOutput)).map((J)=>J.platform)}function Oh(_,I,O,L){if(O.length>0)return{finish:async()=>[Kc(O,I)]};if(!L.selectTargets&&!bi(L.input,L.output))return{finish:async()=>[Kc(O,I)]};let J=L.detectConfiguredTargets??(()=>$h(_,I,L.fetchVersion)),K=Promise.all([wc(L.probeTargets).then((ne)=>$c(ne,_)),J()]);return{ready:K,finish:async()=>{let[ne,oe]=await K,de=kc(ne,{action:I,configuredTargets:oe}),ue=L.selectTargets?await L.selectTargets(I,Zc(I,de)):await tc(I,Zc(I,de),{input:L.input,output:L.output});if(ue==="update")return ue;if(!ue||ue.length===0)return null;return Ri(ue)}}}async function Dh(_,I,O=!1,L){let J=ed[_];J.beforeInstall?.(I);let K=typeof J.installCommands==="function"?await J.installCommands(I,L):{commands:J.installCommands};return await Yo(K.commands),await al(K.cleanupCommands??[]),await K.afterInstall?.(),[`${K.update||O?"Updated":"Installed"} ${pn(_)} integration`,K.message??J.postInstallMessage].filter(Boolean).join(`
256
+ `)}async function Lh(_,I){let O=ed[_];if(!O.uninstallCommands)throw Error(`${pn(_)} uninstall is not supported`);let L=typeof O.uninstallCommands==="function"?O.uninstallCommands(I):{commands:O.uninstallCommands};return await Yo(L.commands),L.afterUninstall?.(),`Uninstalled ${pn(_)} integration`}function Nh(_){let I=Al(_);return I.alreadyInstalled?`Uninstalled OpenCode plugin from ${I.path}`:`OpenCode plugin not installed in ${I.path}`}var rd={"antigravity-cli":{install:yc,uninstall:vc},cursor:{install:$a,uninstall:Oa},"grok-build":{install:Va,uninstall:za},"kimi-code":{install:Vc,uninstall:zc}};function jh(_,I,O,L=!1){if(_==="install"&&!L)qr(O);let J=rd[I][_](O),K=pn(I),ne=_!=="install"?"Uninstalled":L?"Updated":"Installed";return _==="install"&&J.alreadyInstalled?L?`${K} hook up to date in ${J.path}`:`${K} hook already installed in ${J.path}`:_==="uninstall"&&!J.alreadyInstalled?`${K} hook not installed in ${J.path}`:`${ne} ${K} hook ${_==="install"?"in":"from"} ${J.path}`}var od={amp:{install:uc,uninstall:pc,restartNote:'Amp personal plugins apply to every Amp session, including Orb threads. Restart Amp or run "plugins: reload" to apply the change.'},"hermes-agent":{install:Za,uninstall:Xa,afterInstall:async(_)=>{let I=Jo(_);return await yn(["hermes","plugins","enable",Pn,"--no-allow-tool-override"]),!I},beforeUninstall:async(_)=>{zo(_);try{await yn(["hermes","plugins","disable",Pn])}catch(I){console.warn(`${I instanceof Error?I.message:String(I)}
257
+ Removing the plugin files anyway; ${Pn} may still be listed in the Hermes config.`)}},restartNote:"Restart Hermes to apply the change."}};async function Fh(_,I,O,L=!1){let J=od[I];if(_==="uninstall")await J.beforeUninstall?.(O);let K=_==="install"?await J.install(O):await J.uninstall(O),ne=_==="install"&&await J.afterInstall?.(O),oe=pn(I),de=!ne&&(_==="install"&&K.alreadyInstalled||_==="uninstall"&&!K.alreadyInstalled);return[de?_==="install"?`${oe} plugin ${L?"up to date":"already installed"} at ${K.path}`:`${oe} plugin not installed at ${K.path}`:`${_!=="install"?"Uninstalled":L?"Updated":"Installed"} ${oe} plugin ${_==="install"?"at":"from"} ${K.path}`,de?void 0:J.restartNote].filter(Boolean).join(`
258
+ `)}var Hh={"copilot-cli":{afterInstall:Ih},"hermes-agent":{beforeInstall:(_,I)=>{if(!I)qr(_)}},openclaw:{beforeUninstall:Xo},pi:{afterInstall:Th}};function Mh(_){return _ in rd}function Uh(_){return _ in od}var Yc=["Install CC Safety Net as a native Kimi Code plugin:",""," 1. Start Kimi Code and run: /plugins install https://github.com/kenryu42/cc-safety-net"," Confirm the trust prompt; it defaults to cancel."," 2. Run /reload, or start a new session.","","Note: Kimi Code hooks are fail-open. When the hook process cannot start, crashes, or times","out, Kimi Code allows the tool call."].join(`
259
+ `);function Gh(_){if(Ut({environment:_,cwd:process.cwd()}).status!=="configured")return Yc;return[Yc,"",nn.red(["CAUTION: the global Kimi Code hook is installed and will run alongside the plugin.","After the plugin is active, remove it with: cc-safety-net uninstall --kimi-code"].join(`
259
260
  `))].join(`
260
- `)}function Dc(P,A){return A.map((q)=>P==="install"&&q.target==="kimi-code"&&q.unavailableReason==="already installed"?{...q,available:!0,unavailableReason:void 0,label:`${q.label} (global hook installed)`}:q)}function hg(P,A){if(P.selectKimiInstallMethod)return P.selectKimiInstallMethod();if(!ui(P.input,P.output))return Promise.resolve("global-hook");return Bl({input:P.input,output:P.output,globalHookInstalled:Mn({environment:A,cwd:process.cwd()}).status==="configured"})}async function Nc(P,A,q,V=!1,ee){let ne=pg[A];if(P==="install")ne?.beforeInstall?.(q,V);if(P==="uninstall")ne?.beforeUninstall?.(q);if(fg(A))return dg(P,A,q,V);if(mg(A))return ug(P,A,q,V);if(P==="uninstall")return A==="opencode"?cg(q):lg(A);return[await ag(A,q,V,ee),await ne?.afterInstall?.(q)].filter(Boolean).join(`
261
- `)}function yg(P){let A=xt({label:"update"},P).errors[0];if(A)throw Error(A)}async function vg(P,A=hn){let q=await $c(P,A),V=Gr(In(P),"installed-plugins");return{targets:yi([...q.hooks.filter((ne)=>ne.platform!=="copilot-cli"&&ne.detected).map((ne)=>ne.platform),...[wr,aa,sa].flatMap((ne)=>Br(Gr(V,...ne))?["copilot-cli"]:[]),...br(P,wi)?["claude-code"]:[],...ki(q.codexPluginListOutput)?["codex"]:[]]),codexPluginListOutput:q.codexPluginListOutput}}async function bg(P){let A=c(),q=P.output??process.stdout,V=(P.scriptPath??process.argv[1]??"").split(/[\\/]/),ee=V.find((et)=>/^bunx-\d+-/.test(et)),ne=ee!==void 0||V.includes("_npx")?null:(P.checkLatestVersion??Wt)(),ce=async()=>{let et=ne&&await ne;if(et?.updateAvailable)q.write(`
262
- Update available: cc-safety-net ${et.currentVersion} → ${et.latestVersion}. Update this CLI with your package manager, e.g. \`npm i -g cc-safety-net@latest\` for a global install.
263
- `)},he=vg(A,P.fetchVersion??hn).then(async(et)=>{let Re=new Set(et.targets);return{targets:et.targets,codexPluginListOutput:et.codexPluginListOutput,available:new Map(await Promise.all(Ht.filter((at)=>Re.has(at.target)&&Sc.has(at.target)).map(async(at)=>[at.target,await vi(at.probeCommand)])))}}),ye=await An(P.showBanner??!0,()=>({ready:he,finish:()=>he}),()=>Dn({input:P.input??process.stdin,output:q}),{loadingMessage:"Checking installed integrations…",output:q}),be=await Promise.resolve().then(()=>(ac(A.tmpdir,process.platform,ee),null)).catch((et)=>Wn(et));if(ye.targets.length===0){if(q.write("No installed integrations found. Run `cc-safety-net install` to set one up.\n"),be!==null)console.error(be);return await ce(),be===null?0:1}let xe=ye.targets.some((et)=>Rc.has(et))?await Promise.resolve().then(()=>(Ur(A),null)).catch((et)=>Wn(et)):null,Ie=await gr(Promise.all(ye.targets.map((et)=>{if(Sc.has(et)&&!ye.available.get(et))return Promise.resolve({message:`${bt(et)} not found; skipped`,failed:!1});if(xe!==null&&Rc.has(et))return Promise.resolve({message:xe,failed:!0});return Nc("install",et,A,!0,ye.codexPluginListOutput).then((Re)=>({message:Re,failed:!1}),(Re)=>({message:Wn(Re),failed:!0}))})),{loadingMessage:`Updating ${ye.targets.length} integration${ye.targets.length===1?"":"s"}…`,output:q}),Xe=be===null?Ie:[...Ie,{message:be,failed:!0}];return Xe.forEach((et)=>et.failed?console.error(et.message):q.write(`${et.message}
264
- `)),await ce(),Xe.some((et)=>et.failed)?1:0}function xi(P,A={}){return Promise.resolve().then(()=>yg(P)).then(()=>bg(A)).catch((q)=>(console.error(Wn(q)),1))}async function Kn(P,A,q={}){try{let V=c(),ee=await An(!0,()=>sg(V,P,A,q),()=>Dn({input:q.input??process.stdin,output:q.output??process.stdout}),{loadingMessage:P==="install"?"Checking available integrations…":"Checking installed integrations…",output:q.output??process.stdout});if(!ee)return(q.output??process.stdout).write(`Cancelled: nothing was ${P}ed.
265
- `),0;if(ee==="update")return(q.runUpdate??(()=>xi([],{fetchVersion:q.fetchVersion,input:q.input,output:q.output,showBanner:!1})))();let ne=q.output??process.stdout;return await lc(ee,async(ce)=>{if(ce==="kimi-code"&&P==="install"){let ye=await hg(q,V);if(ye===null){ne.write(`Cancelled: Kimi Code integration was not installed.
266
- `);return}if(ye==="plugin"){ne.write(`${gg(V)}
267
- `);return}}let he=await gr(Nc(P,ce,V),{loadingMessage:`${P==="install"?"Installing":"Uninstalling"} ${bt(ce)} integration…`,output:ne});ne.write(`${he}
268
- `)}),0}catch(V){return console.error(Wn(V)),1}}function Wn(P){let A=P instanceof Error?P.message:String(P),q=typeof P==="object"&&P!==null&&"code"in P?P.code:null;if(q==="EACCES"||q==="EPERM")return`${A}
269
- Check file permissions for the target config file and parent directory.`;if(q==="ENOENT")return`${A}
270
- Check that the target config path and parent directory exist.`;if(q==="ENOTDIR")return`${A}
271
- Check that every parent path component is a directory.`;return A}import{mkdirSync as Sg}from"node:fs";import{dirname as Rg}from"node:path";import{createInterface as Pg}from"node:readline";import{existsSync as Mc,readFileSync as Lg}from"node:fs";function un(P,A){let q=Ye(P,A);return{policy:q.policy,errors:ie(qe(q.issues,Je,(V)=>V.kind==="custom")," "," ")}}function Yn(P,A){return un(P,A).errors}function jc(P,A){return{"safety.level":P.safety.level,...Ci("safety.overrides",P.safety.overrides),"workflow.worktree_mode":String(P.workflow.worktree_mode),"destructive_command_protection.enabled":String(P.destructive_command_protection.enabled),...Ci("destructive_command_protection.overrides",P.destructive_command_protection.overrides),"destructive_command_protection.allow_paths":Si(P.destructive_command_protection.allow_paths),"secret_protection.enabled":String(P.secret_protection.enabled),...Ci("secret_protection.overrides",P.secret_protection.overrides),"secret_protection.deny_paths":Si(P.secret_protection.deny_paths),"secret_protection.allow_paths":Si(P.secret_protection.allow_paths),...A?{"audit.retention_days":String(P.audit.retention_days)}:{}}}function qr(P,A,q){let V=jc(P,q),ee=jc(A,q);return[...new Set([...Object.keys(V),...Object.keys(ee)])].flatMap((ne)=>V[ne]===ee[ne]?[]:[{field:ne,before:V[ne],after:ee[ne]}])}function Xn(P,A){let q=u(P,A);if(!Mc(q))return{baseline:C(globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__,P.home),diagnostics:[]};let V=pn(q),ee=un(V.value,P.home);return{baseline:ee.policy,diagnostics:V.errors.length>0?V.errors:ee.errors}}function pn(P){if(!Mc(P))return{errors:[`${P}: file not found`]};try{return{value:JSON.parse(Lg(P,"utf-8")),errors:[]}}catch(A){let q=A instanceof Error?A.message:String(A);return{errors:[`${P}: ${A instanceof SyntaxError?`Invalid JSON: ${q}`:q}`]}}}function Vr(P,A){let q=wg(P)?P:{};return{version:A.version,...Object.fromEntries(["safety","workflow","destructive_command_protection","secret_protection"].filter((V)=>q[V]!==void 0).map((V)=>[V,q[V]]))}}function Ci(P,A){return Object.fromEntries(Object.entries(A).flatMap(([q,V])=>V===void 0?[]:[[`${P}.${q}`,String(V)]]))}function Si(P){return P.length===0?"(none)":P.join(", ")}function wg(P){return!!P&&typeof P==="object"&&!Array.isArray(P)}import{chmodSync as kg,existsSync as Hc,mkdirSync as xg,readFileSync as Uc}from"node:fs";import{dirname as Cg}from"node:path";function Gc(P,A={}){let q=u(P,A);if(!Hc(q))return{path:q,exists:!1,raw:"",policy:W(),errors:[]};let V=Uc(q,"utf-8");if(!V.trim())return{path:q,exists:!0,raw:V,policy:W(),errors:["Config file is empty"]};try{let ee=un(JSON.parse(V),P.home);return{path:q,exists:!0,raw:V,policy:ee.policy,errors:ee.errors}}catch(ee){return{path:q,exists:!0,raw:V,policy:W(),errors:[`Invalid JSON: ${ee instanceof Error?ee.message:String(ee)}`]}}}function Vt(P,A,q={}){let V=u(P,q),ee=un(A,P.home);if(ee.errors.length>0)return{path:V,policy:W(),errors:ee.errors};let ne=ee.policy;return xg(Cg(V),{recursive:!0,mode:448}),g(re(V),`${JSON.stringify(ne,null,2)}
272
- `,384),kg(V,384),{path:V,policy:ne,errors:[]}}function Bc(P,A){let q=un(A,P.home);if(q.errors.length>0)return{errors:q.errors};return{preview:Ae(q.policy,P.env),errors:[]}}function qc(P,A={}){let q=u(P,A);if(!Hc(q))return Vt(P,X,A);let V=Uc(q,"utf-8");if(!V.trim())return Vt(P,X,A);try{return Vt(P,C(JSON.parse(V),P.home),A)}catch{return Vt(P,X,A)}}var Vc=new Set(["check","apply"]),zc="(unset)";async function Wc(P,A,q={}){let V=xt({label:"policy",booleans:{global:["-g","--global"]},positionals:"list"},A),ee=V.positionals[0],ne=[...V.errors,...ee&&!Vc.has(ee)?[`Unknown policy subcommand: ${ee}`]:[],...ee&&Vc.has(ee)&&!V.positionals[1]?[`policy ${ee} requires a file`]:[],...V.positionals.slice(2).map((Re)=>`Unexpected policy argument: ${Re}`)];if(ne.length>0){for(let Re of ne)console.error(Re);return 1}let ce=V.positionals[1];if(!ee||!ce)return Cn(or,console.error),1;let he=V.flags.global?u(P):b(q.cwd??process.cwd()),ye=pn(ce),be=[...ye.errors,...Yn(ye.value,P.home).map((Re)=>`${ce}: ${Re}`),...!V.flags.global&&Ag(ye.value)&&ye.value.audit!==void 0?[`${ce}: audit settings are user scope only; remove the audit section from a project proposal`]:[]];if(be.length>0){for(let Re of be)console.error(Re);return 1}let xe=C(ye.value,P.home);if(console.log(`Scope: ${V.flags.global?"user":"project"} (${he})`),console.log(`Proposal: ${ce}`),V.flags.global)Jc(C(pn(he).value,P.home),xe,!0);if(!V.flags.global){let Re=Xn(P).baseline;console.log("Effective policy (user + project merged):"),Jc(Z(Re,ae(pn(he).value,P.home).policy).policy,Z(Re,ae(ye.value,P.home).policy).policy,!1)}if(ee==="check")return 0;let Ie=q.input??process.stdin,Xe=q.output??process.stdout;if(!Ie.isTTY||!Xe.isTTY)return console.error("policy apply confirms interactively; run this yourself in a terminal:"),console.error(` cc-safety-net policy apply ${ce}${V.flags.global?" --global":""}`),1;if(!await Eg(`Apply this policy to ${he}? [y/N] `,Ie,Xe))return console.log("Cancelled; nothing was written."),0;return Dg(P,he,ye.value,xe,V.flags.global),console.log(`Policy applied: ${he}`),0}function Eg(P,A,q){let V=Pg({input:A,output:q,terminal:!1});return new Promise((ee)=>{V.once("close",()=>ee(!1)),V.question(P,(ne)=>{ee(/^y(es)?$/i.test(ne.trim())),V.close()})})}function Dg(P,A,q,V,ee){if(ee){Vt(P,V);return}Sg(Rg(A),{recursive:!0}),Pt(A,Vr(q,V))}function Jc(P,A,q){let V=qr(P,A,q);if(V.length===0){console.log("No changes.");return}console.log(`Changes (${V.length}):`);for(let ee of V)console.log(` ${ee.field}: ${ee.before??zc} -> ${ee.after??zc}`)}function Ag(P){return!!P&&typeof P==="object"&&!Array.isArray(P)}import{join as Bh}from"node:path";var Kc="# Custom Rules Reference\n\nAgent reference for generating CC Safety Net rulebook configuration.\n\n## Config Locations\n\n| Scope | Config path | Rulebook path | Priority |\n|-------|-------------|---------------|----------|\n| User | `~/.cc-safety-net/rules/rule.json` | `~/.cc-safety-net/rules/<rulebook-name>/rulebook.json` | First |\n| Project | `.cc-safety-net/rules/rule.json` | `.cc-safety-net/rules/<rulebook-name>/rulebook.json` | Second |\n| GitHub source | Listed in a local `rule.json` | Vendored into the consumer's `<rulebook-name>/rulebook.json` by `rule add` | Source order |\n\nEvery rulebook is a live file: the runtime reads it on each tool call, so an edit applies to the next command with no publishing step.\n\nUser scope is evaluated before project scope; within a scope, sources apply in `rules` array order. A duplicate active rulebook name keeps the first claim and ignores the later rulebook with a warning, so a user-scoped name shadows a project-scoped one.\n\nUse `cc-safety-net rule init` to create an inert local config. Use `--global` for user scope. Use `cc-safety-net rule init --example` to also create an inactive example rulebook. `CC_SAFETY_NET_HOME` overrides the `~/.cc-safety-net` user root.\n\nLegacy inline `.safety-net.json` and `~/.cc-safety-net/config.json` files are not loaded at runtime. Convert them with `cc-safety-net rule migrate`.\n\n## rule.json Schema\n\n```json\n{\n \"version\": 1,\n \"rules\": [\"project-rules\", \"owner/repo#main/team-rules\"],\n \"overrides\": {\n \"project-rules/block-docker-system-prune\": {\n \"reason\": \"Use targeted Docker cleanup commands.\"\n },\n \"team-rules/block-npm-global\": \"off\"\n },\n \"transparent_wrappers\": [\"rtk\"]\n}\n```\n\n- `version`: Required. Must be `1`.\n- `$schema`: Optional. `cc-safety-net rule verify` inserts it into a valid `rule.json` that lacks it.\n- `rules`: Optional array of rulebook source strings. Missing `rules` is treated as `[]`.\n- `overrides`: Optional object keyed by `<rulebook-name>/<rule-name>`.\n- `overrides` values are either `\"off\"` to disable a rule or an object with a required `reason` (replacement block reason) and an optional `intent` (one of `hard_stop`, `use_alternative`, `scope_down`, `manual_only`, `stop_and_explain`).\n- A project override cannot target a user-scoped rule: only that override is ignored, the user rule keeps its configured state, and `rule verify` reports the diagnostic as a failure.\n- `transparent_wrappers`: Optional array of command names that transparently execute a visible child command.\n- Transparent wrappers have no built-in defaults. Configure only wrappers you intentionally trust, such as `\"rtk\"`.\n- Use `cc-safety-net rule wrapper add rtk` to configure RTK without manually editing `rule.json`.\n\n## Rulebook Sources\n\n- Local sources are bare rulebook names such as `project-rules`; the rulebook file is `.cc-safety-net/rules/project-rules/rulebook.json`.\n- Run `cc-safety-net rule add owner/repo` to add every rulebook currently present on the repository's default branch.\n- Use `--only` to select one or more rulebooks while preserving their order: `cc-safety-net rule add owner/repo --only aws gcloud`.\n- Use `--ref` to select a branch, tag, or commit instead of the default branch: `cc-safety-net rule add owner/repo --ref v2 --only aws`.\n- GitHub sources are stored in canonical form as `owner/repo#ref/<rulebook-name>`. That form remains valid in `rule.json` and as direct CLI input.\n- GitHub refs may contain `/`-separated path segments, such as `feature/rulebook-v2`.\n- The GitHub source name, the repository directory name, and the rulebook `name` must match exactly.\n- Rulebook source strings must be unique in a config.\n\n## rulebook.json Schema\n\n```json\n{\n \"rulebook_version\": 1,\n \"name\": \"project-rules\",\n \"version\": \"1.0.0\",\n \"description\": \"Project-specific CC Safety Net rules.\",\n \"author\": \"project\",\n \"allowed_commands\": [\"docker\"],\n \"rules\": [\n {\n \"name\": \"block-docker-system-prune\",\n \"command\": \"docker\",\n \"subcommand\": \"system\",\n \"block_args\": [\"prune\"],\n \"reason\": \"Use targeted cleanup instead.\"\n }\n ],\n \"tests\": [\n {\n \"command\": \"docker system prune\",\n \"expect\": \"blocked\",\n \"rule\": \"block-docker-system-prune\"\n },\n {\n \"command\": \"docker ps\",\n \"expect\": \"allowed\"\n }\n ]\n}\n```\n\n### Rulebook Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `rulebook_version` | Yes | Must be `1` or `2` |\n| `name` | Yes | `^[a-zA-Z][a-zA-Z0-9_-]{0,63}$` |\n| `version` | Yes | Non-empty string |\n| `description` | No | Free text; not type-checked at runtime |\n| `author` | No | Free text; not type-checked at runtime |\n| `allowed_commands` | Yes | Unique command names matching `^[a-zA-Z][a-zA-Z0-9_-]*$` |\n| `rules` | Yes | Array of rule objects |\n| `tests` | No | Array of fixtures |\n\n### Rule Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `name` | Yes | Unique within the rulebook (case-insensitive); same pattern as rulebook `name` |\n| `command` | Yes | Must be listed in `allowed_commands`; basename only, not path |\n| `subcommand` | No | Same pattern as `command`; omit to match any subcommand |\n| `intent` | No | One of `hard_stop`, `use_alternative`, `scope_down`, `manual_only`, `stop_and_explain` |\n| `block_args` | Yes | Non-empty array of non-empty strings |\n| `reason` | Yes | Non-empty string, max 256 chars |\n\n### Rule Fields (`rulebook_version` 2)\n\nVersion 2 replaces `subcommand` and `block_args` with an exact-token `match` object. Version 1 rulebooks keep their fields and their behavior; a client that does not support version 2 rejects the rulebook instead of applying broader version 1 semantics.\n\n```json\n{\n \"name\": \"block-terraform-apply-destroy\",\n \"command\": \"terraform\",\n \"match\": {\n \"command_path\": [\"apply\"],\n \"any_args\": [\"-destroy\", \"--destroy\"]\n },\n \"reason\": \"Review a destroy plan first with 'terraform plan -destroy'.\",\n \"intent\": \"use_alternative\"\n}\n```\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `name` | Yes | Same as version 1 |\n| `command` | Yes | Same as version 1 |\n| `match.command_path` | Yes | Non-empty array of non-empty command words |\n| `match.any_args` | No | Non-empty array of unique non-empty argument tokens |\n| `match.exclude_args` | No | Non-empty array of unique non-empty argument tokens |\n| `intent` | No | Same as version 1 |\n| `reason` | Yes | Same as version 1 |\n\n### Matching Behavior (`rulebook_version` 2)\n\n- **Command**: Normalized to lowercase basename, as in version 1.\n- **Command path**: After recognized global options and their values are skipped, the next command words must equal `command_path` exactly. AWS, gcloud, and Azure CLI value-taking global options are built in; Terraform's `-chdir=dir` is `=`-joined and is skipped with its own token.\n- **Unrecognized options**: A token starting with `-` that is not a recognized global option is skipped without consuming a value, so an unlisted value-taking option with a separate value (`--newflag value`) makes the rule miss. This fails open deliberately; document such gaps in the rulebook.\n- **`any_args`**: At least one listed token must appear literally among the arguments.\n- **`exclude_args`**: Any listed token appearing literally among the arguments prevents the match, which is how a safe preview such as `aws s3 rm --dryrun` stays allowed.\n- **No short-option expansion**: Arguments compare as exact tokens, so list every accepted spelling (`\"-destroy\"` and `\"--destroy\"`).\n- **Literal and case-sensitive**: No regex, glob, or substring matching. The first matching rule wins.\n- Release channels are separate rules: `gcloud beta compute instances delete` needs its own `command_path`.\n\n### Test Fixture Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `command` | Yes | Non-empty shell command string |\n| `expect` | Yes | `\"blocked\"` or `\"allowed\"` |\n| `rule` | Required for blocked fixtures | Rule name expected to block the command |\n\nFixtures are optional documentation of intended behavior. Version 1 fixtures are shape-validated only. Version 2 fixtures are evaluated against the rulebook's own rules when a source is fetched by `rule add` or `rule update`, and by `rule verify`; a failing fixture rejects that source before it is written. Loading a rulebook does not re-evaluate fixtures. CC Safety Net never executes fixture commands; they are analyzer inputs only.\n\n## Matching Behavior\n\nThe subcommand, argument, and option rules below describe `rulebook_version` 1 rules; version 2 rules match as described in Matching Behavior (`rulebook_version` 2). Execution order and transparent wrappers apply to both.\n\n- **Command**: Normalized to lowercase basename with any trailing `.exe` removed (`/usr/bin/git` → `git`).\n- **Subcommand**: The first command token after recognized Git and Docker global options and their values; `--` ends option parsing. An unrecognized option without `=` may consume the following token as its value.\n- **Arguments**: Each `block_args` value is compared literally against every command token, including expanded short options. The command is blocked if **any** item matches.\n- **Short options**: Expanded (`-Ap` matches `-A`).\n- **Long options**: Exact match (`--all-files` does not match `--all`).\n- **Execution order**: Built-in rules first, then custom rulebooks. Custom rules only add restrictions.\n- **Transparent wrappers**: A configured wrapper such as `rtk` lets `rtk git commit` be analyzed as `git commit` only when `git` is protected by built-in analyzers or active custom rules. `rtk -- git commit` is also supported.\n\n## Workflow\n\n1. Run `cc-safety-net rule init` or create `rule.json` manually.\n2. Optionally run `cc-safety-net rule init --example` to create an inactive example rulebook.\n3. Use `cc-safety-net rule wrapper add rtk` for trusted transparent wrappers.\n4. Run `cc-safety-net rule add <source>` after creating or choosing a rulebook source; add `--only <rulebook...>` or `--ref <ref>` for repository selection. The command adds the selected sources and syncs them.\n5. Edit a local rulebook whenever you like: the edit is enforced on the next command, so there is nothing to run afterwards.\n6. Run `cc-safety-net rule update [source]` to re-fetch remote sources and rewrite the vendored copies; the command prints what changed. A source with an ordinary update failure keeps its vendored copy while the other selected sources still update. Resource-limit failures remain fatal for the whole update.\n7. Run `cc-safety-net rule verify` to validate config, local rulebooks, and shareable GitHub-source rulebook directories in the current repository (it does not fetch remote content).\n8. Run `cc-safety-net rule list` to inspect active rulebooks and transparent wrappers.\n\nA missing or invalid rulebook file makes that source inactive, and an unreadable or invalid `rule.json` makes every source in its scope inactive. Inactive sources stop applying their rules while other custom rules and all built-in protections stay active. Fix the file named in the diagnostic, or run `cc-safety-net rule update` when a remote source has not been vendored yet. Run `cc-safety-net status` to see degraded sources.\n";function zr(P,A){if(!P.ok){ed(P);return}Zc(P,A)}function Xc(P,A,q){if(P.ok)console.log(q);if(!P.add){zr(P,`Added rulebook source: ${A}`);return}if(!P.ok){ed(P);return}if(P.add.added.length>0)console.log(`Added ${P.add.added.length} ${P.add.added.length===1?"rulebook":"rulebooks"} from ${P.add.source} at ${P.add.ref}:`),P.add.added.forEach((V)=>{console.log(` - ${V}`)});if(P.add.alreadyConfigured.length>0)console.log(`Rulebooks already configured from ${P.add.source} at ${P.add.ref}: ${P.add.alreadyConfigured.join(", ")}`);if(P.add.commits.length>0)console.log(`Vendored at ${P.add.commits.map((V)=>V.slice(0,7)).join(", ")}.`);Zc(P,"Rule config updated.")}function Zc(P,A){for(let q of P.changes??[])console.log(q);console.log(A),console.log(""),_g(P.entries)}function _g(P){if(P.length===0){console.log("Active rulebooks: (none)");return}console.log(`Active rulebooks (${P.length}):`);for(let A of P)console.log(` - ${A.name} ${A.version} (${Tg(A.ruleCount)})`),console.log(` Source: ${A.spec}`)}function Tg(P){return`${P} ${P===1?"rule":"rules"}`}function Qc(P){fn("Active sources",P.rulebooks,(A)=>[`[${A.source}] ${A.name} ${A.version}`,` Source: ${A.spec}`]),fn("Active rules",P.rules,(A)=>[`[${$g(P,A.name)}] ${A.name}`,...Ig(A),` Reason: ${A.reason}`]),fn("Disabled rules",Yc(P,"off"),(A)=>[A.key]),fn("Reason overrides",Yc(P,"reason"),(A)=>[A.key,` Reason: ${A.value.reason}`]),fn("Transparent wrappers",P.transparent_wrappers,(A)=>[A]),fn("Issues",P.errors,(A)=>[A]),fn("Warnings",P.warnings,(A)=>[A])}function fn(P,A,q){if(A.length===0){console.log(`${P}: (none)`);return}console.log(`${P} (${A.length}):`);for(let V of A){let[ee,...ne]=q(V);console.log(` - ${ee}`);for(let ce of ne)console.log(` ${ce}`)}}function Ig(P){if(!P.match)return[` Command: ${P.subcommand?`${P.command} ${P.subcommand}`:P.command}`,` Block args: ${P.block_args.join(", ")}`];return[` Command: ${[P.command,...P.match.command_path].join(" ")}`,...P.match.any_args?[` Any args: ${P.match.any_args.join(", ")}`]:[],...P.match.exclude_args?[` Exclude args: ${P.match.exclude_args.join(", ")}`]:[]]}function $g(P,A){return P.rulebooks.find((q)=>q.rules.includes(A))?.source??"project"}function Yc(P,A){return Object.entries({...P.userConfig?.overrides,...P.projectConfig?.overrides}).filter((q)=>{if(A==="off")return q[1]==="off";return!!q[1]&&typeof q[1]==="object"}).map(([q,V])=>({key:q,value:V}))}function ed(P){for(let A of P.errors)console.error(A)}import{dirname as xd,join as eo}from"node:path";import{join as Ai,resolve as zg}from"node:path";function Ri(P){let A=m(P);if(A.errors.length>0)return{ok:!1,result:{ok:!1,errors:A.errors,entries:[]}};return{ok:!0,config:A.config??it}}function td(P){Pt(P,{version:1,rules:[],overrides:{},transparent_wrappers:[]})}function nd(P){Pt(P,{rulebook_version:1,name:"example-rules",version:"1.0.0",description:"Project-specific CC Safety Net rules.",author:"project",allowed_commands:["docker"],rules:[{name:"block-docker-system-prune",command:"docker",subcommand:"system",block_args:["prune"],reason:"Use targeted cleanup instead."}],tests:[{command:"docker system prune",expect:"blocked",rule:"block-docker-system-prune"}]})}import{dirname as Yr}from"node:path";var Og="custom.";function Jr(P){if(P.rulebook_version!==2)return[];let A=P.rules.map((q)=>({name:q.name,command:q.command,block_args:[],match:q.match,reason:q.reason,intent:q.intent}));return(P.tests??[]).flatMap((q,V)=>{let ee=Pi(h(q.command));if(ee.length===0)return[`tests[${V}]: could not parse fixture command: ${q.command}`];let ne=ee.reduce((ce,he)=>ce??_(he,A)?.id.slice(Og.length),void 0);if(q.expect==="blocked"){if(ne===q.rule)return[];let ce=ne?`"${ne}" matched first`:"no rule matched";return[`tests[${V}]: expected "${q.rule}" to block "${q.command}" but ${ce}`]}return ne?[`tests[${V}]: expected "${q.command}" to be allowed but "${ne}" matched`]:[]})}function Pi(P){return P.nodes.flatMap((A)=>{if(A.kind==="group"||A.kind==="function")return Pi(A.body);if(A.kind!=="command")return[];let q=ge(Q(A.dialect,A.words)).words.map(t);return[...q.length>0?[q]:[],...A.nested.flatMap((V)=>Pi(V))]})}var Wr=Object.freeze({concurrency:4,maxRequests:131,maxResponseBytes:67108864});function Kr(P={}){return{requests:0,responseBytes:0,maxRequests:P.maxRequests??Wr.maxRequests,maxResponseBytes:P.maxResponseBytes??Wr.maxResponseBytes}}function zt(P){return{controller:new AbortController,budget:Kr(),resolveUrl:P}}function rd(P){return P instanceof Error&&P.message==="Rule synchronization exceeds CC Safety Net's safe resource limits."}function od(P){if(P.requests>=P.maxRequests)throw Error("Rule synchronization exceeds CC Safety Net's safe resource limits.");P.requests++}function id(P,A){if(A>P.maxResponseBytes-P.responseBytes)throw P.responseBytes+=A,Error("Rule synchronization exceeds CC Safety Net's safe resource limits.");P.responseBytes+=A}var ld=Object.freeze({timeoutMs:15000,metadataBytes:524288,commitBytes:262144,treeBytes:16777216,rawBytes:4194304});async function sd(P,A,q=v(Yr(Yr(A)),"rules policy"),V=zt()){if(S(P))return Mg(P,V);return jg(P,A,q)}async function cd(P,A,q,V,ee,ne){if(!S(P))return sd(P,A,q,V);let ce=ee?null:Fg(P,A,q);if(ce)return ce;if(!ee&&!ne)throw Error(`${P} is not vendored; run rule update ${P} to vendor it`);return sd(P,A,q,V)}function Fg(P,A,q=v(Yr(Yr(A)),"rules policy")){let V=I(P),ee=O(A,V.name),ne=n(i(q,ee));if(ne===null)return null;let ce=se(Ei(ne,`Invalid rulebook ${ee}.`));if(ce.name!==V.name)throw Error(`rulebook name "${ce.name}" in ${ee} must match "${V.name}"`);return{spec:P,rulebook:ce,content:ne}}async function dd(P,A={}){if(!K(P))throw Error(`Invalid GitHub repository source: ${P}`);let[q,V]=P.split("/");if(!q||!V)throw Error(`Invalid GitHub repository source: ${P}`);if(A.ref!==void 0&&!oe(A.ref))throw Error(`GitHub rulebook refs must use valid path segments: ${A.ref}`);let ee=A.operation??zt(),ne=A.ref??await Ng(q,V,P,ee),ce=await pd(q,V,ne,P,ee),he=await Xr(`https://api.github.com/repos/${q}/${V}/git/trees/${ce}?recursive=1`,"tree",ee),ye=he.response;if(!ye.ok)throw Error(`Failed to inspect ${P}: GitHub tree returned ${ye.status}`);let be=JSON.parse(he.content);if(!Array.isArray(be?.tree))throw Error(`Failed to inspect ${P}: unexpected GitHub tree response`);let xe=be.tree,Ie=[...new Set(xe.flatMap((Xe)=>{if(!Xe||typeof Xe!=="object")return[];let et=Xe;if(et.type!=="blob"||typeof et.path!=="string")return[];let Re=et.path.match(rt);return Re?.[1]?[Re[1]]:[]}))].sort();if(Ie.length===0)throw Error(`No rulebooks found in ${P} under ${de}/`);return{source:P,owner:q,repo:V,ref:ne,commit:ce,names:Ie}}async function Ng(P,A,q,V){let ee=await Xr(`https://api.github.com/repos/${P}/${A}`,"metadata",V),ne=ee.response;if(!ne.ok)throw Error(`Failed to inspect ${q}: GitHub returned ${ne.status}`);let he=JSON.parse(ee.content)?.default_branch;if(typeof he!=="string"||he==="")throw Error(`Failed to inspect ${q}: missing default branch`);if(!oe(he))throw Error(`GitHub returned an invalid default branch: ${he}`);return he}function jg(P,A,q){ot(P);let V=O(A,P),ee=n(i(q,V));if(ee===null)throw Error(`Rulebook source not found: ${P}`);let ne=ud(Ei(ee,"Invalid local rulebook source."));if(ne.name!==P)throw Error(`rulebook name "${ne.name}" must match local source "${P}"`);return{spec:P,rulebook:ne,content:ee}}async function Mg(P,A){let q=I(P),V=await pd(q.owner,q.repo,q.ref,P,A),ee=await Xr(`https://raw.githubusercontent.com/${q.owner}/${q.repo}/${V}/${q.path}`,"raw",A),ne=ee.response;if(!ne.ok)throw Error(`Failed to fetch ${P}: GitHub raw returned ${ne.status}`);let ce=ee.content,he=ud(Ei(ce,"Invalid GitHub rulebook response."));if(he.name!==q.name)throw Error(`rulebook name "${he.name}" must match GitHub source "${q.name}"`);return{spec:P,rulebook:he,content:ce}}function ud(P){let A=se(P),q=Jr(A);if(q.length>0)throw Error(q.join("; "));return A}function Ei(P,A){try{return JSON.parse(P)}catch{throw Error(A)}}async function pd(P,A,q,V,ee){let ne=await Xr(`https://api.github.com/repos/${P}/${A}/commits/${encodeURIComponent(q)}`,"commit",ee),ce=ne.response;if(!ce.ok)throw Error(`Failed to resolve ${V}: GitHub returned ${ce.status}`);let he=JSON.parse(ne.content);if(typeof he?.sha!=="string"||he.sha==="")throw Error(`Failed to resolve commit for ${V}`);return he.sha}async function Hg(P,A,q={}){if(q.signal?.aborted)throw q.signal.reason;let V=q.budget??Kr(),ee=new AbortController,ne=()=>ee.abort(q.signal?.reason);q.signal?.addEventListener("abort",ne,{once:!0});let ce=!1,he=setTimeout(()=>{if(ee.signal.aborted)return;ce=!0,ee.abort()},q.timeoutMs??ld.timeoutMs);try{if(q.signal?.aborted)throw q.signal.reason;od(V);let ye=await fetch(P,{signal:ee.signal,redirect:"error"});if(!ye.ok)return fd(ye),{response:ye,content:""};return{response:ye,content:await Ug(ye,A,V,()=>ee.abort())}}catch(ye){if(ce)throw Error("GitHub request timed out",{cause:ye});if(q.signal?.aborted)throw q.signal.reason;throw ye}finally{clearTimeout(he),q.signal?.removeEventListener("abort",ne)}}function Xr(P,A,q){return Hg(q.resolveUrl?.(P)??P,A,{budget:q.budget,signal:q.controller.signal})}async function Ug(P,A,q=Kr(),V){let ee=ld[`${A}Bytes`],ne=Number(P.headers.get("content-length"));if(Number.isFinite(ne)&&ne>ee)throw fd(P),Error(`GitHub ${A} response exceeds ${ee} bytes`);if(!P.body)return"";let ce=P.body.getReader(),he=[],ye=0;while(!0){let be=await ce.read();if(be.done)break;try{id(q,be.value.byteLength)}catch(xe){throw V?.(),ad(ce),xe}if(ye+=be.value.byteLength,ye>ee)throw V?.(),ad(ce),Error(`GitHub ${A} response exceeds ${ee} bytes`);he.push(Buffer.from(be.value))}return Buffer.concat(he,ye).toString("utf-8")}function fd(P){if(!P.body)return;md(()=>P.body?.cancel())}function ad(P){md(()=>P.cancel())}function md(P){try{Promise.resolve(P()).catch(()=>{})}catch{}}var Gg=/^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)#(.+)$/;function gd(P,A){let q=vd(P.rules,A);if(q.length>0)return{ok:!0,specs:q};return yd(P.rules,A)}function hd(P,A){let q=vd(P,A);if(q.length>0)return{ok:!0,specs:q};let V=qg(P,A);if(V.length>0)return{ok:!0,specs:V};let ee=Vg(P,A);if(!ee.ok)return ee;if(ee.specs.length>0)return{ok:!0,specs:ee.specs};return yd(P,A)}function yd(P,A){let q=P.filter((V)=>Di(V)?.name===A);if(q.length===1)return{ok:!0,specs:q};return Bg(A,q)}function Bg(P,A){return{ok:!1,result:{ok:!1,errors:A.length===0?[`No configured rulebook matches ${P}`]:[`Ambiguous rulebook match ${P}: ${A.join(", ")}`],entries:[]}}}function vd(P,A){return P.filter((q)=>q===A)}function qg(P,A){let q=A.match(Gg),V=q?.[1],ee=q?.[2],ne=q?.[3];if(!V||!ee||!ne||!oe(ne))return[];return bd(P,(ce)=>ce.owner===V&&ce.repo===ee&&ce.ref===ne)}function Vg(P,A){if(!K(A))return{ok:!0,specs:[]};let[q,V]=A.split("/"),ee=bd(P,(ce)=>ce.owner===q&&ce.repo===V);if(new Set(ee.map((ce)=>Di(ce)?.ref).filter((ce)=>!!ce)).size<2)return{ok:!0,specs:ee};return{ok:!1,result:{ok:!1,errors:[`Multiple refs are configured for ${A}. Use an explicit ref:`,` cc-safety-net rule remove ${A}#<ref>`],entries:[]}}}function Di(P){try{return I(P)}catch{return null}}function bd(P,A){return P.filter((q)=>{let V=Di(q);return V?A(V):!1})}async function Qr(P,A={}){let q=_i(A);return Jg(P,q,await Zr(P,q,zt()))}function Jg(P,A,q){if(!q.ok)return q;let V=Et(P,A),ee=[...new Set(U(V.configPath,V.filesystemScope))];if(ee.length===0)return q;return{ok:!1,errors:ee,entries:q.entries}}async function Zr(P,A,q,V={},ee=new Set,ne=new Set){try{let ce=Et(P,A),he=Ri(ce.configTarget);if(!he.ok)return he.result;let ye=he.config,be=A.only?gd(ye,A.only):{ok:!0,specs:ye.rules};if(!be.ok)return be.result;let xe=new Set([...A.refresh?be.specs:[],...ee]),Ie=(ut)=>cd(ut,ce.configDir,ce.filesystemScope,q,xe.has(ut),!A.refresh||xe.has(ut)),Xe=await oh(ye.rules,A.refresh?(ut)=>Ie(ut).then((vt)=>({ok:!0,item:vt})).catch((vt)=>{if(rd(vt))throw vt;return{ok:!1,spec:ut,message:vt instanceof Error?vt.message:String(vt)}}):async(ut)=>({ok:!0,item:await Ie(ut)}),q),et=Xe.filter((ut)=>!ut.ok),Re=Xe.filter((ut)=>ut.ok).map((ut)=>ut.item),at=Re.flatMap((ut)=>Wg(ut,ye.rules)),ct=Re.flatMap((ut)=>Kg(ut,ne,ce)),lt=new Set([...at,...ct].map((ut)=>ut.spec)),ft=[...et,...at,...ct],mt=[],gt=Xg(mt,()=>Re.flatMap((ut)=>lt.has(ut.spec)||ft.length>0&&ne.has(ut.spec)?[]:Yg(ut,ce,V,mt)));return{ok:ft.length===0,errors:ft.map((ut)=>`Failed to update ${ut.spec}: ${ut.message}`),entries:Re.map(Qg),changes:gt}}catch(ce){return Qn(ce)}}function Wg(P,A){if(!S(P.spec))return[];let q=Pe(P.spec),V=A.filter((ee)=>ee!==P.spec&&Pe(ee).toLowerCase()===q.toLowerCase());if(V.length===0)return[];return[{ok:!1,spec:P.spec,message:`rulebook name "${q}" is also claimed by ${V.join(", ")}; rename one of them`}]}function Kg(P,A,q){if(!A.has(P.spec)||!S(P.spec))return[];let V=O(q.configDir,P.rulebook.name),ee=n(i(q.filesystemScope,V));if(ee===null||ee===P.content)return[];return[{ok:!1,spec:P.spec,message:`${V} already exists and no configured source claims it; remove or rename the file, then re-run rule add`}]}function Yg(P,A,q,V){if(!S(P.spec))return[];let ee=O(A.configDir,P.rulebook.name),ne=i(A.filesystemScope,ee),ce=n(ne);if(ce===P.content)return[];return V?.push({target:ne,previous:ce}),g(ne,P.content,void 0,q._testAfterPolicyRename),Zg(P,ce)}function Xg(P,A){try{return A()}catch(q){for(let V of[...P].reverse()){if(V.previous===null){F(V.target);continue}g(V.target,V.previous)}throw q}}function Zg(P,A){if(A===null)return[`Vendored ${P.spec} (${P.rulebook.version})`];let q=me(A),V="problem"in q?null:q.rulebook,ee=new Map(V?.rules.map((ce)=>[ce.name,JSON.stringify(ce)])??[]),ne=new Set(P.rulebook.rules.map((ce)=>ce.name));return[`Updated ${P.spec} (${V?.version??"unreadable"} -> ${P.rulebook.version})`,...[...ne].filter((ce)=>!ee.has(ce)).map((ce)=>` + ${ce}`),...[...ee.keys()].filter((ce)=>!ne.has(ce)).map((ce)=>` - ${ce}`),...P.rulebook.rules.filter((ce)=>{let he=ee.get(ce.name);return he!==void 0&&he!==JSON.stringify(ce)}).map((ce)=>` ~ ${ce.name}`)]}function Qg(P){return{spec:P.spec,name:P.rulebook.name,version:P.rulebook.version,ruleCount:P.rulebook.rules.length}}async function Ld(P,A,q={}){return eh(P,A,sh(q),zt())}async function eh(P,A,q,V,ee={}){let ne=null,ce=!1;try{let he=Et(P,q),ye=n(he.configTarget);ne={target:he.configTarget,content:ye};let be=Ri(he.configTarget);if(!be.ok)return be.result;let xe=be.config,Ie=K(A);th(A,q,Ie);let Xe=Ie?await dd(A,{ref:q.ref,operation:V}):null,et=Xe?nh(Xe,q.rulebooks):[],Re=Xe?et.map((mt)=>rh(xe.rules,Xe,mt)??`${A}#${Xe.ref}/${mt}`):[A],at=Re.filter((mt)=>!xe.rules.includes(mt)),ct=[...xe.rules,...at];if(ct.length>pe)return ih();if(ct.length!==xe.rules.length)ce=!0,Pt(he.configTarget,{version:1,rules:ct,overrides:xe.overrides??{},transparent_wrappers:xe.transparent_wrappers??[]},void 0,ee._testAfterPolicyRename);let lt=await Zr(P,q,V,ee,new Set(at),new Set(at));if(!lt.ok)Zn(he.configTarget,ye);if(!lt.ok||!Xe)return lt;let ft=et.filter((mt,gt)=>at.includes(Re[gt]??""));return{...lt,add:{source:A,ref:Xe.ref,selected:et,added:ft,alreadyConfigured:et.filter((mt)=>!ft.includes(mt)),commits:at.length>0?[Xe.commit]:[]}}}catch(he){if(ce&&ne)try{Zn(ne.target,ne.content)}catch(ye){return Qn(ye)}return Qn(he)}}function th(P,A,q){if(!q&&A.rulebooks!==void 0)throw Error("--only can only select rulebooks from an owner/repo source");if(!q&&A.ref)throw Error(`--ref can only select a ref for an owner/repo source: ${P}`);if(A.rulebooks?.length===0)throw Error("--only requires at least one rulebook name");let V=A.rulebooks?.filter((ee)=>!l.test(ee))??[];if(V.length>0)throw Error(`Invalid rulebook names: ${V.join(", ")}`)}function nh(P,A){let q=A?[...new Set(A)]:P.names,V=q.filter((ee)=>!P.names.includes(ee));if(V.length>0)throw Error(`Rulebooks not found in ${P.source} at ${P.ref}: ${V.join(", ")}
273
- Available rulebooks: ${P.names.join(", ")}`);return q}function rh(P,A,q){let V=`${A.source}#${A.ref}/${q}`;if(P.includes(V))return V;let ee=`${A.source}#${A.commit}/${q}`;return P.find((ne)=>ne===ee)}async function oh(P,A,q=zt()){if(P.length>pe)throw Error(fe);let V=[],ee=0,ne,ce=Array.from({length:Math.min(P.length,Wr.concurrency)},async()=>{while(!ne){let he=ee;if(he>=P.length)return;ee++;try{V[he]=await A(P[he],he,q.controller.signal)}catch(ye){if(!ne)ne={value:ye},ee=P.length,q.controller.abort(ye);return}}});if(await Promise.all(ce),ne)throw ne.value;return V}function ih(){return{ok:!1,errors:[fe],entries:[]}}function _i(P){return{cwd:P.cwd,userConfigDir:P.userConfigDir,userConfigPath:P.userConfigPath,projectConfigPath:P.projectConfigPath,global:P.global,only:P.only,refresh:P.refresh}}function sh(P){return{..._i(P),ref:P.ref,rulebooks:P.rulebooks}}function ah(P){return{..._i(P),deleteSource:P.deleteSource}}async function wd(P,A,q={}){try{return await lh(P,A,ah(q),{})}catch(V){return Qn(V)}}async function lh(P,A,q,V){let ee=Et(P,q),ne=m(ee.configTarget);if(ne.errors.length>0)return{ok:!1,errors:ne.errors,entries:[]};if(!ne.config)return{ok:!1,errors:[`No config found at ${ee.configPath}`],entries:[]};let ce=hd(ne.config.rules,A);if(!ce.ok)return ce.result;let he=q.deleteSource?ch(ee.configDir,ce.specs,ee.filesystemScope):{ok:!0,dirs:[]};if(!he.ok)return he.result;let ye=n(ee.configTarget);if(ye===null)return Qn(Error("Rules config is unavailable."));try{Pt(ee.configTarget,{version:1,rules:ne.config.rules.filter((Ie)=>!ce.specs.includes(Ie)),overrides:ne.config.overrides??{},transparent_wrappers:ne.config.transparent_wrappers??[]},void 0,V._testAfterPolicyRename)}catch(Ie){throw Zn(ee.configTarget,ye),Ie}let be=await Zr(P,q,zt(),V);if(!be.ok)return Zn(ee.configTarget,ye),be;let xe=dh(he.dirs,V,ee.filesystemScope);if(!xe.ok){Zn(ee.configTarget,ye);let Ie=await Zr(P,q,zt(),V);if(!Ie.ok)return{ok:!1,errors:[...xe.result.errors,...Ie.errors],entries:Ie.entries};return xe.result}return be}function ch(P,A,q){let V=A.flatMap((he)=>l.test(he)?[]:["--delete-source can only delete local rulebook sources"]),ee=A.map((he)=>Ai(P,he)),ne=V.length>0?[]:ee.flatMap((he)=>kd(he,q)),ce=[...V,...ne];return ce.length>0?{ok:!1,result:{ok:!1,errors:ce,entries:[]}}:{ok:!0,dirs:ee}}function kd(P,A){let q=zg(P),V=i(A,q),ee=le(V);if(!ee)return[`Local rulebook source directory not found: ${P}`];let ne=ee.find((ce)=>ce.name==="rulebook.json");if(!ne)return[`Local rulebook source directory is missing rulebook.json: ${P}`];if(ne.kind!=="file")throw new r(A.label);if(n(i(A,Ai(q,"rulebook.json"))),ee.length>1)return[`Local rulebook source directory contains extra files: ${P}. delete manually if you really want to remove the directory.`];return[]}function dh(P,A,q){let V=P.flatMap((ee)=>{try{if(!le(i(q,ee)))return[];let ne=kd(ee,q);if(ne.length>0)return ne;return uh(ee,A,q),[]}catch(ne){return[`Failed to delete local rulebook source ${ee}: ${ne instanceof Error?ne.message:String(ne)}`]}});return V.length>0?{ok:!1,result:{ok:!1,errors:V,entries:[]}}:{ok:!0}}function uh(P,A,q){if(A._testDeleteLocalSourceDir){A._testDeleteLocalSourceDir(P);return}F(i(q,Ai(P,ue))),nt(i(q,P))}function Zn(P,A){if(A===null){F(P);return}g(P,A)}function Qn(P){return{ok:!1,errors:[P instanceof Error?P.message:String(P)],entries:[]}}var ph=".safety-net.json",fh="~/.cc-safety-net/config.json";async function Rd(P,A){return[await Cd(P,{legacyPath:Hs({cwd:A.cwd}),configPath:M(A.cwd),defaultRulebookName:"project-rules",migratedFrom:ph,cleanup:A.cleanup,syncOptions:{cwd:A.cwd}}),await Cd(P,{legacyPath:lr(P),configPath:j(P),defaultRulebookName:"user-rules",migratedFrom:fh,cleanup:A.cleanup,syncOptions:{cwd:A.cwd,global:!0}})].every((V)=>V)?0:1}async function Cd(P,A){let q=Et(P,A.syncOptions),V=i(q.filesystemScope,A.legacyPath),ee=n(V);if(ee===null)return console.log(`No legacy config found at ${A.legacyPath}`),!0;let ne=gh(ee);if(!ne.ok){for(let et of ne.errors)console.error(et);return!1}let ce=m(q.configTarget);if(ce.errors.length>0){for(let et of ce.errors)console.error(et);return!1}let he=ce.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},ye=hh(xd(A.configPath),he.rules,A.defaultRulebookName,A.migratedFrom,q.filesystemScope),be=eo(xd(A.configPath),ye,"rulebook.json"),xe=i(q.filesystemScope,be),Ie=[Sd(q.configTarget),Sd(xe)],Xe=await mh(P,A,q.configTarget,xe,ye,ne.config.rules,he.rules.includes(ye)?he.rules:[...he.rules,ye],he.overrides??{},he.transparent_wrappers??[]);if(!Xe.ok){bh(Ie);for(let et of Xe.errors)console.error(et);return!1}if(!A.cleanup)return console.log(`Migrated legacy config at ${A.legacyPath}. Legacy file is no longer used.`),!0;if(!vh(q.configTarget,xe,ye,A.migratedFrom,ne.config.rules))return console.error(`Migration cleanup verification failed for ${A.legacyPath}`),!1;return F(V),console.log(`Deleted legacy config at ${A.legacyPath}`),!0}async function mh(P,A,q,V,ee,ne,ce,he,ye){try{return Pt(q,{version:1,rules:ce,overrides:he,transparent_wrappers:ye}),Pt(V,yh(ee,A.migratedFrom,ne)),await Qr(P,A.syncOptions)}catch(be){return{ok:!1,errors:[be instanceof Error?be.message:String(be)]}}}function gh(P){try{let A=JSON.parse(P),q=uo(A);if(q.errors.length>0)return{ok:!1,errors:q.errors};return{ok:!0,config:{version:1,rules:A.rules??[]}}}catch{return{ok:!1,errors:["Invalid JSON"]}}}function hh(P,A,q,V,ee){let ne=A.find((ce)=>Lh(i(ee,eo(P,ce,"rulebook.json")))===V);if(ne)return ne;if(n(i(ee,eo(P,q,"rulebook.json")))===null)return q;for(let ce=2;;ce++){let he=`${q}-${ce}`;if(n(i(ee,eo(P,he,"rulebook.json")))===null)return he}}function yh(P,A,q){return{rulebook_version:1,name:P,version:"1.0.0",description:"Migrated CC Safety Net rules.",author:"project",migrated_from:A,allowed_commands:[...new Set(q.map((V)=>V.command))],rules:q,tests:q.map((V)=>({command:[V.command,V.subcommand,V.block_args[0]].filter(Boolean).join(" "),expect:"blocked",rule:V.name}))}}function vh(P,A,q,V,ee){if(!m(P).config?.rules.includes(q))return!1;try{let ce=n(A);if(ce===null)return!1;let he=JSON.parse(ce);return he.migrated_from===V&&JSON.stringify(he.rules)===JSON.stringify(ee)}catch{return!1}}function Sd(P){return{target:P,content:n(P)}}function bh(P){for(let A of P){if(A.content===null){F(A.target);continue}g(A.target,A.content)}}function Lh(P){let A=n(P);if(A===null)return null;try{let q=JSON.parse(A);return typeof q.migrated_from==="string"?q.migrated_from:null}catch{return null}}import{mkdir as wh,readFile as kh,writeFile as xh}from"node:fs/promises";import{dirname as Ch,join as Sh}from"node:path";var Rh=86400000,Ph=604800000;async function Ed(P,A=Date.now()){if(P.env.get("CC_SAFETY_NET_NO_UPDATE_CHECK"))return null;let q=je(P);if(!q)return null;let V=Sh(q,".cc-safety-net","update-check.json"),ee=await Eh(V,A);if(!ee.lastCheck||A-ee.lastCheck>Rh){let he=await Wt();if(ee.lastCheck=A,he.latestVersion)ee.latestVersion=he.latestVersion;if(!await Pd(V,ee))return null;if(he.error)return null}let ne=ee.latestVersion,ce=wt();if(!ne||!yo(ne,ce))return null;if(ee.notifiedVersion===ne&&ee.notifiedAt!==void 0&&A-ee.notifiedAt<Ph)return null;if(ee.notifiedVersion=ne,ee.notifiedAt=A,!await Pd(V,ee))return null;return`UPDATE_AVAILABLE: cc-safety-net v${ne} is available (running v${ce}). Ask the user once whether to run \`npx -y cc-safety-net@latest update\`; continue the current task either way and do not raise this again.`}async function Eh(P,A){let q=await kh(P,"utf8").then((ne)=>JSON.parse(ne)).catch(()=>{return});if(!q||typeof q!=="object"||Array.isArray(q))return{};let V=q,ee=(ne)=>typeof ne==="number"&&Number.isFinite(ne)&&ne<=A?ne:void 0;return{lastCheck:ee(V.lastCheck),latestVersion:typeof V.latestVersion==="string"?V.latestVersion:void 0,notifiedVersion:typeof V.notifiedVersion==="string"?V.notifiedVersion:void 0,notifiedAt:ee(V.notifiedAt)}}async function Pd(P,A){return wh(Ch(P),{recursive:!0,mode:448}).then(()=>xh(P,JSON.stringify(A),{mode:384})).then(()=>!0).catch(()=>!1)}import{join as Dh,resolve as Ti}from"node:path";var Dd="CC Safety Net Config",Ah="═".repeat(Dd.length),_h="https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json",Th=new Set(["rule.json","rule.lock","cache"]);function Ad(P,A={}){try{return Ih(P,A)}catch(q){if(q instanceof r)return console.error(q.message),1;throw q}}function Ih(P,A){let q=A.cwd??process.cwd(),V=J(P,{cwd:q}),ee=lr(P),ne=cs(q),ce=Ti(q,de),he=i(V.userScope,ee),ye=i(V.projectScope,ne),be=!1,xe=!1,Ie=[],Xe=[],et=$h(i(V.projectScope,ce));if(Fh(),n(V.userConfigTarget)!==null){let Re=Jt(V.userConfigTarget);if(Re.errors.push(...U(V.userConfigPath,V.userScope)),Ie.push({scope:"User",path:V.userConfigPath,result:Re,schema:"rules",target:V.userConfigTarget}),Re.errors.length>0)be=!0}if(n(he)!==null)if(xe=!0,n(V.userConfigTarget)!==null)Xe.push(to("user","cleanup"));else{let Re=po(he);if(Ie.push({scope:"User",path:ee,result:Re,schema:"legacy",inactive:!0,target:he}),Xe.push(to("user",Re.errors.length>0?"fix-or-delete":"migrate")),Re.errors.length>0)be=!0}if(n(V.projectConfigTarget)!==null){let Re=Jt(V.projectConfigTarget);if(Re.errors.push(...U(V.projectConfigPath,V.projectScope)),Ie.push({scope:"Project",path:Ti(V.projectConfigPath),result:Re,schema:"rules",target:V.projectConfigTarget}),Re.errors.length>0)be=!0;if(n(ye)!==null)xe=!0,Xe.push(to("project","cleanup"))}else if(n(ye)!==null){xe=!0,be=!0;let Re=po(ye);Ie.push({scope:"Project",path:Ti(ne),result:Re,schema:"legacy",inactive:!0,target:ye}),Xe.push(to("project",Re.errors.length>0?"fix-or-delete":"migrate"))}if(et?.result.errors.length)be=!0;if(Ie.length===0&&!et)return console.log(`
274
- No config files found. Using built-in rules only.`),0;for(let Re of Ie)if(Re.inactive)jh(Re.scope,Re.path,Re.result);else if(Re.result.errors.length>0)Mh(Re.scope,Re.path,Re.result.errors);else{if(Re.schema==="rules"&&Gh(Re.target))console.log(`
275
- Added $schema to ${Re.scope.toLowerCase()} config.`);Nh(Re.scope,Re.path,Re.result,Re.schema)}for(let Re of Xe)console.error(`
276
- ${dt.red(Re)}`);if(et)if(et.result.errors.length>0)Uh(et.path,et.result.errors);else Hh(et.path,et.result);if(be)return console.error(`
277
- Config validation failed.`),1;return console.log(xe?`
261
+ `)}function Zc(_,I){return I.map((O)=>_==="install"&&O.target==="kimi-code"&&O.unavailableReason==="already installed"?{...O,available:!0,unavailableReason:void 0,label:`${O.label} (global hook installed)`}:O)}function Bh(_,I){if(_.selectKimiInstallMethod)return _.selectKimiInstallMethod();if(!bi(_.input,_.output))return Promise.resolve("global-hook");return nc({input:_.input,output:_.output,globalHookInstalled:Ut({environment:I,cwd:process.cwd()}).status==="configured"})}async function id(_,I,O,L=!1,J){let K=Hh[I];if(_==="install")K?.beforeInstall?.(O,L);if(_==="uninstall")K?.beforeUninstall?.(O);if(Mh(I))return jh(_,I,O,L);if(Uh(I))return Fh(_,I,O,L);if(_==="uninstall")return I==="opencode"?Nh(O):Lh(I,O);return[await Dh(I,O,L,J),await K?.afterInstall?.(O)].filter(Boolean).join(`
262
+ `)}function qh(_){let I=gn({label:"update"},_).errors[0];if(I)throw Error(I)}async function Vh(_,I=vt){let O=await td(_,I),L=Vr(Lt(_),"installed-plugins");return{targets:Ri([...O.hooks.filter((K)=>K.platform!=="copilot-cli"&&K.detected).map((K)=>K.platform),...[Cr,ya,ha].flatMap((K)=>zr(Vr(L,...K))?["copilot-cli"]:[]),...xr(_,Ti)?["claude-code"]:[],...$i(O.codexPluginListOutput)?["codex"]:[]]),codexPluginListOutput:O.codexPluginListOutput}}async function zh(_){let I=c(),O=_.output??process.stdout,L=(_.scriptPath??process.argv[1]??"").split(/[\\/]/),J=L.find((Pe)=>/^bunx-\d+-/.test(Pe)),K=J!==void 0||L.includes("_npx")?null:(_.checkLatestVersion??Gn)(),ne=async()=>{let Pe=K&&await K;if(Pe?.updateAvailable)O.write(`
263
+ Update available: cc-safety-net ${Pe.currentVersion} → ${Pe.latestVersion}. Update this CLI with your package manager, e.g. \`npm i -g cc-safety-net@latest\` for a global install.
264
+ `)},oe=Vh(I,_.fetchVersion??vt).then(async(Pe)=>{let we=new Set(Pe.targets);return{targets:Pe.targets,codexPluginListOutput:Pe.codexPluginListOutput,available:new Map(await Promise.all($n.filter((Le)=>we.has(Le.target)&&Jc.has(Le.target)).map(async(Le)=>[Le.target,await Kt(Le.probeCommand)])))}}),de=await $t(_.showBanner??!0,()=>({ready:oe,finish:()=>oe}),()=>Tt({input:_.input??process.stdin,output:O}),{loadingMessage:"Checking installed integrations…",output:O}),ue=await Promise.resolve().then(()=>(Oc(I.tmpdir,process.platform,J),null)).catch((Pe)=>Zt(Pe));if(de.targets.length===0){if(O.write("No installed integrations found. Run `cc-safety-net install` to set one up.\n"),ue!==null)console.error(ue);return await ne(),ue===null?0:1}let ve=de.targets.some((Pe)=>Wc.has(Pe))?await Promise.resolve().then(()=>(qr(I),null)).catch((Pe)=>Zt(Pe)):null,xe=await vr(Promise.all(de.targets.map((Pe)=>{if(Jc.has(Pe)&&!de.available.get(Pe))return Promise.resolve({message:`${pn(Pe)} not found; skipped`,failed:!1});if(ve!==null&&Wc.has(Pe))return Promise.resolve({message:ve,failed:!0});return id("install",Pe,I,!0,de.codexPluginListOutput).then((we)=>({message:we,failed:!1}),(we)=>({message:Zt(we),failed:!0}))})),{loadingMessage:`Updating ${de.targets.length} integration${de.targets.length===1?"":"s"}…`,output:O}),Se=ue===null?xe:[...xe,{message:ue,failed:!0}];return Se.forEach((Pe)=>Pe.failed?console.error(Pe.message):O.write(`${Pe.message}
265
+ `)),await ne(),Se.some((Pe)=>Pe.failed)?1:0}function Oi(_,I={}){return Promise.resolve().then(()=>qh(_)).then(()=>zh(I)).catch((O)=>(console.error(Zt(O)),1))}async function Xt(_,I,O={}){try{let L=c(),J=await $t(!0,()=>Oh(L,_,I,O),()=>Tt({input:O.input??process.stdin,output:O.output??process.stdout}),{loadingMessage:_==="install"?"Checking available integrations…":"Checking installed integrations…",output:O.output??process.stdout});if(!J)return(O.output??process.stdout).write(`Cancelled: nothing was ${_}ed.
266
+ `),0;if(J==="update")return(O.runUpdate??(()=>Oi([],{fetchVersion:O.fetchVersion,input:O.input,output:O.output,showBanner:!1})))();let K=O.output??process.stdout;return await bc(J,async(ne)=>{if(ne==="kimi-code"&&_==="install"){let de=await Bh(O,L);if(de===null){K.write(`Cancelled: Kimi Code integration was not installed.
267
+ `);return}if(de==="plugin"){K.write(`${Gh(L)}
268
+ `);return}}let oe=await vr(id(_,ne,L),{loadingMessage:`${_==="install"?"Installing":"Uninstalling"} ${pn(ne)} integration…`,output:K});K.write(`${oe}
269
+ `)}),0}catch(L){return console.error(Zt(L)),1}}function Zt(_){let I=_ instanceof Error?_.message:String(_),O=typeof _==="object"&&_!==null&&"code"in _?_.code:null;if(O==="EACCES"||O==="EPERM")return`${I}
270
+ Check file permissions for the target config file and parent directory.`;if(O==="ENOENT")return`${I}
271
+ Check that the target config path and parent directory exist.`;if(O==="ENOTDIR")return`${I}
272
+ Check that every parent path component is a directory.`;return I}import{mkdirSync as Xh}from"node:fs";import{dirname as Qh}from"node:path";import{createInterface as ey}from"node:readline";import{existsSync as ad,readFileSync as Jh}from"node:fs";function ft(_,I){let O=et(_,I);return{policy:O.policy,errors:ae(Ze(O.issues,Qe,(L)=>L.kind==="custom")," "," ")}}function Qt(_,I){return ft(_,I).errors}function sd(_,I){return{"safety.level":_.safety.level,...Di("safety.overrides",_.safety.overrides),"workflow.worktree_mode":String(_.workflow.worktree_mode),"destructive_command_protection.enabled":String(_.destructive_command_protection.enabled),...Di("destructive_command_protection.overrides",_.destructive_command_protection.overrides),"destructive_command_protection.allow_paths":Li(_.destructive_command_protection.allow_paths),"secret_protection.enabled":String(_.secret_protection.enabled),...Di("secret_protection.overrides",_.secret_protection.overrides),"secret_protection.deny_paths":Li(_.secret_protection.deny_paths),"secret_protection.allow_paths":Li(_.secret_protection.allow_paths),...I?{"audit.retention_days":String(_.audit.retention_days)}:{}}}function Jr(_,I,O){let L=sd(_,O),J=sd(I,O);return[...new Set([...Object.keys(L),...Object.keys(J)])].flatMap((K)=>L[K]===J[K]?[]:[{field:K,before:L[K],after:J[K]}])}function er(_,I){let O=d(_,I);if(!ad(O))return{baseline:C(globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__,_.home),diagnostics:[]};let L=mt(O),J=ft(L.value,_.home);return{baseline:J.policy,diagnostics:L.errors.length>0?L.errors:J.errors}}function mt(_){if(!ad(_))return{errors:[`${_}: file not found`]};try{return{value:JSON.parse(Jh(_,"utf-8")),errors:[]}}catch(I){let O=I instanceof Error?I.message:String(I);return{errors:[`${_}: ${I instanceof SyntaxError?`Invalid JSON: ${O}`:O}`]}}}function Wr(_,I){let O=Wh(_)?_:{};return{version:I.version,...Object.fromEntries(["safety","workflow","destructive_command_protection","secret_protection"].filter((L)=>O[L]!==void 0).map((L)=>[L,O[L]]))}}function Di(_,I){return Object.fromEntries(Object.entries(I).flatMap(([O,L])=>L===void 0?[]:[[`${_}.${O}`,String(L)]]))}function Li(_){return _.length===0?"(none)":_.join(", ")}function Wh(_){return!!_&&typeof _==="object"&&!Array.isArray(_)}import{chmodSync as Kh,existsSync as ld,mkdirSync as Yh,readFileSync as cd}from"node:fs";import{dirname as Zh}from"node:path";function dd(_,I={}){let O=d(_,I);if(!ld(O))return{path:O,exists:!1,raw:"",policy:z(),errors:[]};let L=cd(O,"utf-8");if(!L.trim())return{path:O,exists:!0,raw:L,policy:z(),errors:["Config file is empty"]};try{let J=ft(JSON.parse(L),_.home);return{path:O,exists:!0,raw:L,policy:J.policy,errors:J.errors}}catch(J){return{path:O,exists:!0,raw:L,policy:z(),errors:[`Invalid JSON: ${J instanceof Error?J.message:String(J)}`]}}}function Hn(_,I,O={}){let L=d(_,O),J=ft(I,_.home);if(J.errors.length>0)return{path:L,policy:z(),errors:J.errors};let K=J.policy;return Yh(Zh(L),{recursive:!0,mode:448}),g(ie(L),`${JSON.stringify(K,null,2)}
273
+ `,384),Kh(L,384),{path:L,policy:K,errors:[]}}function ud(_,I){let O=ft(I,_.home);if(O.errors.length>0)return{errors:O.errors};return{preview:Ne(O.policy,_.env),errors:[]}}function pd(_,I={}){let O=d(_,I);if(!ld(O))return Hn(_,ee,I);let L=cd(O,"utf-8");if(!L.trim())return Hn(_,ee,I);try{return Hn(_,C(JSON.parse(L),_.home),I)}catch{return Hn(_,ee,I)}}var fd=new Set(["check","apply"]),md="(unset)";async function hd(_,I,O={}){let L=gn({label:"policy",booleans:{global:["-g","--global"]},positionals:"list"},I),J=L.positionals[0],K=[...L.errors,...J&&!fd.has(J)?[`Unknown policy subcommand: ${J}`]:[],...J&&fd.has(J)&&!L.positionals[1]?[`policy ${J} requires a file`]:[],...L.positionals.slice(2).map((we)=>`Unexpected policy argument: ${we}`)];if(K.length>0){for(let we of K)console.error(we);return 1}let ne=L.positionals[1];if(!J||!ne)return Pt(ar,console.error),1;let oe=L.flags.global?d(_):b(O.cwd??process.cwd()),de=mt(ne),ue=[...de.errors,...Qt(de.value,_.home).map((we)=>`${ne}: ${we}`),...!L.flags.global&&ry(de.value)&&de.value.audit!==void 0?[`${ne}: audit settings are user scope only; remove the audit section from a project proposal`]:[]];if(ue.length>0){for(let we of ue)console.error(we);return 1}let ve=C(de.value,_.home);if(console.log(`Scope: ${L.flags.global?"user":"project"} (${oe})`),console.log(`Proposal: ${ne}`),L.flags.global)gd(C(mt(oe).value,_.home),ve,!0);if(!L.flags.global){let we=er(_).baseline;console.log("Effective policy (user + project merged):"),gd(Q(we,le(mt(oe).value,_.home).policy).policy,Q(we,le(de.value,_.home).policy).policy,!1)}if(J==="check")return 0;let xe=O.input??process.stdin,Se=O.output??process.stdout;if(!xe.isTTY||!Se.isTTY)return console.error("policy apply confirms interactively; run this yourself in a terminal:"),console.error(` cc-safety-net policy apply ${ne}${L.flags.global?" --global":""}`),1;if(!await ny(`Apply this policy to ${oe}? [y/N] `,xe,Se))return console.log("Cancelled; nothing was written."),0;return ty(_,oe,de.value,ve,L.flags.global),console.log(`Policy applied: ${oe}`),0}function ny(_,I,O){let L=ey({input:I,output:O,terminal:!1});return new Promise((J)=>{L.once("close",()=>J(!1)),L.question(_,(K)=>{J(/^y(es)?$/i.test(K.trim())),L.close()})})}function ty(_,I,O,L,J){if(J){Hn(_,L);return}Xh(Qh(I),{recursive:!0}),bn(I,Wr(O,L))}function gd(_,I,O){let L=Jr(_,I,O);if(L.length===0){console.log("No changes.");return}console.log(`Changes (${L.length}):`);for(let J of L)console.log(` ${J.field}: ${J.before??md} -> ${J.after??md}`)}function ry(_){return!!_&&typeof _==="object"&&!Array.isArray(_)}import{join as hv}from"node:path";var yd="# Custom Rules Reference\n\nAgent reference for generating CC Safety Net rulebook configuration.\n\n## Config Locations\n\n| Scope | Config path | Rulebook path | Priority |\n|-------|-------------|---------------|----------|\n| User | `~/.cc-safety-net/rules/rule.json` | `~/.cc-safety-net/rules/<rulebook-name>/rulebook.json` | First |\n| Project | `.cc-safety-net/rules/rule.json` | `.cc-safety-net/rules/<rulebook-name>/rulebook.json` | Second |\n| GitHub source | Listed in a local `rule.json` | Vendored into the consumer's `<rulebook-name>/rulebook.json` by `rule add` | Source order |\n\nEvery rulebook is a live file: the runtime reads it on each tool call, so an edit applies to the next command with no publishing step.\n\nUser scope is evaluated before project scope; within a scope, sources apply in `rules` array order. A duplicate active rulebook name keeps the first claim and ignores the later rulebook with a warning, so a user-scoped name shadows a project-scoped one.\n\nUse `cc-safety-net rule init` to create an inert local config. Use `--global` for user scope. Use `cc-safety-net rule init --example` to also create an inactive example rulebook. `CC_SAFETY_NET_HOME` overrides the `~/.cc-safety-net` user root.\n\nLegacy inline `.safety-net.json` and `~/.cc-safety-net/config.json` files are not loaded at runtime. Convert them with `cc-safety-net rule migrate`.\n\n## rule.json Schema\n\n```json\n{\n \"version\": 1,\n \"rules\": [\"project-rules\", \"owner/repo#main/team-rules\"],\n \"overrides\": {\n \"project-rules/block-docker-system-prune\": {\n \"reason\": \"Use targeted Docker cleanup commands.\"\n },\n \"team-rules/block-npm-global\": \"off\"\n },\n \"transparent_wrappers\": [\"rtk\"]\n}\n```\n\n- `version`: Required. Must be `1`.\n- `$schema`: Optional. `cc-safety-net rule verify` inserts it into a valid `rule.json` that lacks it.\n- `rules`: Optional array of rulebook source strings. Missing `rules` is treated as `[]`.\n- `overrides`: Optional object keyed by `<rulebook-name>/<rule-name>`.\n- `overrides` values are either `\"off\"` to disable a rule or an object with a required `reason` (replacement block reason) and an optional `intent` (one of `hard_stop`, `use_alternative`, `scope_down`, `manual_only`, `stop_and_explain`).\n- A project override cannot target a user-scoped rule: only that override is ignored, the user rule keeps its configured state, and `rule verify` reports the diagnostic as a failure.\n- `transparent_wrappers`: Optional array of command names that transparently execute a visible child command.\n- `exec`, `nice`, `nohup`, `setsid`, `stdbuf`, `time`, and `timeout` are built-in transparent wrappers and need no configuration. Configure only other wrappers you intentionally trust, such as `\"rtk\"`.\n- Use `cc-safety-net rule wrapper add rtk` to configure RTK without manually editing `rule.json`.\n\n## Rulebook Sources\n\n- Local sources are bare rulebook names such as `project-rules`; the rulebook file is `.cc-safety-net/rules/project-rules/rulebook.json`.\n- Run `cc-safety-net rule add owner/repo` to add every rulebook currently present on the repository's default branch.\n- Use `--only` to select one or more rulebooks while preserving their order: `cc-safety-net rule add owner/repo --only aws gcloud`.\n- Use `--ref` to select a branch, tag, or commit instead of the default branch: `cc-safety-net rule add owner/repo --ref v2 --only aws`.\n- GitHub sources are stored in canonical form as `owner/repo#ref/<rulebook-name>`. That form remains valid in `rule.json` and as direct CLI input.\n- GitHub refs may contain `/`-separated path segments, such as `feature/rulebook-v2`.\n- The GitHub source name, the repository directory name, and the rulebook `name` must match exactly.\n- Rulebook source strings must be unique in a config.\n\n## rulebook.json Schema\n\n```json\n{\n \"rulebook_version\": 1,\n \"name\": \"project-rules\",\n \"version\": \"1.0.0\",\n \"description\": \"Project-specific CC Safety Net rules.\",\n \"author\": \"project\",\n \"allowed_commands\": [\"docker\"],\n \"rules\": [\n {\n \"name\": \"block-docker-system-prune\",\n \"command\": \"docker\",\n \"subcommand\": \"system\",\n \"block_args\": [\"prune\"],\n \"reason\": \"Use targeted cleanup instead.\"\n }\n ],\n \"tests\": [\n {\n \"command\": \"docker system prune\",\n \"expect\": \"blocked\",\n \"rule\": \"block-docker-system-prune\"\n },\n {\n \"command\": \"docker ps\",\n \"expect\": \"allowed\"\n }\n ]\n}\n```\n\n### Rulebook Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `rulebook_version` | Yes | Must be `1` or `2` |\n| `name` | Yes | `^[a-zA-Z][a-zA-Z0-9_-]{0,63}$` |\n| `version` | Yes | Non-empty string |\n| `description` | No | Free text; not type-checked at runtime |\n| `author` | No | Free text; not type-checked at runtime |\n| `allowed_commands` | Yes | Unique command names matching `^[a-zA-Z][a-zA-Z0-9_-]*$` |\n| `rules` | Yes | Array of rule objects |\n| `tests` | No | Array of fixtures |\n\n### Rule Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `name` | Yes | Unique within the rulebook (case-insensitive); same pattern as rulebook `name` |\n| `command` | Yes | Must be listed in `allowed_commands`; basename only, not path |\n| `subcommand` | No | Same pattern as `command`; omit to match any subcommand |\n| `intent` | No | One of `hard_stop`, `use_alternative`, `scope_down`, `manual_only`, `stop_and_explain` |\n| `block_args` | Yes | Non-empty array of non-empty strings |\n| `reason` | Yes | Non-empty string, max 256 chars |\n\n### Rule Fields (`rulebook_version` 2)\n\nVersion 2 replaces `subcommand` and `block_args` with an exact-token `match` object. Version 1 rulebooks keep their fields and their behavior; a client that does not support version 2 rejects the rulebook instead of applying broader version 1 semantics.\n\n```json\n{\n \"name\": \"block-terraform-apply-destroy\",\n \"command\": \"terraform\",\n \"match\": {\n \"command_path\": [\"apply\"],\n \"any_args\": [\"-destroy\", \"--destroy\"]\n },\n \"reason\": \"Review a destroy plan first with 'terraform plan -destroy'.\",\n \"intent\": \"use_alternative\"\n}\n```\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `name` | Yes | Same as version 1 |\n| `command` | Yes | Same as version 1 |\n| `match.command_path` | Yes | Non-empty array of non-empty command words |\n| `match.any_args` | No | Non-empty array of unique non-empty argument tokens |\n| `match.exclude_args` | No | Non-empty array of unique non-empty argument tokens |\n| `intent` | No | Same as version 1 |\n| `reason` | Yes | Same as version 1 |\n\n### Matching Behavior (`rulebook_version` 2)\n\n- **Command**: Normalized to lowercase basename, as in version 1.\n- **Command path**: After recognized global options and their values are skipped, the next command words must equal `command_path` exactly. AWS, gcloud, and Azure CLI value-taking global options are built in; Terraform's `-chdir=dir` is `=`-joined and is skipped with its own token.\n- **Unrecognized options**: A token starting with `-` that is not a recognized global option is skipped without consuming a value, so an unlisted value-taking option with a separate value (`--newflag value`) makes the rule miss. This fails open deliberately; document such gaps in the rulebook.\n- **`any_args`**: At least one listed token must appear literally among the arguments.\n- **`exclude_args`**: Any listed token appearing literally among the arguments prevents the match, which is how a safe preview such as `aws s3 rm --dryrun` stays allowed.\n- **No short-option expansion**: Arguments compare as exact tokens, so list every accepted spelling (`\"-destroy\"` and `\"--destroy\"`).\n- **Literal and case-sensitive**: No regex, glob, or substring matching. The first matching rule wins.\n- Release channels are separate rules: `gcloud beta compute instances delete` needs its own `command_path`.\n\n### Test Fixture Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `command` | Yes | Non-empty shell command string |\n| `expect` | Yes | `\"blocked\"` or `\"allowed\"` |\n| `rule` | Required for blocked fixtures | Rule name expected to block the command |\n\nFixtures are optional documentation of intended behavior. Version 1 fixtures are shape-validated only. Version 2 fixtures are evaluated against the rulebook's own rules when a source is fetched by `rule add` or `rule update`, and by `rule verify`; a failing fixture rejects that source before it is written. Loading a rulebook does not re-evaluate fixtures. CC Safety Net never executes fixture commands; they are analyzer inputs only.\n\n## Matching Behavior\n\nThe subcommand, argument, and option rules below describe `rulebook_version` 1 rules; version 2 rules match as described in Matching Behavior (`rulebook_version` 2). Execution order and transparent wrappers apply to both.\n\n- **Command**: Normalized to lowercase basename with any trailing `.exe` removed (`/usr/bin/git` → `git`).\n- **Subcommand**: The first command token after recognized Git and Docker global options and their values; `--` ends option parsing. An unrecognized option without `=` may consume the following token as its value.\n- **Arguments**: Each `block_args` value is compared literally against every command token, including expanded short options. The command is blocked if **any** item matches.\n- **Short options**: Expanded (`-Ap` matches `-A`).\n- **Long options**: Exact match (`--all-files` does not match `--all`).\n- **Execution order**: Built-in rules first, then custom rulebooks. Custom rules only add restrictions.\n- **Transparent wrappers**: A configured wrapper such as `rtk` lets `rtk git commit` be analyzed as `git commit` only when `git` is protected by built-in analyzers or active custom rules. `rtk -- git commit` is also supported.\n\n## Workflow\n\n1. Run `cc-safety-net rule init` or create `rule.json` manually.\n2. Optionally run `cc-safety-net rule init --example` to create an inactive example rulebook.\n3. Use `cc-safety-net rule wrapper add rtk` for trusted transparent wrappers.\n4. Run `cc-safety-net rule add <source>` after creating or choosing a rulebook source; add `--only <rulebook...>` or `--ref <ref>` for repository selection. The command adds the selected sources and syncs them.\n5. Edit a local rulebook whenever you like: the edit is enforced on the next command, so there is nothing to run afterwards.\n6. Run `cc-safety-net rule update [source]` to re-fetch remote sources and rewrite the vendored copies; the command prints what changed. A source with an ordinary update failure keeps its vendored copy while the other selected sources still update. Resource-limit failures remain fatal for the whole update.\n7. Run `cc-safety-net rule verify` to validate config, local rulebooks, and shareable GitHub-source rulebook directories in the current repository (it does not fetch remote content).\n8. Run `cc-safety-net rule list` to inspect active rulebooks and transparent wrappers.\n\nA missing or invalid rulebook file makes that source inactive, and an unreadable or invalid `rule.json` makes every source in its scope inactive. Inactive sources stop applying their rules while other custom rules and all built-in protections stay active. Fix the file named in the diagnostic, or run `cc-safety-net rule update` when a remote source has not been vendored yet. Run `cc-safety-net status` to see degraded sources.\n";function Kr(_,I){if(!_.ok){xd(_);return}wd(_,I)}function bd(_,I,O){if(_.ok)console.log(O);if(!_.add){Kr(_,`Added rulebook source: ${I}`);return}if(!_.ok){xd(_);return}if(_.add.added.length>0)console.log(`Added ${_.add.added.length} ${_.add.added.length===1?"rulebook":"rulebooks"} from ${_.add.source} at ${_.add.ref}:`),_.add.added.forEach((L)=>{console.log(` - ${L}`)});if(_.add.alreadyConfigured.length>0)console.log(`Rulebooks already configured from ${_.add.source} at ${_.add.ref}: ${_.add.alreadyConfigured.join(", ")}`);if(_.add.commits.length>0)console.log(`Vendored at ${_.add.commits.map((L)=>L.slice(0,7)).join(", ")}.`);wd(_,"Rule config updated.")}function wd(_,I){for(let O of _.changes??[])console.log(O);console.log(I),console.log(""),oy(_.entries)}function oy(_){if(_.length===0){console.log("Active rulebooks: (none)");return}console.log(`Active rulebooks (${_.length}):`);for(let I of _)console.log(` - ${I.name} ${I.version} (${iy(I.ruleCount)})`),console.log(` Source: ${I.spec}`)}function iy(_){return`${_} ${_===1?"rule":"rules"}`}function kd(_){gt("Active sources",_.rulebooks,(I)=>[`[${I.source}] ${I.name} ${I.version}`,` Source: ${I.spec}`]),gt("Active rules",_.rules,(I)=>[`[${ay(_,I.name)}] ${I.name}`,...sy(I),` Reason: ${I.reason}`]),gt("Disabled rules",vd(_,"off"),(I)=>[I.key]),gt("Reason overrides",vd(_,"reason"),(I)=>[I.key,` Reason: ${I.value.reason}`]),gt("Transparent wrappers",_.transparent_wrappers,(I)=>[I]),gt("Issues",_.errors,(I)=>[I]),gt("Warnings",_.warnings,(I)=>[I])}function gt(_,I,O){if(I.length===0){console.log(`${_}: (none)`);return}console.log(`${_} (${I.length}):`);for(let L of I){let[J,...K]=O(L);console.log(` - ${J}`);for(let ne of K)console.log(` ${ne}`)}}function sy(_){if(!_.match)return[` Command: ${_.subcommand?`${_.command} ${_.subcommand}`:_.command}`,` Block args: ${_.block_args.join(", ")}`];return[` Command: ${[_.command,..._.match.command_path].join(" ")}`,..._.match.any_args?[` Any args: ${_.match.any_args.join(", ")}`]:[],..._.match.exclude_args?[` Exclude args: ${_.match.exclude_args.join(", ")}`]:[]]}function ay(_,I){return _.rulebooks.find((O)=>O.rules.includes(I))?.source??"project"}function vd(_,I){return Object.entries({..._.userConfig?.overrides,..._.projectConfig?.overrides}).filter((O)=>{if(I==="off")return O[1]==="off";return!!O[1]&&typeof O[1]==="object"}).map(([O,L])=>({key:O,value:L}))}function xd(_){for(let I of _.errors)console.error(I)}import{dirname as Vd,join as ro}from"node:path";import{join as Mi,resolve as by}from"node:path";function Ni(_){let I=m(_);if(I.errors.length>0)return{ok:!1,result:{ok:!1,errors:I.errors,entries:[]}};return{ok:!0,config:I.config??lt}}function Sd(_){bn(_,{version:1,rules:[],overrides:{},transparent_wrappers:[]})}function Cd(_){bn(_,{rulebook_version:1,name:"example-rules",version:"1.0.0",description:"Project-specific CC Safety Net rules.",author:"project",allowed_commands:["docker"],rules:[{name:"block-docker-system-prune",command:"docker",subcommand:"system",block_args:["prune"],reason:"Use targeted cleanup instead."}],tests:[{command:"docker system prune",expect:"blocked",rule:"block-docker-system-prune"}]})}import{dirname as Qr}from"node:path";var ly="custom.";function Yr(_){if(_.rulebook_version!==2)return[];let I=_.rules.map((O)=>({name:O.name,command:O.command,block_args:[],match:O.match,reason:O.reason,intent:O.intent}));return(_.tests??[]).flatMap((O,L)=>{let J=ji(h(O.command));if(J.length===0)return[`tests[${L}]: could not parse fixture command: ${O.command}`];let K=J.reduce((ne,oe)=>ne??A(oe,I)?.id.slice(ly.length),void 0);if(O.expect==="blocked"){if(K===O.rule)return[];let ne=K?`"${K}" matched first`:"no rule matched";return[`tests[${L}]: expected "${O.rule}" to block "${O.command}" but ${ne}`]}return K?[`tests[${L}]: expected "${O.command}" to be allowed but "${K}" matched`]:[]})}function ji(_){return _.nodes.flatMap((I)=>{if(I.kind==="group"||I.kind==="function")return ji(I.body);if(I.kind!=="command")return[];let O=be(te(I.dialect,I.words)).words.map(t);return[...O.length>0?[O]:[],...I.nested.flatMap((L)=>ji(L))]})}var Zr=Object.freeze({concurrency:4,maxRequests:131,maxResponseBytes:67108864});function Xr(_={}){return{requests:0,responseBytes:0,maxRequests:_.maxRequests??Zr.maxRequests,maxResponseBytes:_.maxResponseBytes??Zr.maxResponseBytes}}function Mn(_){return{controller:new AbortController,budget:Xr(),resolveUrl:_}}function Rd(_){return _ instanceof Error&&_.message==="Rule synchronization exceeds CC Safety Net's safe resource limits."}function Pd(_){if(_.requests>=_.maxRequests)throw Error("Rule synchronization exceeds CC Safety Net's safe resource limits.");_.requests++}function Ed(_,I){if(I>_.maxResponseBytes-_.responseBytes)throw _.responseBytes+=I,Error("Rule synchronization exceeds CC Safety Net's safe resource limits.");_.responseBytes+=I}var Id=Object.freeze({timeoutMs:15000,metadataBytes:524288,commitBytes:262144,treeBytes:16777216,rawBytes:4194304});async function Ad(_,I,O=v(Qr(Qr(I)),"rules policy"),L=Mn()){if(S(_))return py(_,L);return uy(_,I,O)}async function Td(_,I,O,L,J,K){if(!S(_))return Ad(_,I,O,L);let ne=J?null:cy(_,I,O);if(ne)return ne;if(!J&&!K)throw Error(`${_} is not vendored; run rule update ${_} to vendor it`);return Ad(_,I,O,L)}function cy(_,I,O=v(Qr(Qr(I)),"rules policy")){let L=D(_),J=N(I,L.name),K=n(i(O,J));if(K===null)return null;let ne=ce(Fi(K,`Invalid rulebook ${J}.`));if(ne.name!==L.name)throw Error(`rulebook name "${ne.name}" in ${J} must match "${L.name}"`);return{spec:_,rulebook:ne,content:K}}async function $d(_,I={}){if(!Y(_))throw Error(`Invalid GitHub repository source: ${_}`);let[O,L]=_.split("/");if(!O||!L)throw Error(`Invalid GitHub repository source: ${_}`);if(I.ref!==void 0&&!se(I.ref))throw Error(`GitHub rulebook refs must use valid path segments: ${I.ref}`);let J=I.operation??Mn(),K=I.ref??await dy(O,L,_,J),ne=await Dd(O,L,K,_,J),oe=await eo(`https://api.github.com/repos/${O}/${L}/git/trees/${ne}?recursive=1`,"tree",J),de=oe.response;if(!de.ok)throw Error(`Failed to inspect ${_}: GitHub tree returned ${de.status}`);let ue=JSON.parse(oe.content);if(!Array.isArray(ue?.tree))throw Error(`Failed to inspect ${_}: unexpected GitHub tree response`);let ve=ue.tree,xe=[...new Set(ve.flatMap((Se)=>{if(!Se||typeof Se!=="object")return[];let Pe=Se;if(Pe.type!=="blob"||typeof Pe.path!=="string")return[];let we=Pe.path.match(at);return we?.[1]?[we[1]]:[]}))].sort();if(xe.length===0)throw Error(`No rulebooks found in ${_} under ${me}/`);return{source:_,owner:O,repo:L,ref:K,commit:ne,names:xe}}async function dy(_,I,O,L){let J=await eo(`https://api.github.com/repos/${_}/${I}`,"metadata",L),K=J.response;if(!K.ok)throw Error(`Failed to inspect ${O}: GitHub returned ${K.status}`);let oe=JSON.parse(J.content)?.default_branch;if(typeof oe!=="string"||oe==="")throw Error(`Failed to inspect ${O}: missing default branch`);if(!se(oe))throw Error(`GitHub returned an invalid default branch: ${oe}`);return oe}function uy(_,I,O){ct(_);let L=N(I,_),J=n(i(O,L));if(J===null)throw Error(`Rulebook source not found: ${_}`);let K=Od(Fi(J,"Invalid local rulebook source."));if(K.name!==_)throw Error(`rulebook name "${K.name}" must match local source "${_}"`);return{spec:_,rulebook:K,content:J}}async function py(_,I){let O=D(_),L=await Dd(O.owner,O.repo,O.ref,_,I),J=await eo(`https://raw.githubusercontent.com/${O.owner}/${O.repo}/${L}/${O.path}`,"raw",I),K=J.response;if(!K.ok)throw Error(`Failed to fetch ${_}: GitHub raw returned ${K.status}`);let ne=J.content,oe=Od(Fi(ne,"Invalid GitHub rulebook response."));if(oe.name!==O.name)throw Error(`rulebook name "${oe.name}" must match GitHub source "${O.name}"`);return{spec:_,rulebook:oe,content:ne}}function Od(_){let I=ce(_),O=Yr(I);if(O.length>0)throw Error(O.join("; "));return I}function Fi(_,I){try{return JSON.parse(_)}catch{throw Error(I)}}async function Dd(_,I,O,L,J){let K=await eo(`https://api.github.com/repos/${_}/${I}/commits/${encodeURIComponent(O)}`,"commit",J),ne=K.response;if(!ne.ok)throw Error(`Failed to resolve ${L}: GitHub returned ${ne.status}`);let oe=JSON.parse(K.content);if(typeof oe?.sha!=="string"||oe.sha==="")throw Error(`Failed to resolve commit for ${L}`);return oe.sha}async function fy(_,I,O={}){if(O.signal?.aborted)throw O.signal.reason;let L=O.budget??Xr(),J=new AbortController,K=()=>J.abort(O.signal?.reason);O.signal?.addEventListener("abort",K,{once:!0});let ne=!1,oe=setTimeout(()=>{if(J.signal.aborted)return;ne=!0,J.abort()},O.timeoutMs??Id.timeoutMs);try{if(O.signal?.aborted)throw O.signal.reason;Pd(L);let de=await fetch(_,{signal:J.signal,redirect:"error"});if(!de.ok)return Ld(de),{response:de,content:""};return{response:de,content:await my(de,I,L,()=>J.abort())}}catch(de){if(ne)throw Error("GitHub request timed out",{cause:de});if(O.signal?.aborted)throw O.signal.reason;throw de}finally{clearTimeout(oe),O.signal?.removeEventListener("abort",K)}}function eo(_,I,O){return fy(O.resolveUrl?.(_)??_,I,{budget:O.budget,signal:O.controller.signal})}async function my(_,I,O=Xr(),L){let J=Id[`${I}Bytes`],K=Number(_.headers.get("content-length"));if(Number.isFinite(K)&&K>J)throw Ld(_),Error(`GitHub ${I} response exceeds ${J} bytes`);if(!_.body)return"";let ne=_.body.getReader(),oe=[],de=0;while(!0){let ue=await ne.read();if(ue.done)break;try{Ed(O,ue.value.byteLength)}catch(ve){throw L?.(),_d(ne),ve}if(de+=ue.value.byteLength,de>J)throw L?.(),_d(ne),Error(`GitHub ${I} response exceeds ${J} bytes`);oe.push(Buffer.from(ue.value))}return Buffer.concat(oe,de).toString("utf-8")}function Ld(_){if(!_.body)return;Nd(()=>_.body?.cancel())}function _d(_){Nd(()=>_.cancel())}function Nd(_){try{Promise.resolve(_()).catch(()=>{})}catch{}}var gy=/^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)#(.+)$/;function jd(_,I){let O=Md(_.rules,I);if(O.length>0)return{ok:!0,specs:O};return Hd(_.rules,I)}function Fd(_,I){let O=Md(_,I);if(O.length>0)return{ok:!0,specs:O};let L=yy(_,I);if(L.length>0)return{ok:!0,specs:L};let J=vy(_,I);if(!J.ok)return J;if(J.specs.length>0)return{ok:!0,specs:J.specs};return Hd(_,I)}function Hd(_,I){let O=_.filter((L)=>Hi(L)?.name===I);if(O.length===1)return{ok:!0,specs:O};return hy(I,O)}function hy(_,I){return{ok:!1,result:{ok:!1,errors:I.length===0?[`No configured rulebook matches ${_}`]:[`Ambiguous rulebook match ${_}: ${I.join(", ")}`],entries:[]}}}function Md(_,I){return _.filter((O)=>O===I)}function yy(_,I){let O=I.match(gy),L=O?.[1],J=O?.[2],K=O?.[3];if(!L||!J||!K||!se(K))return[];return Ud(_,(ne)=>ne.owner===L&&ne.repo===J&&ne.ref===K)}function vy(_,I){if(!Y(I))return{ok:!0,specs:[]};let[O,L]=I.split("/"),J=Ud(_,(ne)=>ne.owner===O&&ne.repo===L);if(new Set(J.map((ne)=>Hi(ne)?.ref).filter((ne)=>!!ne)).size<2)return{ok:!0,specs:J};return{ok:!1,result:{ok:!1,errors:[`Multiple refs are configured for ${I}. Use an explicit ref:`,` cc-safety-net rule remove ${I}#<ref>`],entries:[]}}}function Hi(_){try{return D(_)}catch{return null}}function Ud(_,I){return _.filter((O)=>{let L=Hi(O);return L?I(L):!1})}async function to(_,I={}){let O=Ui(I);return wy(_,O,await no(_,O,Mn()))}function wy(_,I,O){if(!O.ok)return O;let L=wn(_,I),J=[...new Set(H(L.configPath,L.filesystemScope))];if(J.length===0)return O;return{ok:!1,errors:J,entries:O.entries}}async function no(_,I,O,L={},J=new Set,K=new Set){try{let ne=wn(_,I),oe=Ni(ne.configTarget);if(!oe.ok)return oe.result;let de=oe.config,ue=I.only?jd(de,I.only):{ok:!0,specs:de.rules};if(!ue.ok)return ue.result;let ve=new Set([...I.refresh?ue.specs:[],...J]),xe=(rn)=>Td(rn,ne.configDir,ne.filesystemScope,O,ve.has(rn),!I.refresh||ve.has(rn)),Se=await Ty(de.rules,I.refresh?(rn)=>xe(rn).then((un)=>({ok:!0,item:un})).catch((un)=>{if(Rd(un))throw un;return{ok:!1,spec:rn,message:un instanceof Error?un.message:String(un)}}):async(rn)=>({ok:!0,item:await xe(rn)}),O),Pe=Se.filter((rn)=>!rn.ok),we=Se.filter((rn)=>rn.ok).map((rn)=>rn.item),Le=we.flatMap((rn)=>ky(rn,de.rules)),en=we.flatMap((rn)=>xy(rn,K,ne)),Ve=new Set([...Le,...en].map((rn)=>rn.spec)),on=[...Pe,...Le,...en],sn=[],an=Cy(sn,()=>we.flatMap((rn)=>Ve.has(rn.spec)||on.length>0&&K.has(rn.spec)?[]:Sy(rn,ne,L,sn)));return{ok:on.length===0,errors:on.map((rn)=>`Failed to update ${rn.spec}: ${rn.message}`),entries:we.map(Py),changes:an}}catch(ne){return tr(ne)}}function ky(_,I){if(!S(_.spec))return[];let O=De(_.spec),L=I.filter((J)=>J!==_.spec&&De(J).toLowerCase()===O.toLowerCase());if(L.length===0)return[];return[{ok:!1,spec:_.spec,message:`rulebook name "${O}" is also claimed by ${L.join(", ")}; rename one of them`}]}function xy(_,I,O){if(!I.has(_.spec)||!S(_.spec))return[];let L=N(O.configDir,_.rulebook.name),J=n(i(O.filesystemScope,L));if(J===null||J===_.content)return[];return[{ok:!1,spec:_.spec,message:`${L} already exists and no configured source claims it; remove or rename the file, then re-run rule add`}]}function Sy(_,I,O,L){if(!S(_.spec))return[];let J=N(I.configDir,_.rulebook.name),K=i(I.filesystemScope,J),ne=n(K);if(ne===_.content)return[];return L?.push({target:K,previous:ne}),g(K,_.content,void 0,O._testAfterPolicyRename),Ry(_,ne)}function Cy(_,I){try{return I()}catch(O){for(let L of[..._].reverse()){if(L.previous===null){j(L.target);continue}g(L.target,L.previous)}throw O}}function Ry(_,I){if(I===null)return[`Vendored ${_.spec} (${_.rulebook.version})`];let O=ye(I),L="problem"in O?null:O.rulebook,J=new Map(L?.rules.map((ne)=>[ne.name,JSON.stringify(ne)])??[]),K=new Set(_.rulebook.rules.map((ne)=>ne.name));return[`Updated ${_.spec} (${L?.version??"unreadable"} -> ${_.rulebook.version})`,...[...K].filter((ne)=>!J.has(ne)).map((ne)=>` + ${ne}`),...[...J.keys()].filter((ne)=>!K.has(ne)).map((ne)=>` - ${ne}`),..._.rulebook.rules.filter((ne)=>{let oe=J.get(ne.name);return oe!==void 0&&oe!==JSON.stringify(ne)}).map((ne)=>` ~ ${ne.name}`)]}function Py(_){return{spec:_.spec,name:_.rulebook.name,version:_.rulebook.version,ruleCount:_.rulebook.rules.length}}async function Gd(_,I,O={}){return Ey(_,I,Oy(O),Mn())}async function Ey(_,I,O,L,J={}){let K=null,ne=!1;try{let oe=wn(_,O),de=n(oe.configTarget);K={target:oe.configTarget,content:de};let ue=Ni(oe.configTarget);if(!ue.ok)return ue.result;let ve=ue.config,xe=Y(I);Ay(I,O,xe);let Se=xe?await $d(I,{ref:O.ref,operation:L}):null,Pe=Se?_y(Se,O.rulebooks):[],we=Se?Pe.map((sn)=>Iy(ve.rules,Se,sn)??`${I}#${Se.ref}/${sn}`):[I],Le=we.filter((sn)=>!ve.rules.includes(sn)),en=[...ve.rules,...Le];if(en.length>ge)return $y();if(en.length!==ve.rules.length)ne=!0,bn(oe.configTarget,{version:1,rules:en,overrides:ve.overrides??{},transparent_wrappers:ve.transparent_wrappers??[]},void 0,J._testAfterPolicyRename);let Ve=await no(_,O,L,J,new Set(Le),new Set(Le));if(!Ve.ok)nr(oe.configTarget,de);if(!Ve.ok||!Se)return Ve;let on=Pe.filter((sn,an)=>Le.includes(we[an]??""));return{...Ve,add:{source:I,ref:Se.ref,selected:Pe,added:on,alreadyConfigured:Pe.filter((sn)=>!on.includes(sn)),commits:Le.length>0?[Se.commit]:[]}}}catch(oe){if(ne&&K)try{nr(K.target,K.content)}catch(de){return tr(de)}return tr(oe)}}function Ay(_,I,O){if(!O&&I.rulebooks!==void 0)throw Error("--only can only select rulebooks from an owner/repo source");if(!O&&I.ref)throw Error(`--ref can only select a ref for an owner/repo source: ${_}`);if(I.rulebooks?.length===0)throw Error("--only requires at least one rulebook name");let L=I.rulebooks?.filter((J)=>!u.test(J))??[];if(L.length>0)throw Error(`Invalid rulebook names: ${L.join(", ")}`)}function _y(_,I){let O=I?[...new Set(I)]:_.names,L=O.filter((J)=>!_.names.includes(J));if(L.length>0)throw Error(`Rulebooks not found in ${_.source} at ${_.ref}: ${L.join(", ")}
274
+ Available rulebooks: ${_.names.join(", ")}`);return O}function Iy(_,I,O){let L=`${I.source}#${I.ref}/${O}`;if(_.includes(L))return L;let J=`${I.source}#${I.commit}/${O}`;return _.find((K)=>K===J)}async function Ty(_,I,O=Mn()){if(_.length>ge)throw Error(he);let L=[],J=0,K,ne=Array.from({length:Math.min(_.length,Zr.concurrency)},async()=>{while(!K){let oe=J;if(oe>=_.length)return;J++;try{L[oe]=await I(_[oe],oe,O.controller.signal)}catch(de){if(!K)K={value:de},J=_.length,O.controller.abort(de);return}}});if(await Promise.all(ne),K)throw K.value;return L}function $y(){return{ok:!1,errors:[he],entries:[]}}function Ui(_){return{cwd:_.cwd,userConfigDir:_.userConfigDir,userConfigPath:_.userConfigPath,projectConfigPath:_.projectConfigPath,global:_.global,only:_.only,refresh:_.refresh}}function Oy(_){return{...Ui(_),ref:_.ref,rulebooks:_.rulebooks}}function Dy(_){return{...Ui(_),deleteSource:_.deleteSource}}async function Bd(_,I,O={}){try{return await Ly(_,I,Dy(O),{})}catch(L){return tr(L)}}async function Ly(_,I,O,L){let J=wn(_,O),K=m(J.configTarget);if(K.errors.length>0)return{ok:!1,errors:K.errors,entries:[]};if(!K.config)return{ok:!1,errors:[`No config found at ${J.configPath}`],entries:[]};let ne=Fd(K.config.rules,I);if(!ne.ok)return ne.result;let oe=O.deleteSource?Ny(J.configDir,ne.specs,J.filesystemScope):{ok:!0,dirs:[]};if(!oe.ok)return oe.result;let de=n(J.configTarget);if(de===null)return tr(Error("Rules config is unavailable."));try{bn(J.configTarget,{version:1,rules:K.config.rules.filter((xe)=>!ne.specs.includes(xe)),overrides:K.config.overrides??{},transparent_wrappers:K.config.transparent_wrappers??[]},void 0,L._testAfterPolicyRename)}catch(xe){throw nr(J.configTarget,de),xe}let ue=await no(_,O,Mn(),L);if(!ue.ok)return nr(J.configTarget,de),ue;let ve=jy(oe.dirs,L,J.filesystemScope);if(!ve.ok){nr(J.configTarget,de);let xe=await no(_,O,Mn(),L);if(!xe.ok)return{ok:!1,errors:[...ve.result.errors,...xe.errors],entries:xe.entries};return ve.result}return ue}function Ny(_,I,O){let L=I.flatMap((oe)=>u.test(oe)?[]:["--delete-source can only delete local rulebook sources"]),J=I.map((oe)=>Mi(_,oe)),K=L.length>0?[]:J.flatMap((oe)=>qd(oe,O)),ne=[...L,...K];return ne.length>0?{ok:!1,result:{ok:!1,errors:ne,entries:[]}}:{ok:!0,dirs:J}}function qd(_,I){let O=by(_),L=i(I,O),J=pe(L);if(!J)return[`Local rulebook source directory not found: ${_}`];let K=J.find((ne)=>ne.name==="rulebook.json");if(!K)return[`Local rulebook source directory is missing rulebook.json: ${_}`];if(K.kind!=="file")throw new r(I.label);if(n(i(I,Mi(O,"rulebook.json"))),J.length>1)return[`Local rulebook source directory contains extra files: ${_}. delete manually if you really want to remove the directory.`];return[]}function jy(_,I,O){let L=_.flatMap((J)=>{try{if(!pe(i(O,J)))return[];let K=qd(J,O);if(K.length>0)return K;return Fy(J,I,O),[]}catch(K){return[`Failed to delete local rulebook source ${J}: ${K instanceof Error?K.message:String(K)}`]}});return L.length>0?{ok:!1,result:{ok:!1,errors:L,entries:[]}}:{ok:!0}}function Fy(_,I,O){if(I._testDeleteLocalSourceDir){I._testDeleteLocalSourceDir(_);return}j(i(O,Mi(_,fe))),st(i(O,_))}function nr(_,I){if(I===null){j(_);return}g(_,I)}function tr(_){return{ok:!1,errors:[_ instanceof Error?_.message:String(_)],entries:[]}}var Hy=".safety-net.json",My="~/.cc-safety-net/config.json";async function Wd(_,I){return[await zd(_,{legacyPath:Ys({cwd:I.cwd}),configPath:U(I.cwd),defaultRulebookName:"project-rules",migratedFrom:Hy,cleanup:I.cleanup,syncOptions:{cwd:I.cwd}}),await zd(_,{legacyPath:ur(_),configPath:G(_),defaultRulebookName:"user-rules",migratedFrom:My,cleanup:I.cleanup,syncOptions:{cwd:I.cwd,global:!0}})].every((L)=>L)?0:1}async function zd(_,I){let O=wn(_,I.syncOptions),L=i(O.filesystemScope,I.legacyPath),J=n(L);if(J===null)return console.log(`No legacy config found at ${I.legacyPath}`),!0;let K=Gy(J);if(!K.ok){for(let Pe of K.errors)console.error(Pe);return!1}let ne=m(O.configTarget);if(ne.errors.length>0){for(let Pe of ne.errors)console.error(Pe);return!1}let oe=ne.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},de=By(Vd(I.configPath),oe.rules,I.defaultRulebookName,I.migratedFrom,O.filesystemScope),ue=ro(Vd(I.configPath),de,"rulebook.json"),ve=i(O.filesystemScope,ue),xe=[Jd(O.configTarget),Jd(ve)],Se=await Uy(_,I,O.configTarget,ve,de,K.config.rules,oe.rules.includes(de)?oe.rules:[...oe.rules,de],oe.overrides??{},oe.transparent_wrappers??[]);if(!Se.ok){zy(xe);for(let Pe of Se.errors)console.error(Pe);return!1}if(!I.cleanup)return console.log(`Migrated legacy config at ${I.legacyPath}. Legacy file is no longer used.`),!0;if(!Vy(O.configTarget,ve,de,I.migratedFrom,K.config.rules))return console.error(`Migration cleanup verification failed for ${I.legacyPath}`),!1;return j(L),console.log(`Deleted legacy config at ${I.legacyPath}`),!0}async function Uy(_,I,O,L,J,K,ne,oe,de){try{return bn(O,{version:1,rules:ne,overrides:oe,transparent_wrappers:de}),bn(L,qy(J,I.migratedFrom,K)),await to(_,I.syncOptions)}catch(ue){return{ok:!1,errors:[ue instanceof Error?ue.message:String(ue)]}}}function Gy(_){try{let I=JSON.parse(_),O=go(I);if(O.errors.length>0)return{ok:!1,errors:O.errors};return{ok:!0,config:{version:1,rules:I.rules??[]}}}catch{return{ok:!1,errors:["Invalid JSON"]}}}function By(_,I,O,L,J){let K=I.find((ne)=>Jy(i(J,ro(_,ne,"rulebook.json")))===L);if(K)return K;if(n(i(J,ro(_,O,"rulebook.json")))===null)return O;for(let ne=2;;ne++){let oe=`${O}-${ne}`;if(n(i(J,ro(_,oe,"rulebook.json")))===null)return oe}}function qy(_,I,O){return{rulebook_version:1,name:_,version:"1.0.0",description:"Migrated CC Safety Net rules.",author:"project",migrated_from:I,allowed_commands:[...new Set(O.map((L)=>L.command))],rules:O,tests:O.map((L)=>({command:[L.command,L.subcommand,L.block_args[0]].filter(Boolean).join(" "),expect:"blocked",rule:L.name}))}}function Vy(_,I,O,L,J){if(!m(_).config?.rules.includes(O))return!1;try{let ne=n(I);if(ne===null)return!1;let oe=JSON.parse(ne);return oe.migrated_from===L&&JSON.stringify(oe.rules)===JSON.stringify(J)}catch{return!1}}function Jd(_){return{target:_,content:n(_)}}function zy(_){for(let I of _){if(I.content===null){j(I.target);continue}g(I.target,I.content)}}function Jy(_){let I=n(_);if(I===null)return null;try{let O=JSON.parse(I);return typeof O.migrated_from==="string"?O.migrated_from:null}catch{return null}}import{mkdir as Wy,readFile as Ky,writeFile as Yy}from"node:fs/promises";import{dirname as Zy,join as Xy}from"node:path";var Qy=86400000,ev=604800000;async function Yd(_,I=Date.now()){if(_.env.get("CC_SAFETY_NET_NO_UPDATE_CHECK"))return null;let O=He(_);if(!O)return null;let L=Xy(O,".cc-safety-net","update-check.json"),J=await nv(L,I);if(!J.lastCheck||I-J.lastCheck>Qy){let oe=await Gn();if(J.lastCheck=I,oe.latestVersion)J.latestVersion=oe.latestVersion;if(!await Kd(L,J))return null;if(oe.error)return null}let K=J.latestVersion,ne=fn();if(!K||!ko(K,ne))return null;if(J.notifiedVersion===K&&J.notifiedAt!==void 0&&I-J.notifiedAt<ev)return null;if(J.notifiedVersion=K,J.notifiedAt=I,!await Kd(L,J))return null;return`UPDATE_AVAILABLE: cc-safety-net v${K} is available (running v${ne}). Ask the user once whether to run \`npx -y cc-safety-net@latest update\`; continue the current task either way and do not raise this again.`}async function nv(_,I){let O=await Ky(_,"utf8").then((K)=>JSON.parse(K)).catch(()=>{return});if(!O||typeof O!=="object"||Array.isArray(O))return{};let L=O,J=(K)=>typeof K==="number"&&Number.isFinite(K)&&K<=I?K:void 0;return{lastCheck:J(L.lastCheck),latestVersion:typeof L.latestVersion==="string"?L.latestVersion:void 0,notifiedVersion:typeof L.notifiedVersion==="string"?L.notifiedVersion:void 0,notifiedAt:J(L.notifiedAt)}}async function Kd(_,I){return Wy(Zy(_),{recursive:!0,mode:448}).then(()=>Yy(_,JSON.stringify(I),{mode:384})).then(()=>!0).catch(()=>!1)}import{join as tv,resolve as Gi}from"node:path";var Zd="CC Safety Net Config",rv="═".repeat(Zd.length),ov="https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json",iv=new Set(["rule.json","rule.lock","cache"]);function Xd(_,I={}){try{return sv(_,I)}catch(O){if(O instanceof r)return console.error(O.message),1;throw O}}function sv(_,I){let O=I.cwd??process.cwd(),L=Z(_,{cwd:O}),J=ur(_),K=bs(O),ne=Gi(O,me),oe=i(L.userScope,J),de=i(L.projectScope,K),ue=!1,ve=!1,xe=[],Se=[],Pe=av(i(L.projectScope,ne));if(cv(),n(L.userConfigTarget)!==null){let we=Un(L.userConfigTarget);if(we.errors.push(...H(L.userConfigPath,L.userScope)),xe.push({scope:"User",path:L.userConfigPath,result:we,schema:"rules",target:L.userConfigTarget}),we.errors.length>0)ue=!0}if(n(oe)!==null)if(ve=!0,n(L.userConfigTarget)!==null)Se.push(oo("user","cleanup"));else{let we=ho(oe);if(xe.push({scope:"User",path:J,result:we,schema:"legacy",inactive:!0,target:oe}),Se.push(oo("user",we.errors.length>0?"fix-or-delete":"migrate")),we.errors.length>0)ue=!0}if(n(L.projectConfigTarget)!==null){let we=Un(L.projectConfigTarget);if(we.errors.push(...H(L.projectConfigPath,L.projectScope)),xe.push({scope:"Project",path:Gi(L.projectConfigPath),result:we,schema:"rules",target:L.projectConfigTarget}),we.errors.length>0)ue=!0;if(n(de)!==null)ve=!0,Se.push(oo("project","cleanup"))}else if(n(de)!==null){ve=!0,ue=!0;let we=ho(de);xe.push({scope:"Project",path:Gi(K),result:we,schema:"legacy",inactive:!0,target:de}),Se.push(oo("project",we.errors.length>0?"fix-or-delete":"migrate"))}if(Pe?.result.errors.length)ue=!0;if(xe.length===0&&!Pe)return console.log(`
275
+ No config files found. Using built-in rules only.`),0;for(let we of xe)if(we.inactive)uv(we.scope,we.path,we.result);else if(we.result.errors.length>0)pv(we.scope,we.path,we.result.errors);else{if(we.schema==="rules"&&gv(we.target))console.log(`
276
+ Added $schema to ${we.scope.toLowerCase()} config.`);dv(we.scope,we.path,we.result,we.schema)}for(let we of Se)console.error(`
277
+ ${nn.red(we)}`);if(Pe)if(Pe.result.errors.length>0)mv(Pe.path,Pe.result.errors);else fv(Pe.path,Pe.result);if(ue)return console.error(`
278
+ Config validation failed.`),1;return console.log(ve?`
278
279
  Configs valid with warnings.`:`
279
- All configs valid.`),0}function to(P,A){let q=`legacy ${P} config`;if(A==="cleanup")return`Warning: Legacy ${P} config is no longer needed. Run \`npx -y cc-safety-net rule migrate --cleanup\` to clean it up safely.`;if(A==="migrate")return`Warning: Legacy ${P} config is ignored by CC Safety Net. Run \`npx -y cc-safety-net rule migrate\`.`;return`Warning: Legacy ${P} config is no longer supported. Fix or delete the ${q}, then run \`npx -y cc-safety-net rule migrate\`.`}function $h(P){if(le(P)===null)return null;let A=Oh(P);if(A.ruleNames.size===0&&A.errors.length===0)return null;return{path:P.path,result:A}}function Oh(P){let A=[],q=new Set,V=(le(P)??[]).filter((ee)=>!Th.has(ee.name)).sort((ee,ne)=>ee.name.localeCompare(ne.name));if(V.length===0)return{errors:A,ruleNames:q};for(let ee of V){if(!l.test(ee.name)){A.push(`rulebook directory names must match ${l}: ${ee.name}`);continue}if(ee.kind!=="directory"){A.push(`${ee.name} must be a rulebook directory`);continue}let ne=i(P.scope,Dh(P.path,ee.name,"rulebook.json")),ce=n(ne);if(ce===null){A.push(`${ee.name}/rulebook.json is required`);continue}try{let he;try{he=JSON.parse(ce)}catch{A.push(`${ee.name}/rulebook.json: invalid JSON`);continue}let ye=se(he);if(ye.name!==ee.name){A.push(`rulebook name "${ye.name}" must match folder "${ee.name}"`);continue}let be=Jr(ye);if(be.length>0){A.push(...be.map((xe)=>`${ee.name}/rulebook.json: ${xe}`));continue}q.add(ee.name)}catch(he){A.push(he instanceof Error?`${ee.name}/rulebook.json: ${he.message}`:`${ee.name}/rulebook.json: ${String(he)}`)}}return{errors:A,ruleNames:q}}function Fh(){console.log(Dd),console.log(Ah)}function Nh(P,A,q,V){if(console.log(`
280
- ✓ ${P} config: ${A}`),console.log(` Schema: ${V==="rules"?"rulebook sources":"legacy inline rules"}`),q.ruleNames.size>0){console.log(` ${V==="rules"?"Sources":"Rules"}:`);let ee=1;for(let ne of q.ruleNames)console.log(` ${ee}. ${ne}`),ee++}else console.log(` ${V==="rules"?"Sources":"Rules"}: (none)`)}function jh(P,A,q){if(console.error(`
281
- ✗ Legacy ${P.toLowerCase()} config: ${A}`),console.error(" Schema: legacy inline rules"),console.error(" Status: ignored by CC Safety Net"),q.errors.length>0){console.error(" Errors:");let V=1;for(let ee of q.errors)for(let ne of ee.split("; "))console.error(` ${V}. ${ne}`),V++;return}if(q.ruleNames.size>0){console.error(" Rules:");let V=1;for(let ee of q.ruleNames)console.error(` ${V}. ${ee}`),V++;return}console.error(" Rules: (none)")}function Mh(P,A,q){_d(`${P} config`,A,q)}function Hh(P,A){console.log(`
282
- ✓ GitHub source rules: ${P}`),console.log(" Rulebooks:");let q=1;for(let V of A.ruleNames)console.log(` ${q}. ${V}`),q++}function Uh(P,A){_d("GitHub source rules",P,A)}function _d(P,A,q){console.error(`
283
- ✗ ${P}: ${A}`),console.error(" Errors:");let V=1;for(let ee of q)for(let ne of ee.split("; "))console.error(` ${V}. ${ne}`),V++}function Gh(P){try{let A=n(P);if(A===null)return!1;let q=JSON.parse(A);if(q.$schema)return!1;return g(P,JSON.stringify({$schema:_h,...q},null,2)),!0}catch(A){if(A instanceof r)throw A;return!1}}var Td=new Set(["init","add","remove","update","sync","list","wrapper","migrate","doc","verify"]),qh=new Set(["add","remove","list"]),Vh="cc-safety-net/rulebooks";async function Id(P,A){try{return await zh(P,A)}catch(q){if(q instanceof r)return console.error(q.message),1;throw q}}async function zh(P,A){let q=Wh(A),V=q.help?Jh(q.positionals):null;if(V)return Cn(V),0;if(q.errors.length>0){for(let he of q.errors)console.error(he);return 1}let ee=q.positionals[0];if(!ee)return Cn(gn,console.error),1;let ne=q.positionals[1],ce={global:q.global};if(ee==="init"){let he=Et(P,ce);Zh(he.configTarget);let ye=Bh(he.configDir,"example-rules","rulebook.json"),be=i(he.filesystemScope,ye);if(q.example&&n(be)===null)nd(be);let xe=U(he.configPath,he.filesystemScope);for(let Ie of xe)console.error(Ie);if(xe.length>0)return 1;return console.log("Rule config initialized."),0}if(ee==="add"){let he=$d(q);if(!he)return console.error("rule add requires a source (pass --only <rulebook...> to select from cc-safety-net/rulebooks)"),1;let ye=Et(P,ce),be=await Ld(P,he,{...ce,ref:q.ref,rulebooks:q.only.length>0?q.only:void 0});return Xc(be,he,`Scope: ${q.global?"user":"project"} (${ye.configDir})`),be.ok?0:1}if(ee==="remove"){if(!ne)return console.error("rule remove requires a source"),1;let he=await wd(P,ne,{...ce,deleteSource:q.deleteSource});return zr(he,`Removed rulebook source: ${ne}`),he.ok?0:1}if(ee==="update"){let he=await Qr(P,{...ce,only:ne,refresh:!0});return zr(he,"Rule config updated."),he.ok?0:1}if(ee==="sync")return Bs(P,{global:q.global});if(ee==="list"){let he=Y(P,{cwd:process.cwd()});return Qc(he),he.errors.length>0?1:0}if(ee==="wrapper")return Qh(P,q);if(ee==="migrate")return Rd(P,{cleanup:q.cleanup,cwd:process.cwd()});if(ee==="doc"){console.log(Kc);let he=await Ed(P);if(he)console.error(he);return 0}if(ee==="verify")return Ad(P);return 1}function Jh(P){if(P.length===0)return gn;let A=gn.subcommands.filter((V)=>V.usage.split(" ")[0]===P[0]);if(A.length===0)return null;if(P.length===1&&A.length>1)return{name:`rule ${P[0]}`,description:`Subcommands of rule ${P[0]}`,usage:`rule ${P[0]} <subcommand>`,subcommands:A,options:[]};let q=P.length===1?A[0]:A.find((V)=>V.usage.split(" ")[1]===P[1]);if(!q)return null;return{name:`rule ${P[0]}`,description:q.description,usage:`rule ${q.usage}`,options:P[0]==="add"?ao:[],examples:P[0]==="add"?lo:void 0}}function Wh(P){let A=xt({label:"rule",booleans:{global:["-g","--global"],cleanup:["--cleanup"],deleteSource:["--delete-source"],example:["--example"]},values:{ref:["--ref"]},lists:{only:["--only"]},positionals:"list"},P),q={...A.flags,ref:A.values.ref,only:A.lists.only??[],help:A.help,positionals:A.positionals,errors:A.errors};return Kh(q),q}function Kh(P){let[A]=P.positionals;if(A&&!Td.has(A))P.errors.push(`Unknown rule subcommand: ${A}`);if(P.deleteSource&&A!=="remove")if(A&&Td.has(A))P.errors.push(`Unknown option for rule ${A}: --delete-source`);else P.errors.push("--delete-source is only valid with 'rule remove'");if(P.cleanup&&A!=="migrate")P.errors.push(er(A,"--cleanup"));if(P.example&&A!=="init")P.errors.push(er(A,"--example"));if(P.ref&&A!=="add")P.errors.push(er(A,"--ref"));if(P.only.length>0&&A!=="add")P.errors.push(er(A,"--only"));if(A==="add")Yh(P);if(A==="migrate"){if(P.global)P.errors.push(er(A,"--global"));if(P.positionals.length>1)P.errors.push(`Unexpected rule migrate argument: ${P.positionals[1]}`)}else if(A==="wrapper")Xh(P);else if(P.positionals.length>2)P.errors.push(`Unexpected rule argument: ${P.positionals[2]}`);if(A==="list"&&P.global)P.errors.push("Unknown option for rule list: --global")}function $d(P){if(P.positionals[1])return P.positionals[1];if(P.ref||P.only.length>0)return Vh;return}function Yh(P){let A=$d(P);if(!A)return;if((P.ref||P.only.length>0)&&!K(A)){if(P.ref)P.errors.push(`--ref can only select a ref for an owner/repo source: ${A}`);if(P.only.length>0)P.errors.push("--only can only select rulebooks from an owner/repo source");return}if(P.ref&&!oe(P.ref))P.errors.push(`--ref must use valid path segments: ${P.ref}`);let q=P.only.filter((V)=>!l.test(V));if(q.length>0)P.errors.push(`Invalid rulebook names: ${q.join(", ")}`)}function er(P,A){return P?`Unknown option for rule ${P}: ${A}`:`Unknown option for rule: ${A}`}function Xh(P){let A=P.positionals[1],q=P.positionals[2];if(!A){P.errors.push("rule wrapper requires add, remove, or list");return}if(!qh.has(A)){P.errors.push(`Unknown rule wrapper action: ${A}`);return}if(A==="list"){if(q)P.errors.push(`Unexpected rule wrapper argument: ${q}`);return}if(!q){P.errors.push(`rule wrapper ${A} requires a command`);return}if(P.positionals.length>3)P.errors.push(`Unexpected rule wrapper argument: ${P.positionals[3]}`)}function Zh(P){if(n(P)===null){td(P);return}let A=m(P);if(!A.config)return;Pt(P,{version:1,rules:A.config.rules,overrides:A.config.overrides??{},transparent_wrappers:A.config.transparent_wrappers??[]})}async function Qh(P,A){let q=A.positionals[1],V=A.positionals[2],ee=Et(P,{global:A.global}).configTarget;if(q==="list"){let ye=m(ee);if(ye.errors.length>0){for(let be of ye.errors)console.error(be);return 1}return ey(ye.config?.transparent_wrappers??[]),0}if(!V||!w.test(V))return console.error("transparent wrapper must match command pattern"),1;if(Le(V))return console.error(`reserved command "${V}" cannot be a wrapper`),1;let ne=m(ee);if(ne.errors.length>0){for(let ye of ne.errors)console.error(ye);return 1}let ce=ne.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},he=q==="add"?[...new Set([...ce.transparent_wrappers??[],V])]:(ce.transparent_wrappers??[]).filter((ye)=>ye!==V);return Pt(ee,{version:1,rules:ce.rules,overrides:ce.overrides??{},transparent_wrappers:he}),console.log(q==="add"?`Added transparent wrapper: ${V}`:`Removed transparent wrapper: ${V}`),0}function ey(P){if(P.length===0){console.log("Transparent wrappers: (none)");return}console.log(`Transparent wrappers (${P.length}):`);for(let A of P)console.log(` - ${A}`)}import{sep as sy}from"node:path";import{existsSync as ty,readFileSync as ny}from"node:fs";import{join as ry}from"node:path";async function oy(P){if(P.isTTY)return null;return(await We(P).catch(()=>null))?.trim()||null}function iy(P){let A=P.env.get("CLAUDE_SETTINGS_PATH");if(A)return A;return ry(vr(P),"settings.json")}function Ii(P){let A=iy(P);if(!ty(A))return!1;try{let q=ny(A,"utf-8"),V=JSON.parse(q);if(!V.enabledPlugins)return!1;let ee="cc-safety-net@cc-marketplace";if(!(ee in V.enabledPlugins))return!1;return V.enabledPlugins[ee]===!0}catch(q){if(L(o.debug,P.env))console.error(`CC Safety Net debug: failed to read Claude settings: ${A}: ${q instanceof Error?q.message:String(q)}`);return!1}}async function $i(P,A=process.stdin){let q=Ii(P),V;if(!q)V="\uD83D\uDEE1️ CC Safety Net ❌";else{let ne=E(P,{cwd:process.cwd()}),ce=ne.policy,he=R(ce,P.env),ye=Object.values(H(ce,he.capabilities)).some((Ie)=>Ie.changesInherited),be={standard:"✅",strict:"\uD83D\uDD12",paranoid:"\uD83D\uDC41️",custom:"\uD83D\uDD27"}[ye?"custom":he.effectiveLevel],xe=(ne.policyScopes?.weakenings.length??0)>0?"\uD83D\uDD3B":"";V=`\uD83D\uDEE1️ CC Safety Net ${be}${he.worktreeMode?"\uD83C\uDF33":""}${xe}${ne.state==="degraded"?"⚠️":""}`}let ee=await oy(A);if(ee&&!ee.startsWith("{"))console.log(`${ee} | ${V}`);else console.log(V)}function Od(P){let A=E(P,{cwd:process.cwd()}),q=A.policy,V=R(q,P.env),ee=!!process.env.NO_COLOR||!process.stdout.isTTY,ne=Math.min(process.stdout.columns||80,100),ce=ee?"ok":"✔",he=ee?"OFF":"✘",ye=(at,ct)=>{let lt=` ${at.padEnd(13)}${ct}`;return(lt.length>ne?`${lt.slice(0,ne-1)}…`:lt).replaceAll(he,dt.red(he))},be=Object.values(H(q,V.capabilities)).some((at)=>at.changesInherited),xe=(at)=>at===P.home||at.startsWith(`${P.home}${sy}`)?`~${at.slice(P.home.length)}`:at,Ie={ready:dt.green,degraded:dt.yellow}[A.state],Xe=A.policyScopes?.weakenings??[],et=[...Ii(P)?[]:["plugin cc-safety-net@cc-marketplace is disabled in Claude Code; nothing is enforced in Claude Code until it is re-enabled. Other integrations are not affected."],...A.diagnostics],Re=ee?"-":"·";console.log([`${ee?"":"\uD83D\uDEE1️ "}CC Safety Net — ${Ie(A.state)}`,"",ye("Protection",`destructive ${q.destructiveCommandProtectionEnabled?ce:he} secrets ${q.secretProtection.enabled?ce:he}`),ye("Level",be?`${V.effectiveLevel} (customised)`:V.effectiveLevel),ye("Rules",q.rules.length===0?"none active":`${q.rules.length} active`),ye("Policy",xe(u(P))),...A.policyScopes?[ye("Project",xe(b(process.cwd())))]:[],...V.worktreeMode?[ye("Worktree","relaxations active")]:[],"",...Xe.length===0?[]:[" Project policy",...Xe.flatMap((at)=>Bn(at," ",ne-6).map((ct,lt)=>lt===0?` ${ct}`:ct)),""],...et.length===0?[" Everything configured is active."]:[" Not active",...et.flatMap((at)=>Bn(at," ",ne-6).map((ct,lt)=>lt===0?` ${Re} ${ct}`:ct)),""," Full report: cc-safety-net doctor"]].join(`
284
- `))}import{spawn as zd}from"node:child_process";import{randomBytes as hy}from"node:crypto";import{existsSync as yy}from"node:fs";import{createServer as vy}from"node:http";import{Writable as by}from"node:stream";var no=500;function ay(P){let A=P.filter((ee)=>ee.decision!=="allow"),q=P.filter((ee)=>ee.decision==="allow"),V=Math.min(A.length,Math.max(no-q.length,Math.ceil(no/2)));return[...A.slice(0,V),...q.slice(0,no-V)]}function Fd(P,A,q=D(P)){if(q)z(P,q);let V=(ct)=>new Date(ct.getFullYear(),ct.getMonth(),ct.getDate()).getTime(),ee=V(new Date),ne=new Date(ee);ne.setDate(ne.getDate()-(A-1));let ce=ne.getTime(),he=[],ye={count:0};for(let ct of q?Xt(q,ye):[])for(let lt of mn(ct,ye)){let ft=new Date(lt.ts).getTime();if(!Number.isFinite(ft))continue;if(ft>=ce)he.push(lt)}he.sort((ct,lt)=>new Date(lt.ts).getTime()-new Date(ct.ts).getTime());let be=Array.from({length:A},()=>0),xe=Array.from({length:A},()=>0),Ie={},Xe={},et={},Re=0,at=0;for(let ct of he){let lt=ct.agent||"unknown";Ie[lt]=(Ie[lt]??0)+1;let ft=Math.round((ee-V(new Date(ct.ts)))/86400000),mt=A-1-ft,gt=ft>=0&&ft<A;if(gt)xe[mt]=(xe[mt]??0)+1;if(ct.decision!=="allow"){if(Re++,ct.ruleId)Xe[ct.ruleId]=(Xe[ct.ruleId]??0)+1;let ut=so(ct.segment||ct.command);if(ut)et[ut]=(et[ut]??0)+1;if(ct.failureStage)at++;if(gt)be[mt]=(be[mt]??0)+1}}return{days:A,logsDir:q,homeDir:P.home,totalInWindow:he.length,truncated:he.length>no,unreadable:ye.count,counts:{blocked:Re,allowed:he.length-Re,agents:Ie,blockedByDay:be,analyzedByDay:xe,rules:Xe,commands:et,errors:at},entries:ay(he).sort((ct,lt)=>new Date(lt.ts).getTime()-new Date(ct.ts).getTime())}}import{spawn as ly}from"node:child_process";import{existsSync as cy,statSync as Nd}from"node:fs";import{delimiter as dy,join as uy}from"node:path";var py=120000,ro="Choose the project folder",fy=`try
285
- return POSIX path of (choose folder with prompt "${ro}")
280
+ All configs valid.`),0}function oo(_,I){let O=`legacy ${_} config`;if(I==="cleanup")return`Warning: Legacy ${_} config is no longer needed. Run \`npx -y cc-safety-net rule migrate --cleanup\` to clean it up safely.`;if(I==="migrate")return`Warning: Legacy ${_} config is ignored by CC Safety Net. Run \`npx -y cc-safety-net rule migrate\`.`;return`Warning: Legacy ${_} config is no longer supported. Fix or delete the ${O}, then run \`npx -y cc-safety-net rule migrate\`.`}function av(_){if(pe(_)===null)return null;let I=lv(_);if(I.ruleNames.size===0&&I.errors.length===0)return null;return{path:_.path,result:I}}function lv(_){let I=[],O=new Set,L=(pe(_)??[]).filter((J)=>!iv.has(J.name)).sort((J,K)=>J.name.localeCompare(K.name));if(L.length===0)return{errors:I,ruleNames:O};for(let J of L){if(!u.test(J.name)){I.push(`rulebook directory names must match ${u}: ${J.name}`);continue}if(J.kind!=="directory"){I.push(`${J.name} must be a rulebook directory`);continue}let K=i(_.scope,tv(_.path,J.name,"rulebook.json")),ne=n(K);if(ne===null){I.push(`${J.name}/rulebook.json is required`);continue}try{let oe;try{oe=JSON.parse(ne)}catch{I.push(`${J.name}/rulebook.json: invalid JSON`);continue}let de=ce(oe);if(de.name!==J.name){I.push(`rulebook name "${de.name}" must match folder "${J.name}"`);continue}let ue=Yr(de);if(ue.length>0){I.push(...ue.map((ve)=>`${J.name}/rulebook.json: ${ve}`));continue}O.add(J.name)}catch(oe){I.push(oe instanceof Error?`${J.name}/rulebook.json: ${oe.message}`:`${J.name}/rulebook.json: ${String(oe)}`)}}return{errors:I,ruleNames:O}}function cv(){console.log(Zd),console.log(rv)}function dv(_,I,O,L){if(console.log(`
281
+ ✓ ${_} config: ${I}`),console.log(` Schema: ${L==="rules"?"rulebook sources":"legacy inline rules"}`),O.ruleNames.size>0){console.log(` ${L==="rules"?"Sources":"Rules"}:`);let J=1;for(let K of O.ruleNames)console.log(` ${J}. ${K}`),J++}else console.log(` ${L==="rules"?"Sources":"Rules"}: (none)`)}function uv(_,I,O){if(console.error(`
282
+ ✗ Legacy ${_.toLowerCase()} config: ${I}`),console.error(" Schema: legacy inline rules"),console.error(" Status: ignored by CC Safety Net"),O.errors.length>0){console.error(" Errors:");let L=1;for(let J of O.errors)for(let K of J.split("; "))console.error(` ${L}. ${K}`),L++;return}if(O.ruleNames.size>0){console.error(" Rules:");let L=1;for(let J of O.ruleNames)console.error(` ${L}. ${J}`),L++;return}console.error(" Rules: (none)")}function pv(_,I,O){Qd(`${_} config`,I,O)}function fv(_,I){console.log(`
283
+ ✓ GitHub source rules: ${_}`),console.log(" Rulebooks:");let O=1;for(let L of I.ruleNames)console.log(` ${O}. ${L}`),O++}function mv(_,I){Qd("GitHub source rules",_,I)}function Qd(_,I,O){console.error(`
284
+ ✗ ${_}: ${I}`),console.error(" Errors:");let L=1;for(let J of O)for(let K of J.split("; "))console.error(` ${L}. ${K}`),L++}function gv(_){try{let I=n(_);if(I===null)return!1;let O=JSON.parse(I);if(O.$schema)return!1;return g(_,JSON.stringify({$schema:ov,...O},null,2)),!0}catch(I){if(I instanceof r)throw I;return!1}}var eu=new Set(["init","add","remove","update","sync","list","wrapper","migrate","doc","verify"]),yv=new Set(["add","remove","list"]),vv="cc-safety-net/rulebooks";async function nu(_,I){try{return await bv(_,I)}catch(O){if(O instanceof r)return console.error(O.message),1;throw O}}async function bv(_,I){let O=kv(I),L=O.help?wv(O.positionals):null;if(L)return Pt(L),0;if(O.errors.length>0){for(let oe of O.errors)console.error(oe);return 1}let J=O.positionals[0];if(!J)return Pt(yt,console.error),1;let K=O.positionals[1],ne={global:O.global};if(J==="init"){let oe=wn(_,ne);Rv(oe.configTarget);let de=hv(oe.configDir,"example-rules","rulebook.json"),ue=i(oe.filesystemScope,de);if(O.example&&n(ue)===null)Cd(ue);let ve=H(oe.configPath,oe.filesystemScope);for(let xe of ve)console.error(xe);if(ve.length>0)return 1;return console.log("Rule config initialized."),0}if(J==="add"){let oe=tu(O);if(!oe)return console.error("rule add requires a source (pass --only <rulebook...> to select from cc-safety-net/rulebooks)"),1;let de=wn(_,ne),ue=await Gd(_,oe,{...ne,ref:O.ref,rulebooks:O.only.length>0?O.only:void 0});return bd(ue,oe,`Scope: ${O.global?"user":"project"} (${de.configDir})`),ue.ok?0:1}if(J==="remove"){if(!K)return console.error("rule remove requires a source"),1;let oe=await Bd(_,K,{...ne,deleteSource:O.deleteSource});return Kr(oe,`Removed rulebook source: ${K}`),oe.ok?0:1}if(J==="update"){let oe=await to(_,{...ne,only:K,refresh:!0});return Kr(oe,"Rule config updated."),oe.ok?0:1}if(J==="sync")return Qs(_,{global:O.global});if(J==="list"){let oe=X(_,{cwd:process.cwd()});return kd(oe),oe.errors.length>0?1:0}if(J==="wrapper")return Pv(_,O);if(J==="migrate")return Wd(_,{cleanup:O.cleanup,cwd:process.cwd()});if(J==="doc"){console.log(yd);let oe=await Yd(_);if(oe)console.error(oe);return 0}if(J==="verify")return Xd(_);return 1}function wv(_){if(_.length===0)return yt;let I=yt.subcommands.filter((L)=>L.usage.split(" ")[0]===_[0]);if(I.length===0)return null;if(_.length===1&&I.length>1)return{name:`rule ${_[0]}`,description:`Subcommands of rule ${_[0]}`,usage:`rule ${_[0]} <subcommand>`,subcommands:I,options:[]};let O=_.length===1?I[0]:I.find((L)=>L.usage.split(" ")[1]===_[1]);if(!O)return null;return{name:`rule ${_[0]}`,description:O.description,usage:`rule ${O.usage}`,options:_[0]==="add"?po:[],examples:_[0]==="add"?fo:void 0}}function kv(_){let I=gn({label:"rule",booleans:{global:["-g","--global"],cleanup:["--cleanup"],deleteSource:["--delete-source"],example:["--example"]},values:{ref:["--ref"]},lists:{only:["--only"]},positionals:"list"},_),O={...I.flags,ref:I.values.ref,only:I.lists.only??[],help:I.help,positionals:I.positionals,errors:I.errors};return xv(O),O}function xv(_){let[I]=_.positionals;if(I&&!eu.has(I))_.errors.push(`Unknown rule subcommand: ${I}`);if(_.deleteSource&&I!=="remove")if(I&&eu.has(I))_.errors.push(`Unknown option for rule ${I}: --delete-source`);else _.errors.push("--delete-source is only valid with 'rule remove'");if(_.cleanup&&I!=="migrate")_.errors.push(rr(I,"--cleanup"));if(_.example&&I!=="init")_.errors.push(rr(I,"--example"));if(_.ref&&I!=="add")_.errors.push(rr(I,"--ref"));if(_.only.length>0&&I!=="add")_.errors.push(rr(I,"--only"));if(I==="add")Sv(_);if(I==="migrate"){if(_.global)_.errors.push(rr(I,"--global"));if(_.positionals.length>1)_.errors.push(`Unexpected rule migrate argument: ${_.positionals[1]}`)}else if(I==="wrapper")Cv(_);else if(_.positionals.length>2)_.errors.push(`Unexpected rule argument: ${_.positionals[2]}`);if(I==="list"&&_.global)_.errors.push("Unknown option for rule list: --global")}function tu(_){if(_.positionals[1])return _.positionals[1];if(_.ref||_.only.length>0)return vv;return}function Sv(_){let I=tu(_);if(!I)return;if((_.ref||_.only.length>0)&&!Y(I)){if(_.ref)_.errors.push(`--ref can only select a ref for an owner/repo source: ${I}`);if(_.only.length>0)_.errors.push("--only can only select rulebooks from an owner/repo source");return}if(_.ref&&!se(_.ref))_.errors.push(`--ref must use valid path segments: ${_.ref}`);let O=_.only.filter((L)=>!u.test(L));if(O.length>0)_.errors.push(`Invalid rulebook names: ${O.join(", ")}`)}function rr(_,I){return _?`Unknown option for rule ${_}: ${I}`:`Unknown option for rule: ${I}`}function Cv(_){let I=_.positionals[1],O=_.positionals[2];if(!I){_.errors.push("rule wrapper requires add, remove, or list");return}if(!yv.has(I)){_.errors.push(`Unknown rule wrapper action: ${I}`);return}if(I==="list"){if(O)_.errors.push(`Unexpected rule wrapper argument: ${O}`);return}if(!O){_.errors.push(`rule wrapper ${I} requires a command`);return}if(_.positionals.length>3)_.errors.push(`Unexpected rule wrapper argument: ${_.positionals[3]}`)}function Rv(_){if(n(_)===null){Sd(_);return}let I=m(_);if(!I.config)return;bn(_,{version:1,rules:I.config.rules,overrides:I.config.overrides??{},transparent_wrappers:I.config.transparent_wrappers??[]})}async function Pv(_,I){let O=I.positionals[1],L=I.positionals[2],J=wn(_,{global:I.global}).configTarget;if(O==="list"){let de=m(J);if(de.errors.length>0){for(let ue of de.errors)console.error(ue);return 1}return Ev(de.config?.transparent_wrappers??[]),0}if(!L||!w.test(L))return console.error("transparent wrapper must match command pattern"),1;if(Ae(L))return console.error(`reserved command "${L}" cannot be a wrapper`),1;let K=m(J);if(K.errors.length>0){for(let de of K.errors)console.error(de);return 1}let ne=K.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},oe=O==="add"?[...new Set([...ne.transparent_wrappers??[],L])]:(ne.transparent_wrappers??[]).filter((de)=>de!==L);return bn(J,{version:1,rules:ne.rules,overrides:ne.overrides??{},transparent_wrappers:oe}),console.log(O==="add"?`Added transparent wrapper: ${L}`:`Removed transparent wrapper: ${L}`),0}function Ev(_){if(_.length===0){console.log("Transparent wrappers: (none)");return}console.log(`Transparent wrappers (${_.length}):`);for(let I of _)console.log(` - ${I}`)}import{sep as Ov}from"node:path";import{existsSync as Av,readFileSync as _v}from"node:fs";import{join as Iv}from"node:path";async function Tv(_){if(_.isTTY)return null;return(await qe(_).catch(()=>null))?.trim()||null}function $v(_){let I=_.env.get("CLAUDE_SETTINGS_PATH");if(I)return I;return Iv(kr(_),"settings.json")}function Bi(_){let I=$v(_);if(!Av(I))return!1;try{let O=_v(I,"utf-8"),L=JSON.parse(O);if(!L.enabledPlugins)return!1;let J="cc-safety-net@cc-marketplace";if(!(J in L.enabledPlugins))return!1;return L.enabledPlugins[J]===!0}catch(O){if(T(o.debug,_.env))console.error(`CC Safety Net debug: failed to read Claude settings: ${I}: ${O instanceof Error?O.message:String(O)}`);return!1}}async function qi(_,I=process.stdin){let O=Bi(_),L;if(!O)L="\uD83D\uDEE1️ CC Safety Net ❌";else{let K=E(_,{cwd:process.cwd()}),ne=K.policy,oe=R(ne,_.env),de=Object.values(B(ne,oe.capabilities)).some((xe)=>xe.changesInherited),ue={standard:"✅",strict:"\uD83D\uDD12",paranoid:"\uD83D\uDC41️",custom:"\uD83D\uDD27"}[de?"custom":oe.effectiveLevel],ve=(K.policyScopes?.weakenings.length??0)>0?"\uD83D\uDD3B":"";L=`\uD83D\uDEE1️ CC Safety Net ${ue}${oe.worktreeMode?"\uD83C\uDF33":""}${ve}${K.state==="degraded"?"⚠️":""}`}let J=await Tv(I);if(J&&!J.startsWith("{"))console.log(`${J} | ${L}`);else console.log(L)}function ru(_){let I=E(_,{cwd:process.cwd()}),O=I.policy,L=R(O,_.env),J=!!process.env.NO_COLOR||!process.stdout.isTTY,K=Math.min(process.stdout.columns||80,100),ne=J?"ok":"✔",oe=J?"OFF":"✘",de=(Le,en)=>{let Ve=` ${Le.padEnd(13)}${en}`;return(Ve.length>K?`${Ve.slice(0,K-1)}…`:Ve).replaceAll(oe,nn.red(oe))},ue=Object.values(B(O,L.capabilities)).some((Le)=>Le.changesInherited),ve=(Le)=>Le===_.home||Le.startsWith(`${_.home}${Ov}`)?`~${Le.slice(_.home.length)}`:Le,xe={ready:nn.green,degraded:nn.yellow}[I.state],Se=I.policyScopes?.weakenings??[],Pe=[...Bi(_)?[]:["plugin cc-safety-net@cc-marketplace is disabled in Claude Code; nothing is enforced in Claude Code until it is re-enabled. Other integrations are not affected."],...I.diagnostics],we=J?"-":"·";console.log([`${J?"":"\uD83D\uDEE1️ "}CC Safety Net — ${xe(I.state)}`,"",de("Protection",`destructive ${O.destructiveCommandProtectionEnabled?ne:oe} secrets ${O.secretProtection.enabled?ne:oe}`),de("Level",ue?`${L.effectiveLevel} (customised)`:L.effectiveLevel),de("Rules",O.rules.length===0?"none active":`${O.rules.length} active`),de("Policy",ve(d(_))),...I.policyScopes?[de("Project",ve(b(process.cwd())))]:[],...L.worktreeMode?[de("Worktree","relaxations active")]:[],"",...Se.length===0?[]:[" Project policy",...Se.flatMap((Le)=>Vt(Le," ",K-6).map((en,Ve)=>Ve===0?` ${en}`:en)),""],...Pe.length===0?[" Everything configured is active."]:[" Not active",...Pe.flatMap((Le)=>Vt(Le," ",K-6).map((en,Ve)=>Ve===0?` ${we} ${en}`:en)),""," Full report: cc-safety-net doctor"]].join(`
285
+ `))}import{spawn as mu}from"node:child_process";import{randomBytes as Bv}from"node:crypto";import{existsSync as qv}from"node:fs";import{createServer as Vv}from"node:http";import{Writable as zv}from"node:stream";var io=500;function Dv(_){let I=_.filter((J)=>J.decision!=="allow"),O=_.filter((J)=>J.decision==="allow"),L=Math.min(I.length,Math.max(io-O.length,Math.ceil(io/2)));return[...I.slice(0,L),...O.slice(0,io-L)]}function ou(_,I,O=F(_)){if(O)q(_,O);let L=(en)=>new Date(en.getFullYear(),en.getMonth(),en.getDate()).getTime(),J=L(new Date),K=new Date(J);K.setDate(K.getDate()-(I-1));let ne=K.getTime(),oe=[],de={count:0};for(let en of O?zn(O,de):[])for(let Ve of ht(en,de)){let on=new Date(Ve.ts).getTime();if(!Number.isFinite(on))continue;if(on>=ne)oe.push(Ve)}oe.sort((en,Ve)=>new Date(Ve.ts).getTime()-new Date(en.ts).getTime());let ue=Array.from({length:I},()=>0),ve=Array.from({length:I},()=>0),xe={},Se={},Pe={},we=0,Le=0;for(let en of oe){let Ve=en.agent||"unknown";xe[Ve]=(xe[Ve]??0)+1;let on=Math.round((J-L(new Date(en.ts)))/86400000),sn=I-1-on,an=on>=0&&on<I;if(an)ve[sn]=(ve[sn]??0)+1;if(en.decision!=="allow"){if(we++,en.ruleId)Se[en.ruleId]=(Se[en.ruleId]??0)+1;let rn=co(en.segment||en.command);if(rn)Pe[rn]=(Pe[rn]??0)+1;if(en.failureStage)Le++;if(an)ue[sn]=(ue[sn]??0)+1}}return{days:I,logsDir:O,homeDir:_.home,totalInWindow:oe.length,truncated:oe.length>io,unreadable:de.count,counts:{blocked:we,allowed:oe.length-we,agents:xe,blockedByDay:ue,analyzedByDay:ve,rules:Se,commands:Pe,errors:Le},entries:Dv(oe).sort((en,Ve)=>new Date(Ve.ts).getTime()-new Date(en.ts).getTime())}}import{spawn as Lv}from"node:child_process";import{existsSync as Nv,statSync as iu}from"node:fs";import{delimiter as jv,join as Fv}from"node:path";var Hv=120000,so="Choose the project folder",Mv=`try
286
+ return POSIX path of (choose folder with prompt "${so}")
286
287
  on error number -128
287
288
  return ""
288
- end try`,my=`Add-Type -AssemblyName System.Windows.Forms
289
+ end try`,Uv=`Add-Type -AssemblyName System.Windows.Forms
289
290
  $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
290
- $dialog.Description = '${ro}'
291
- if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.Write($dialog.SelectedPath) }`,jd=[{binary:"zenity",args:["--file-selection","--directory",`--title=${ro}`]},{binary:"kdialog",args:["--getexistingdirectory",".","--title",ro]}],Md=(P,A)=>(A.PATH??"").split(dy).some((q)=>{if(q.length===0)return!1;try{let V=Nd(uy(q,P));return V.isFile()&&(V.mode&73)!==0}catch{return!1}});function Oi(P,A){if(P==="darwin"||P==="win32")return!0;if(P!=="linux")return!1;if(!A.DISPLAY&&!A.WAYLAND_DISPLAY)return!1;return jd.some((q)=>Md(q.binary,A))}function gy(P,A){if(P==="darwin")return{cmd:"osascript",args:["-e",fy]};if(P==="win32")return{cmd:"powershell.exe",args:["-NoProfile","-STA","-Command",my]};let q=jd.find((V)=>Md(V.binary,A));return q?{cmd:q.binary,args:q.args}:null}function Fi(P=process.platform,A=process.env){let q=gy(P,A);if(!q)return Promise.resolve({error:"No folder dialog is available on this system"});return new Promise((V)=>{let ee=ly(q.cmd,q.args,{env:A,stdio:["ignore","pipe","pipe"]}),ne="",ce=!1,he=(be)=>{if(ce)return;ce=!0,clearTimeout(ye),V(be)},ye=setTimeout(()=>{ee.kill(),he({error:"The folder dialog timed out"})},py);ee.stdout.on("data",(be)=>{ne+=be.toString()}),ee.on("error",()=>he({error:`Could not open the folder dialog (${q.cmd})`})),ee.on("close",()=>{let be=ne.trim().replace(/\/+$/,"");if(!be)return he({cancelled:!0});if(!cy(be)||!Nd(be).isDirectory())return he({error:"That selection is not a folder on disk"});he({path:be})})})}var Hd=`<!doctype html>
291
+ $dialog.Description = '${so}'
292
+ if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.Write($dialog.SelectedPath) }`,su=[{binary:"zenity",args:["--file-selection","--directory",`--title=${so}`]},{binary:"kdialog",args:["--getexistingdirectory",".","--title",so]}],au=(_,I)=>(I.PATH??"").split(jv).some((O)=>{if(O.length===0)return!1;try{let L=iu(Fv(O,_));return L.isFile()&&(L.mode&73)!==0}catch{return!1}});function Vi(_,I){if(_==="darwin"||_==="win32")return!0;if(_!=="linux")return!1;if(!I.DISPLAY&&!I.WAYLAND_DISPLAY)return!1;return su.some((O)=>au(O.binary,I))}function Gv(_,I){if(_==="darwin")return{cmd:"osascript",args:["-e",Mv]};if(_==="win32")return{cmd:"powershell.exe",args:["-NoProfile","-STA","-Command",Uv]};let O=su.find((L)=>au(L.binary,I));return O?{cmd:O.binary,args:O.args}:null}function zi(_=process.platform,I=process.env){let O=Gv(_,I);if(!O)return Promise.resolve({error:"No folder dialog is available on this system"});return new Promise((L)=>{let J=Lv(O.cmd,O.args,{env:I,stdio:["ignore","pipe","pipe"]}),K="",ne=!1,oe=(ue)=>{if(ne)return;ne=!0,clearTimeout(de),L(ue)},de=setTimeout(()=>{J.kill(),oe({error:"The folder dialog timed out"})},Hv);J.stdout.on("data",(ue)=>{K+=ue.toString()}),J.on("error",()=>oe({error:`Could not open the folder dialog (${O.cmd})`})),J.on("close",()=>{let ue=K.trim().replace(/\/+$/,"");if(!ue)return oe({cancelled:!0});if(!Nv(ue)||!iu(ue).isDirectory())return oe({error:"That selection is not a folder on disk"});oe({path:ue})})})}var lu=`<!doctype html>
292
293
  <html lang="en">
293
294
  <head>
294
295
  <meta charset="utf-8">
295
296
  <meta name="viewport" content="width=device-width, initial-scale=1">
296
297
  <title>CC Safety Net</title>
297
- <link rel="icon" href="data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%221254%22%20height%3D%221254%22%20viewBox%3D%2254%2023%201140%201140%22%20role%3D%22img%22%20aria-label%3D%22Safety%20net%20logo%20mesh%20variant%22%3E%0A%20%20%3Cdefs%3E%0A%20%20%20%20%3CradialGradient%20id%3D%22spot-0%22%20cx%3D%2250%25%22%20cy%3D%2250%25%22%20r%3D%2250%25%22%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%23f8fafc%22%20stop-opacity%3D%220.68%22%2F%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%2256%25%22%20stop-color%3D%22%23f8fafc%22%20stop-opacity%3D%220.29%22%2F%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%23f8fafc%22%20stop-opacity%3D%220%22%2F%3E%0A%20%20%20%20%3C%2FradialGradient%3E%0A%20%20%20%20%3CradialGradient%20id%3D%22spot-1%22%20cx%3D%2250%25%22%20cy%3D%2250%25%22%20r%3D%2250%25%22%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%237dd3fc%22%20stop-opacity%3D%220.58%22%2F%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%2256%25%22%20stop-color%3D%22%237dd3fc%22%20stop-opacity%3D%220.24%22%2F%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%237dd3fc%22%20stop-opacity%3D%220%22%2F%3E%0A%20%20%20%20%3C%2FradialGradient%3E%0A%20%20%20%20%3CradialGradient%20id%3D%22spot-2%22%20cx%3D%2250%25%22%20cy%3D%2250%25%22%20r%3D%2250%25%22%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%2364748b%22%20stop-opacity%3D%220.7%22%2F%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%2256%25%22%20stop-color%3D%22%2364748b%22%20stop-opacity%3D%220.29%22%2F%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%2364748b%22%20stop-opacity%3D%220%22%2F%3E%0A%20%20%20%20%3C%2FradialGradient%3E%0A%20%20%20%20%3CradialGradient%20id%3D%22spot-3%22%20cx%3D%2250%25%22%20cy%3D%2250%25%22%20r%3D%2250%25%22%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%230f172a%22%20stop-opacity%3D%220.9%22%2F%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%2256%25%22%20stop-color%3D%22%230f172a%22%20stop-opacity%3D%220.38%22%2F%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%230f172a%22%20stop-opacity%3D%220%22%2F%3E%0A%20%20%20%20%3C%2FradialGradient%3E%0A%20%20%20%20%3ClinearGradient%20id%3D%22edge%22%20x1%3D%2214%25%22%20y1%3D%228%25%22%20x2%3D%2288%25%22%20y2%3D%2294%25%22%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%23ffffff%22%20stop-opacity%3D%220.7%22%2F%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%2250%25%22%20stop-color%3D%22%23bae6fd%22%20stop-opacity%3D%220.24%22%2F%3E%0A%20%20%20%20%20%20%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%231e293b%22%20stop-opacity%3D%220.86%22%2F%3E%0A%20%20%20%20%3C%2FlinearGradient%3E%0A%20%20%20%20%3Cmask%20id%3D%22net-mask%22%20maskUnits%3D%22userSpaceOnUse%22%3E%0A%20%20%20%20%20%20%3Crect%20width%3D%221254%22%20height%3D%221254%22%20fill%3D%22black%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-46.32%22%20y%3D%22-47.38%22%20width%3D%2292.63%22%20height%3D%2294.75%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(628.75%20127.25)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-66.82%22%20y%3D%22-41.01%22%20width%3D%22133.64%22%20height%3D%2282.02%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(713.75%20230.25)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.95%22%20y%3D%22-134.00%22%20width%3D%2279.90%22%20height%3D%22267.99%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(588.00%20275.50)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.60%22%20y%3D%22-65.05%22%20width%3D%2279.20%22%20height%3D%22130.11%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(444.50%20320.50)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-133.29%22%20y%3D%22-40.31%22%20width%3D%22266.58%22%20height%3D%2280.61%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(759.75%20369.25)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-77.07%22%20y%3D%22-39.24%22%20width%3D%22154.15%22%20height%3D%2278.49%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(533.25%20407.25)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-67.10%22%20y%3D%22-39.74%22%20width%3D%22134.21%22%20height%3D%2279.48%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(895.22%20413.86)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.84%22%20y%3D%22-134.04%22%20width%3D%2279.68%22%20height%3D%22268.08%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(401.36%20461.24)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.60%22%20y%3D%22-74.60%22%20width%3D%2279.20%22%20height%3D%22149.20%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(812.25%20500.25)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.60%22%20y%3D%22-77.43%22%20width%3D%2279.20%22%20height%3D%22154.86%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(625.75%20500.75)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.24%22%20y%3D%22-67.18%22%20width%3D%2278.49%22%20height%3D%22134.35%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(263.25%20505.75)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-133.28%22%20y%3D%22-40.02%22%20width%3D%22266.56%22%20height%3D%2280.04%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(941.36%20551.76)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-54.80%22%20y%3D%22-53.74%22%20width%3D%22109.60%22%20height%3D%22107.48%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(1096.75%20593.25)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-77.43%22%20y%3D%22-40.31%22%20width%3D%22154.86%22%20height%3D%2280.61%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(719.75%20594.25)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-51.97%22%20y%3D%22-54.45%22%20width%3D%22103.94%22%20height%3D%22108.89%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(155.25%20594.75)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-76.37%22%20y%3D%22-40.31%22%20width%3D%22152.74%22%20height%3D%2280.61%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(534.50%20595.50)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-135.12%22%20y%3D%22-40.16%22%20width%3D%22270.23%22%20height%3D%2280.32%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(307.96%20634.94)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-40.02%22%20y%3D%22-70.64%22%20width%3D%2280.05%22%20height%3D%22141.27%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(989.66%20680.72)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-38.90%22%20y%3D%22-77.27%22%20width%3D%2277.80%22%20height%3D%22154.54%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(442.49%20687.00)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.95%22%20y%3D%22-77.43%22%20width%3D%2279.90%22%20height%3D%22154.86%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(628.50%20689.00)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.40%22%20y%3D%22-134.46%22%20width%3D%2278.80%22%20height%3D%22268.92%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(853.69%20727.31)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-69.65%22%20y%3D%22-38.18%22%20width%3D%22139.30%22%20height%3D%2276.37%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(353.25%20771.75)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-78.44%22%20y%3D%22-39.44%22%20width%3D%22156.88%22%20height%3D%2278.88%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(720.61%20782.02)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-133.77%22%20y%3D%22-39.86%22%20width%3D%22267.53%22%20height%3D%2279.71%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(493.85%20820.81)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.24%22%20y%3D%22-66.82%22%20width%3D%2278.49%22%20height%3D%22133.64%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(806.50%20868.00)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-40.02%22%20y%3D%22-133.39%22%20width%3D%2280.05%22%20height%3D%22266.79%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(666.35%20914.10)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-67.18%22%20y%3D%22-39.60%22%20width%3D%22134.35%22%20height%3D%2279.20%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(540.00%20960.00)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-49.85%22%20y%3D%22-49.50%22%20width%3D%2299.70%22%20height%3D%2298.99%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(627.25%201064.75)%20rotate(-45.00)%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%3C%2Fmask%3E%0A%20%20%3C%2Fdefs%3E%0A%20%20%3Cg%3E%0A%20%20%20%20%3Cg%20mask%3D%22url(%23net-mask)%22%3E%0A%20%20%20%20%20%20%3Crect%20width%3D%221254%22%20height%3D%221254%22%20fill%3D%22%2307090d%22%2F%3E%0A%20%20%20%20%20%20%3Ccircle%20cx%3D%22360%22%20cy%3D%22240%22%20r%3D%22430%22%20fill%3D%22url(%23spot-0)%22%2F%3E%0A%20%20%20%20%20%20%3Ccircle%20cx%3D%22820%22%20cy%3D%22300%22%20r%3D%22430%22%20fill%3D%22url(%23spot-1)%22%2F%3E%0A%20%20%20%20%20%20%3Ccircle%20cx%3D%22760%22%20cy%3D%22830%22%20r%3D%22500%22%20fill%3D%22url(%23spot-2)%22%2F%3E%0A%20%20%20%20%20%20%3Ccircle%20cx%3D%22300%22%20cy%3D%22780%22%20r%3D%22390%22%20fill%3D%22url(%23spot-3)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20width%3D%221254%22%20height%3D%221254%22%20fill%3D%22url(%23edge)%22%20opacity%3D%220.18%22%2F%3E%0A%20%20%20%20%3C%2Fg%3E%0A%20%20%20%20%3Cg%20fill%3D%22none%22%20stroke%3D%22url(%23edge)%22%20stroke-width%3D%2214%22%20stroke-linejoin%3D%22round%22%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-46.32%22%20y%3D%22-47.38%22%20width%3D%2292.63%22%20height%3D%2294.75%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(628.75%20127.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-66.82%22%20y%3D%22-41.01%22%20width%3D%22133.64%22%20height%3D%2282.02%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(713.75%20230.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.95%22%20y%3D%22-134.00%22%20width%3D%2279.90%22%20height%3D%22267.99%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(588.00%20275.50)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.60%22%20y%3D%22-65.05%22%20width%3D%2279.20%22%20height%3D%22130.11%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(444.50%20320.50)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-133.29%22%20y%3D%22-40.31%22%20width%3D%22266.58%22%20height%3D%2280.61%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(759.75%20369.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-77.07%22%20y%3D%22-39.24%22%20width%3D%22154.15%22%20height%3D%2278.49%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(533.25%20407.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-67.10%22%20y%3D%22-39.74%22%20width%3D%22134.21%22%20height%3D%2279.48%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(895.22%20413.86)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.84%22%20y%3D%22-134.04%22%20width%3D%2279.68%22%20height%3D%22268.08%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(401.36%20461.24)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.60%22%20y%3D%22-74.60%22%20width%3D%2279.20%22%20height%3D%22149.20%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(812.25%20500.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.60%22%20y%3D%22-77.43%22%20width%3D%2279.20%22%20height%3D%22154.86%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(625.75%20500.75)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.24%22%20y%3D%22-67.18%22%20width%3D%2278.49%22%20height%3D%22134.35%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(263.25%20505.75)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-133.28%22%20y%3D%22-40.02%22%20width%3D%22266.56%22%20height%3D%2280.04%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(941.36%20551.76)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-54.80%22%20y%3D%22-53.74%22%20width%3D%22109.60%22%20height%3D%22107.48%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(1096.75%20593.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-77.43%22%20y%3D%22-40.31%22%20width%3D%22154.86%22%20height%3D%2280.61%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(719.75%20594.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-51.97%22%20y%3D%22-54.45%22%20width%3D%22103.94%22%20height%3D%22108.89%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(155.25%20594.75)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-76.37%22%20y%3D%22-40.31%22%20width%3D%22152.74%22%20height%3D%2280.61%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(534.50%20595.50)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-135.12%22%20y%3D%22-40.16%22%20width%3D%22270.23%22%20height%3D%2280.32%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(307.96%20634.94)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-40.02%22%20y%3D%22-70.64%22%20width%3D%2280.05%22%20height%3D%22141.27%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(989.66%20680.72)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-38.90%22%20y%3D%22-77.27%22%20width%3D%2277.80%22%20height%3D%22154.54%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(442.49%20687.00)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.95%22%20y%3D%22-77.43%22%20width%3D%2279.90%22%20height%3D%22154.86%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(628.50%20689.00)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.40%22%20y%3D%22-134.46%22%20width%3D%2278.80%22%20height%3D%22268.92%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(853.69%20727.31)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-69.65%22%20y%3D%22-38.18%22%20width%3D%22139.30%22%20height%3D%2276.37%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(353.25%20771.75)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-78.44%22%20y%3D%22-39.44%22%20width%3D%22156.88%22%20height%3D%2278.88%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(720.61%20782.02)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-133.77%22%20y%3D%22-39.86%22%20width%3D%22267.53%22%20height%3D%2279.71%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(493.85%20820.81)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.24%22%20y%3D%22-66.82%22%20width%3D%2278.49%22%20height%3D%22133.64%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(806.50%20868.00)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-40.02%22%20y%3D%22-133.39%22%20width%3D%2280.05%22%20height%3D%22266.79%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(666.35%20914.10)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-67.18%22%20y%3D%22-39.60%22%20width%3D%22134.35%22%20height%3D%2279.20%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(540.00%20960.00)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-49.85%22%20y%3D%22-49.50%22%20width%3D%2299.70%22%20height%3D%2298.99%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(627.25%201064.75)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%3C%2Fg%3E%0A%20%20%20%20%3Cg%20fill%3D%22none%22%20stroke%3D%22%23ffffff%22%20stroke-opacity%3D%220.2%22%20stroke-width%3D%225%22%20stroke-linejoin%3D%22round%22%20transform%3D%22translate(-10%20-14)%22%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-46.32%22%20y%3D%22-47.38%22%20width%3D%2292.63%22%20height%3D%2294.75%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(628.75%20127.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-66.82%22%20y%3D%22-41.01%22%20width%3D%22133.64%22%20height%3D%2282.02%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(713.75%20230.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.95%22%20y%3D%22-134.00%22%20width%3D%2279.90%22%20height%3D%22267.99%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(588.00%20275.50)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.60%22%20y%3D%22-65.05%22%20width%3D%2279.20%22%20height%3D%22130.11%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(444.50%20320.50)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-133.29%22%20y%3D%22-40.31%22%20width%3D%22266.58%22%20height%3D%2280.61%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(759.75%20369.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-77.07%22%20y%3D%22-39.24%22%20width%3D%22154.15%22%20height%3D%2278.49%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(533.25%20407.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-67.10%22%20y%3D%22-39.74%22%20width%3D%22134.21%22%20height%3D%2279.48%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(895.22%20413.86)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.84%22%20y%3D%22-134.04%22%20width%3D%2279.68%22%20height%3D%22268.08%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(401.36%20461.24)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.60%22%20y%3D%22-74.60%22%20width%3D%2279.20%22%20height%3D%22149.20%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(812.25%20500.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.60%22%20y%3D%22-77.43%22%20width%3D%2279.20%22%20height%3D%22154.86%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(625.75%20500.75)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.24%22%20y%3D%22-67.18%22%20width%3D%2278.49%22%20height%3D%22134.35%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(263.25%20505.75)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-133.28%22%20y%3D%22-40.02%22%20width%3D%22266.56%22%20height%3D%2280.04%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(941.36%20551.76)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-54.80%22%20y%3D%22-53.74%22%20width%3D%22109.60%22%20height%3D%22107.48%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(1096.75%20593.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-77.43%22%20y%3D%22-40.31%22%20width%3D%22154.86%22%20height%3D%2280.61%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(719.75%20594.25)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-51.97%22%20y%3D%22-54.45%22%20width%3D%22103.94%22%20height%3D%22108.89%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(155.25%20594.75)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-76.37%22%20y%3D%22-40.31%22%20width%3D%22152.74%22%20height%3D%2280.61%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(534.50%20595.50)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-135.12%22%20y%3D%22-40.16%22%20width%3D%22270.23%22%20height%3D%2280.32%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(307.96%20634.94)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-40.02%22%20y%3D%22-70.64%22%20width%3D%2280.05%22%20height%3D%22141.27%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(989.66%20680.72)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-38.90%22%20y%3D%22-77.27%22%20width%3D%2277.80%22%20height%3D%22154.54%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(442.49%20687.00)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.95%22%20y%3D%22-77.43%22%20width%3D%2279.90%22%20height%3D%22154.86%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(628.50%20689.00)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.40%22%20y%3D%22-134.46%22%20width%3D%2278.80%22%20height%3D%22268.92%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(853.69%20727.31)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-69.65%22%20y%3D%22-38.18%22%20width%3D%22139.30%22%20height%3D%2276.37%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(353.25%20771.75)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-78.44%22%20y%3D%22-39.44%22%20width%3D%22156.88%22%20height%3D%2278.88%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(720.61%20782.02)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-133.77%22%20y%3D%22-39.86%22%20width%3D%22267.53%22%20height%3D%2279.71%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(493.85%20820.81)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-39.24%22%20y%3D%22-66.82%22%20width%3D%2278.49%22%20height%3D%22133.64%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(806.50%20868.00)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-40.02%22%20y%3D%22-133.39%22%20width%3D%2280.05%22%20height%3D%22266.79%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(666.35%20914.10)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-67.18%22%20y%3D%22-39.60%22%20width%3D%22134.35%22%20height%3D%2279.20%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(540.00%20960.00)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20x%3D%22-49.85%22%20y%3D%22-49.50%22%20width%3D%2299.70%22%20height%3D%2298.99%22%20rx%3D%2212.00%22%20ry%3D%2212.00%22%20transform%3D%22translate(627.25%201064.75)%20rotate(-45.00)%22%2F%3E%0A%20%20%20%20%3C%2Fg%3E%0A%20%20%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A">
298
+ <link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22512%22%20height%3D%22512%22%20viewBox%3D%220%200%20512%20512%22%3E%3Crect%20width%3D%22512%22%20height%3D%22512%22%20rx%3D%22112%22%20fill%3D%22%2317161b%22%2F%3E%3Csvg%20x%3D%2240%22%20y%3D%2240%22%20width%3D%22432%22%20height%3D%22432%22%20viewBox%3D%22-172.38%20-172.38%20824.77%20824.77%22%3E%3Cg%20transform%3D%22rotate(45%20240%20240)%22%3E%3Crect%20x%3D%22-30%22%20y%3D%2214%22%20width%3D%22195%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%22315%22%20y%3D%2214%22%20width%3D%22195%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%22-30%22%20y%3D%2294%22%20width%3D%22115%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%22235%22%20y%3D%2294%22%20width%3D%22170%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%22155%22%20y%3D%22174%22%20width%3D%22170%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%2275%22%20y%3D%22254%22%20width%3D%22170%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%22395%22%20y%3D%22254%22%20width%3D%22115%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%22-30%22%20y%3D%22334%22%20width%3D%22195%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%22315%22%20y%3D%22334%22%20width%3D%22195%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%22-30%22%20y%3D%22414%22%20width%3D%22115%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%22235%22%20y%3D%22414%22%20width%3D%22170%22%20height%3D%2252%22%20rx%3D%229%22%20fill%3D%22%23f5f4f0%22%2F%3E%3Crect%20x%3D%2214%22%20y%3D%22155%22%20width%3D%2252%22%20height%3D%22170%22%20rx%3D%229%22%20fill%3D%22%23e5602a%22%2F%3E%3Crect%20x%3D%2294%22%20y%3D%2275%22%20width%3D%2252%22%20height%3D%22170%22%20rx%3D%229%22%20fill%3D%22%23e5602a%22%2F%3E%3Crect%20x%3D%2294%22%20y%3D%22395%22%20width%3D%2252%22%20height%3D%22115%22%20rx%3D%229%22%20fill%3D%22%23e5602a%22%2F%3E%3Crect%20x%3D%22174%22%20y%3D%22-30%22%20width%3D%2252%22%20height%3D%22195%22%20rx%3D%229%22%20fill%3D%22%23e5602a%22%2F%3E%3Crect%20x%3D%22174%22%20y%3D%22315%22%20width%3D%2252%22%20height%3D%22195%22%20rx%3D%229%22%20fill%3D%22%23e5602a%22%2F%3E%3Crect%20x%3D%22254%22%20y%3D%22-30%22%20width%3D%2252%22%20height%3D%22115%22%20rx%3D%229%22%20fill%3D%22%23e5602a%22%2F%3E%3Crect%20x%3D%22254%22%20y%3D%22235%22%20width%3D%2252%22%20height%3D%22170%22%20rx%3D%229%22%20fill%3D%22%23e5602a%22%2F%3E%3Crect%20x%3D%22334%22%20y%3D%22155%22%20width%3D%2252%22%20height%3D%22170%22%20rx%3D%229%22%20fill%3D%22%23e5602a%22%2F%3E%3Crect%20x%3D%22414%22%20y%3D%2275%22%20width%3D%2252%22%20height%3D%22170%22%20rx%3D%229%22%20fill%3D%22%23e5602a%22%2F%3E%3Crect%20x%3D%22414%22%20y%3D%22395%22%20width%3D%2252%22%20height%3D%22115%22%20rx%3D%229%22%20fill%3D%22%23e5602a%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%3C%2Fsvg%3E%0A">
298
299
  <script>
299
300
  (() => {
300
301
  const stored = localStorage.getItem('cc-safety-net-theme');
@@ -412,7 +413,7 @@ h1 {
412
413
 
413
414
  .brand-logo {
414
415
  display: flex;
415
- color: var(--ink);
416
+ color: light-dark(#17161b, #f5f4f0);
416
417
  }
417
418
 
418
419
  .brand-home {
@@ -2774,20 +2775,7 @@ textarea {
2774
2775
  <div class="app-shell">
2775
2776
  <aside class="sidebar">
2776
2777
  <div class="brand">
2777
- <h1 class="brand-logo"><a class="brand-home" href="#overview" title="Overview"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 512" role="img" aria-label="CC Safety Net">
2778
- <path d="M 1439 165 L 1411 165 L 1409 166 L 1408 168 L 1403 173 L 1403 174 L 1398 179 L 1398 180 L 1395 183 L 1394 183 L 1394 184 L 1385 194 L 1385 195 L 1381 199 L 1381 200 L 1378 202 L 1378 203 L 1374 207 L 1374 208 L 1367 215 L 1367 216 L 1358 226 L 1358 227 L 1352 233 L 1352 234 L 1347 239 L 1347 240 L 1341 246 L 1341 247 L 1336 252 L 1336 253 L 1332 257 L 1332 258 L 1325 265 L 1325 266 L 1319 272 L 1319 273 L 1314 278 L 1314 279 L 1309 284 L 1309 285 L 1303 291 L 1303 292 L 1299 296 L 1299 297 L 1294 302 L 1291 299 L 1290 300 L 1290 301 L 1293 301 L 1294 302 L 1288 309 L 1287 308 L 1288 309 L 1286 312 L 1285 311 L 1285 306 L 1286 305 L 1286 303 L 1288 299 L 1288 296 L 1289 295 L 1289 292 L 1290 291 L 1290 287 L 1291 286 L 1291 284 L 1293 280 L 1293 277 L 1294 276 L 1294 272 L 1295 271 L 1295 269 L 1297 265 L 1297 262 L 1298 261 L 1298 258 L 1299 257 L 1299 253 L 1300 252 L 1300 250 L 1301 249 L 1301 247 L 1303 243 L 1303 238 L 1304 237 L 1304 235 L 1305 234 L 1305 232 L 1307 228 L 1307 224 L 1308 223 L 1308 221 L 1309 220 L 1309 217 L 1310 216 L 1310 214 L 1312 210 L 1312 205 L 1314 202 L 1314 199 L 1316 195 L 1317 188 L 1318 187 L 1318 185 L 1319 184 L 1319 182 L 1321 178 L 1321 173 L 1323 169 L 1323 166 L 1296 166 L 1296 168 L 1294 171 L 1294 174 L 1293 175 L 1293 178 L 1292 179 L 1291 186 L 1290 187 L 1290 189 L 1289 190 L 1289 192 L 1287 196 L 1287 200 L 1285 204 L 1285 207 L 1283 211 L 1283 215 L 1282 216 L 1282 218 L 1281 219 L 1281 222 L 1279 226 L 1279 229 L 1278 230 L 1278 234 L 1277 235 L 1277 237 L 1276 238 L 1276 240 L 1274 244 L 1274 249 L 1273 250 L 1273 252 L 1271 256 L 1271 259 L 1270 260 L 1270 263 L 1269 264 L 1269 268 L 1268 269 L 1268 271 L 1266 275 L 1266 278 L 1265 279 L 1265 284 L 1264 285 L 1264 287 L 1262 291 L 1262 294 L 1261 295 L 1261 298 L 1260 299 L 1259 306 L 1258 307 L 1258 309 L 1257 310 L 1257 313 L 1256 314 L 1256 318 L 1254 322 L 1254 325 L 1273 325 L 1274 327 L 1273 328 L 1272 327 L 1273 328 L 1269 332 L 1269 333 L 1265 337 L 1265 338 L 1261 341 L 1261 342 L 1252 352 L 1252 353 L 1247 358 L 1247 359 L 1242 364 L 1242 365 L 1239 367 L 1239 368 L 1224 385 L 1224 386 L 1220 390 L 1220 391 L 1216 395 L 1216 396 L 1214 397 L 1214 399 L 1247 399 L 1249 397 L 1249 396 L 1259 385 L 1259 384 L 1263 380 L 1263 379 L 1265 377 L 1266 377 L 1266 376 L 1271 371 L 1271 370 L 1278 363 L 1278 362 L 1283 357 L 1283 356 L 1294 344 L 1294 343 L 1298 339 L 1298 338 L 1305 331 L 1305 330 L 1309 326 L 1309 325 L 1312 323 L 1313 320 L 1315 319 L 1316 317 L 1321 312 L 1322 312 L 1321 311 L 1330 301 L 1330 300 L 1335 295 L 1335 294 L 1337 292 L 1338 292 L 1339 289 L 1342 287 L 1342 286 L 1346 282 L 1346 281 L 1352 275 L 1352 274 L 1361 264 L 1361 263 L 1370 253 L 1370 252 L 1375 247 L 1375 246 L 1380 241 L 1380 240 L 1387 233 L 1387 232 L 1402 215 L 1402 214 L 1406 210 L 1406 209 L 1408 207 L 1409 207 L 1409 206 L 1413 202 L 1413 201 L 1418 196 L 1418 195 L 1422 191 L 1422 190 L 1427 185 L 1427 184 L 1431 180 L 1431 179 L 1440 169 L 1441 167 Z
2779
- M 1129 179 L 1126 178 L 1125 176 L 1124 176 L 1116 170 L 1114 170 L 1107 166 L 1105 166 L 1104 165 L 1101 165 L 1100 164 L 1096 164 L 1095 163 L 1091 163 L 1090 162 L 1081 162 L 1080 161 L 1076 161 L 1075 162 L 1066 162 L 1065 163 L 1061 163 L 1060 164 L 1057 164 L 1056 165 L 1051 165 L 1050 166 L 1045 167 L 1040 170 L 1038 170 L 1028 175 L 1023 179 L 1021 179 L 1017 183 L 1016 183 L 1012 187 L 1011 187 L 999 199 L 999 200 L 996 203 L 996 204 L 994 205 L 993 208 L 990 211 L 981 229 L 981 231 L 980 232 L 980 234 L 979 235 L 979 237 L 977 241 L 977 244 L 976 245 L 976 254 L 975 255 L 975 265 L 976 266 L 976 273 L 977 274 L 977 277 L 980 283 L 981 288 L 984 292 L 985 295 L 988 298 L 989 301 L 998 310 L 1001 311 L 1004 314 L 1007 315 L 1009 317 L 1013 319 L 1015 319 L 1018 321 L 1020 321 L 1024 323 L 1027 323 L 1028 324 L 1035 324 L 1036 325 L 1054 325 L 1055 324 L 1062 324 L 1063 323 L 1067 323 L 1068 322 L 1071 322 L 1077 319 L 1080 319 L 1087 315 L 1089 315 L 1093 313 L 1095 311 L 1098 310 L 1103 306 L 1106 305 L 1116 296 L 1117 296 L 1115 292 L 1113 290 L 1112 290 L 1111 288 L 1109 286 L 1108 286 L 1107 284 L 1100 278 L 1098 279 L 1090 286 L 1089 286 L 1086 289 L 1074 295 L 1072 295 L 1068 297 L 1065 297 L 1064 298 L 1061 298 L 1060 299 L 1041 299 L 1040 298 L 1037 298 L 1036 297 L 1031 296 L 1028 294 L 1026 294 L 1024 292 L 1020 290 L 1010 280 L 1008 275 L 1006 273 L 1005 271 L 1005 268 L 1004 267 L 1004 264 L 1003 263 L 1003 248 L 1004 247 L 1005 238 L 1008 233 L 1008 231 L 1010 227 L 1012 225 L 1013 222 L 1018 216 L 1018 215 L 1030 203 L 1031 203 L 1044 194 L 1046 194 L 1053 190 L 1056 190 L 1057 189 L 1060 189 L 1061 188 L 1064 188 L 1065 187 L 1071 187 L 1072 186 L 1076 186 L 1077 187 L 1083 187 L 1084 188 L 1087 188 L 1088 189 L 1090 189 L 1091 190 L 1096 191 L 1100 194 L 1103 195 L 1106 198 L 1107 198 L 1109 200 L 1109 201 L 1114 206 L 1114 207 L 1116 209 L 1118 213 L 1118 216 L 1120 220 L 1120 225 L 1116 227 L 1111 227 L 1110 228 L 1103 228 L 1102 229 L 1097 229 L 1096 230 L 1091 230 L 1090 231 L 1086 231 L 1085 232 L 1077 232 L 1076 233 L 1072 233 L 1071 234 L 1066 234 L 1065 235 L 1061 235 L 1060 236 L 1053 236 L 1052 237 L 1047 237 L 1047 240 L 1046 241 L 1046 243 L 1045 244 L 1045 247 L 1044 248 L 1044 250 L 1043 251 L 1043 254 L 1042 255 L 1042 260 L 1041 261 L 1041 263 L 1044 263 L 1045 262 L 1050 262 L 1051 261 L 1058 261 L 1059 260 L 1063 260 L 1064 259 L 1068 259 L 1069 258 L 1073 258 L 1074 257 L 1080 257 L 1081 256 L 1086 256 L 1087 255 L 1092 255 L 1093 254 L 1097 254 L 1098 253 L 1103 253 L 1104 252 L 1111 252 L 1112 251 L 1116 251 L 1117 250 L 1121 250 L 1122 249 L 1126 249 L 1127 248 L 1133 248 L 1134 247 L 1139 247 L 1140 246 L 1144 246 L 1146 243 L 1146 240 L 1147 239 L 1147 231 L 1148 230 L 1148 220 L 1147 219 L 1147 211 L 1146 210 L 1146 207 L 1144 204 L 1144 202 L 1143 201 L 1143 199 L 1141 195 L 1139 193 L 1138 190 L 1134 186 L 1133 183 L 1132 183 L 1129 180 Z
2780
- M 1779 171 L 1767 165 L 1765 165 L 1764 164 L 1762 164 L 1758 162 L 1755 162 L 1754 161 L 1747 161 L 1746 160 L 1729 160 L 1728 161 L 1722 161 L 1721 162 L 1718 162 L 1717 163 L 1715 163 L 1711 165 L 1707 165 L 1687 175 L 1685 177 L 1681 179 L 1672 187 L 1671 187 L 1661 197 L 1661 198 L 1657 202 L 1657 203 L 1652 209 L 1651 212 L 1649 214 L 1644 224 L 1643 229 L 1640 235 L 1640 238 L 1639 239 L 1639 244 L 1638 245 L 1638 250 L 1637 251 L 1637 267 L 1638 268 L 1638 273 L 1639 274 L 1639 278 L 1640 279 L 1640 282 L 1648 298 L 1652 302 L 1652 303 L 1655 306 L 1657 307 L 1657 308 L 1659 310 L 1660 310 L 1663 313 L 1669 316 L 1671 318 L 1673 319 L 1675 319 L 1676 320 L 1678 320 L 1684 323 L 1688 323 L 1689 324 L 1696 324 L 1697 325 L 1715 325 L 1716 324 L 1723 324 L 1724 323 L 1728 323 L 1729 322 L 1732 322 L 1738 319 L 1741 319 L 1748 315 L 1750 315 L 1754 313 L 1758 310 L 1759 311 L 1760 309 L 1761 309 L 1764 306 L 1765 306 L 1771 301 L 1772 301 L 1778 295 L 1761 278 L 1760 278 L 1756 282 L 1755 282 L 1751 286 L 1750 286 L 1745 290 L 1737 294 L 1732 295 L 1729 297 L 1726 297 L 1725 298 L 1721 298 L 1720 299 L 1703 299 L 1702 298 L 1698 298 L 1697 297 L 1692 296 L 1684 292 L 1682 290 L 1681 290 L 1673 282 L 1671 278 L 1668 275 L 1668 273 L 1667 272 L 1667 270 L 1666 269 L 1666 267 L 1664 263 L 1664 246 L 1665 245 L 1665 242 L 1666 241 L 1666 239 L 1668 235 L 1668 232 L 1670 228 L 1672 226 L 1673 224 L 1673 222 L 1680 214 L 1680 213 L 1690 203 L 1691 203 L 1694 200 L 1695 200 L 1700 196 L 1712 190 L 1715 190 L 1716 189 L 1718 189 L 1722 187 L 1725 187 L 1726 186 L 1744 186 L 1745 187 L 1747 187 L 1748 188 L 1750 188 L 1751 189 L 1756 190 L 1758 191 L 1761 194 L 1764 195 L 1773 204 L 1773 205 L 1777 210 L 1777 212 L 1778 213 L 1778 215 L 1780 219 L 1780 223 L 1781 225 L 1780 226 L 1775 226 L 1774 227 L 1768 227 L 1767 228 L 1759 228 L 1758 229 L 1753 229 L 1752 230 L 1747 230 L 1746 231 L 1742 231 L 1741 232 L 1733 232 L 1732 233 L 1727 233 L 1726 234 L 1722 234 L 1721 235 L 1717 235 L 1716 236 L 1709 236 L 1707 238 L 1707 241 L 1706 242 L 1706 246 L 1705 247 L 1705 250 L 1703 254 L 1703 258 L 1702 259 L 1702 262 L 1706 262 L 1707 261 L 1714 261 L 1715 260 L 1724 259 L 1725 258 L 1728 258 L 1729 257 L 1735 257 L 1736 256 L 1742 256 L 1743 255 L 1747 255 L 1748 254 L 1752 254 L 1753 253 L 1757 253 L 1758 252 L 1765 252 L 1766 251 L 1771 251 L 1772 250 L 1776 250 L 1777 249 L 1781 249 L 1782 248 L 1789 248 L 1790 247 L 1794 247 L 1795 246 L 1804 245 L 1805 243 L 1805 240 L 1806 239 L 1807 240 L 1807 243 L 1809 244 L 1809 241 L 1808 241 L 1806 238 L 1806 232 L 1807 231 L 1807 217 L 1806 216 L 1806 210 L 1805 209 L 1805 206 L 1802 200 L 1802 198 L 1800 194 L 1798 192 L 1797 189 L 1790 181 L 1790 180 L 1788 179 Z
2781
- M 714 187 L 712 189 L 712 190 L 708 193 L 708 194 L 704 198 L 704 199 L 700 203 L 700 204 L 695 210 L 695 212 L 693 214 L 690 220 L 690 222 L 686 229 L 686 233 L 684 237 L 684 240 L 683 241 L 683 245 L 682 246 L 682 268 L 683 269 L 683 273 L 684 274 L 684 276 L 686 280 L 686 283 L 692 295 L 699 303 L 699 304 L 701 306 L 702 306 L 704 308 L 704 309 L 707 310 L 711 314 L 716 316 L 718 318 L 720 319 L 722 319 L 725 321 L 730 322 L 731 323 L 734 323 L 735 324 L 740 324 L 741 325 L 749 325 L 750 326 L 759 326 L 760 325 L 767 325 L 768 324 L 775 324 L 776 323 L 780 323 L 788 319 L 791 319 L 792 318 L 794 318 L 798 315 L 800 315 L 810 309 L 812 310 L 812 313 L 811 314 L 811 319 L 810 320 L 809 325 L 836 325 L 839 319 L 839 316 L 840 315 L 840 310 L 841 309 L 841 307 L 842 306 L 842 303 L 844 299 L 844 295 L 845 294 L 846 287 L 847 286 L 847 284 L 849 280 L 849 275 L 850 274 L 850 271 L 851 270 L 851 268 L 853 264 L 854 255 L 855 254 L 855 252 L 856 251 L 856 248 L 857 247 L 857 244 L 858 243 L 858 217 L 857 216 L 857 212 L 854 206 L 853 201 L 851 197 L 849 195 L 849 193 L 846 190 L 844 186 L 835 177 L 834 177 L 831 174 L 830 174 L 825 170 L 823 170 L 814 165 L 811 165 L 808 163 L 805 163 L 804 162 L 800 162 L 799 161 L 793 161 L 792 160 L 773 160 L 772 161 L 765 161 L 764 162 L 757 163 L 753 165 L 750 165 L 743 169 L 741 169 L 735 172 L 733 174 L 730 175 L 728 177 L 724 179 L 715 187 Z
2782
- M 806 192 L 808 194 L 811 195 L 815 199 L 816 199 L 822 206 L 822 207 L 824 209 L 827 215 L 827 217 L 829 221 L 829 226 L 830 227 L 830 240 L 829 241 L 829 246 L 828 247 L 828 250 L 827 251 L 827 253 L 825 256 L 825 258 L 823 262 L 821 264 L 820 267 L 817 270 L 817 271 L 808 281 L 807 281 L 803 285 L 799 287 L 796 290 L 794 290 L 788 294 L 786 294 L 785 295 L 783 295 L 782 296 L 780 296 L 776 298 L 773 298 L 772 299 L 748 299 L 747 298 L 744 298 L 743 297 L 738 296 L 735 294 L 733 294 L 731 292 L 727 290 L 717 280 L 717 279 L 715 277 L 712 271 L 712 269 L 710 265 L 710 262 L 709 261 L 709 245 L 710 244 L 710 240 L 711 239 L 711 237 L 712 236 L 713 231 L 717 223 L 719 221 L 720 218 L 724 214 L 724 213 L 734 203 L 735 203 L 739 199 L 742 198 L 744 196 L 756 190 L 758 190 L 762 188 L 765 188 L 766 187 L 769 187 L 770 186 L 788 186 L 789 187 L 792 187 L 796 189 L 799 189 L 800 190 L 802 190 Z
2783
- M 1192 121 L 1190 122 L 1190 124 L 1189 125 L 1189 129 L 1188 130 L 1188 132 L 1186 136 L 1186 139 L 1185 140 L 1184 147 L 1183 148 L 1183 150 L 1181 154 L 1181 157 L 1180 158 L 1180 162 L 1179 163 L 1179 165 L 1178 166 L 1178 168 L 1176 172 L 1176 176 L 1175 177 L 1175 179 L 1173 183 L 1173 186 L 1172 187 L 1171 194 L 1170 195 L 1170 197 L 1168 201 L 1168 204 L 1167 205 L 1167 209 L 1166 210 L 1166 212 L 1164 216 L 1164 219 L 1163 220 L 1162 227 L 1160 231 L 1160 234 L 1159 235 L 1158 242 L 1157 243 L 1157 245 L 1155 249 L 1155 252 L 1154 253 L 1154 259 L 1153 260 L 1153 276 L 1154 277 L 1154 282 L 1155 283 L 1155 286 L 1158 292 L 1158 294 L 1161 298 L 1162 301 L 1173 313 L 1174 313 L 1182 319 L 1184 319 L 1189 322 L 1191 322 L 1195 324 L 1199 324 L 1200 325 L 1236 325 L 1236 323 L 1237 322 L 1237 319 L 1238 318 L 1238 315 L 1239 314 L 1239 311 L 1240 310 L 1240 307 L 1241 306 L 1241 303 L 1242 302 L 1242 300 L 1241 299 L 1209 299 L 1208 298 L 1205 298 L 1195 293 L 1187 285 L 1186 282 L 1183 278 L 1183 275 L 1182 274 L 1182 271 L 1181 270 L 1181 257 L 1182 256 L 1182 253 L 1183 252 L 1183 248 L 1184 247 L 1184 245 L 1186 241 L 1186 238 L 1187 237 L 1187 233 L 1188 232 L 1188 230 L 1189 229 L 1189 227 L 1191 223 L 1191 220 L 1192 219 L 1192 215 L 1193 214 L 1193 211 L 1195 207 L 1195 204 L 1196 203 L 1196 199 L 1197 198 L 1197 195 L 1198 194 L 1198 192 L 1200 190 L 1278 190 L 1279 189 L 1279 187 L 1281 183 L 1281 180 L 1282 179 L 1282 177 L 1283 176 L 1283 174 L 1285 170 L 1285 166 L 1286 165 L 1285 164 L 1269 164 L 1268 165 L 1239 165 L 1238 164 L 1221 164 L 1220 165 L 1210 165 L 1209 164 L 1207 164 L 1206 163 L 1207 162 L 1207 159 L 1209 155 L 1209 152 L 1210 151 L 1210 147 L 1211 146 L 1211 144 L 1213 140 L 1214 133 L 1216 129 L 1217 122 L 1216 121 Z
2784
- M 997 121 L 978 121 L 977 122 L 960 122 L 959 123 L 952 124 L 948 126 L 945 126 L 938 130 L 936 130 L 931 134 L 928 135 L 925 138 L 922 139 L 917 144 L 916 144 L 907 153 L 907 154 L 903 158 L 903 159 L 897 166 L 888 184 L 888 186 L 886 190 L 886 193 L 884 197 L 884 200 L 882 204 L 882 209 L 881 210 L 881 213 L 880 214 L 880 216 L 878 220 L 878 224 L 877 225 L 876 232 L 875 233 L 875 235 L 873 239 L 873 244 L 871 248 L 871 251 L 869 255 L 869 259 L 868 260 L 868 263 L 867 264 L 867 266 L 866 267 L 866 270 L 864 274 L 864 279 L 863 280 L 863 282 L 862 283 L 862 285 L 860 289 L 860 294 L 859 295 L 859 298 L 857 301 L 857 304 L 856 305 L 856 308 L 855 309 L 855 313 L 854 314 L 854 316 L 853 317 L 853 320 L 851 324 L 852 325 L 878 325 L 879 324 L 879 322 L 880 321 L 880 317 L 881 316 L 881 314 L 883 310 L 883 307 L 884 306 L 885 299 L 887 295 L 887 292 L 888 291 L 889 284 L 891 280 L 891 277 L 892 276 L 892 273 L 893 272 L 894 265 L 896 261 L 896 258 L 897 257 L 897 254 L 898 253 L 898 249 L 899 248 L 899 246 L 901 242 L 901 239 L 902 238 L 903 231 L 905 227 L 905 224 L 906 223 L 906 219 L 907 218 L 908 211 L 910 207 L 910 204 L 911 203 L 911 199 L 912 198 L 912 196 L 914 194 L 980 194 L 982 192 L 982 188 L 983 187 L 984 180 L 986 176 L 986 173 L 988 172 L 987 170 L 987 168 L 930 168 L 929 167 L 937 159 L 938 159 L 941 156 L 942 156 L 944 154 L 946 154 L 948 152 L 952 150 L 955 150 L 956 149 L 959 149 L 960 148 L 964 148 L 965 147 L 992 147 L 993 146 L 993 144 L 995 140 L 995 136 L 996 135 L 996 130 L 998 126 L 998 122 Z
2785
- M 1844 120 L 1842 124 L 1842 127 L 1841 128 L 1841 131 L 1840 132 L 1840 136 L 1839 137 L 1839 140 L 1838 141 L 1838 144 L 1837 145 L 1837 149 L 1835 153 L 1835 157 L 1834 158 L 1834 161 L 1832 165 L 1832 168 L 1831 169 L 1831 173 L 1830 174 L 1830 177 L 1828 181 L 1828 184 L 1827 185 L 1827 188 L 1826 189 L 1826 193 L 1824 197 L 1824 200 L 1823 201 L 1823 204 L 1822 205 L 1822 209 L 1821 210 L 1821 213 L 1820 214 L 1820 216 L 1819 217 L 1819 220 L 1818 221 L 1818 224 L 1817 225 L 1817 230 L 1815 234 L 1815 237 L 1813 241 L 1813 245 L 1812 246 L 1812 249 L 1811 250 L 1811 253 L 1810 254 L 1810 259 L 1809 260 L 1809 275 L 1810 276 L 1810 280 L 1811 281 L 1811 284 L 1812 285 L 1812 287 L 1813 288 L 1814 293 L 1817 297 L 1818 300 L 1821 303 L 1821 304 L 1831 314 L 1834 315 L 1839 319 L 1841 319 L 1849 323 L 1852 323 L 1853 324 L 1858 324 L 1859 325 L 1890 325 L 1891 324 L 1891 321 L 1892 320 L 1892 317 L 1893 316 L 1893 313 L 1894 312 L 1894 309 L 1895 308 L 1896 299 L 1865 299 L 1864 298 L 1861 298 L 1854 294 L 1852 294 L 1848 290 L 1847 290 L 1846 288 L 1842 284 L 1841 281 L 1839 279 L 1837 275 L 1837 270 L 1836 269 L 1836 258 L 1837 257 L 1837 250 L 1838 249 L 1838 246 L 1840 242 L 1840 239 L 1841 238 L 1841 235 L 1842 234 L 1842 230 L 1844 226 L 1844 223 L 1845 222 L 1845 219 L 1846 218 L 1846 214 L 1847 213 L 1847 210 L 1848 209 L 1848 207 L 1849 206 L 1849 203 L 1850 202 L 1850 199 L 1851 198 L 1851 193 L 1853 189 L 1924 189 L 1925 188 L 1925 185 L 1926 184 L 1926 180 L 1927 179 L 1927 176 L 1928 175 L 1928 172 L 1929 171 L 1930 164 L 1929 163 L 1860 163 L 1859 162 L 1860 161 L 1861 154 L 1862 153 L 1862 151 L 1863 150 L 1863 147 L 1864 146 L 1864 141 L 1865 140 L 1865 138 L 1866 137 L 1866 134 L 1868 130 L 1868 126 L 1869 125 L 1869 120 Z
2786
- M 675 120 L 575 120 L 574 121 L 567 121 L 566 122 L 563 122 L 562 123 L 559 123 L 558 124 L 556 124 L 555 125 L 550 126 L 538 132 L 536 134 L 532 136 L 528 140 L 527 140 L 526 142 L 522 145 L 522 146 L 518 150 L 516 154 L 513 157 L 513 159 L 508 168 L 508 173 L 507 174 L 507 177 L 506 178 L 506 194 L 507 195 L 508 202 L 510 205 L 510 207 L 512 209 L 514 214 L 517 217 L 517 218 L 520 221 L 521 221 L 522 223 L 523 223 L 529 228 L 533 230 L 535 230 L 538 232 L 543 233 L 544 234 L 551 234 L 552 235 L 615 235 L 616 234 L 618 234 L 619 235 L 624 235 L 625 236 L 627 236 L 635 240 L 641 247 L 643 251 L 643 253 L 644 254 L 644 267 L 643 268 L 643 271 L 642 272 L 642 274 L 641 276 L 639 278 L 637 282 L 630 289 L 629 289 L 627 291 L 626 291 L 622 294 L 620 294 L 616 296 L 613 296 L 612 297 L 487 297 L 485 299 L 485 302 L 483 306 L 483 310 L 482 311 L 482 314 L 481 315 L 481 319 L 480 320 L 480 325 L 607 325 L 608 324 L 614 324 L 615 323 L 619 323 L 627 319 L 630 319 L 634 317 L 636 315 L 638 315 L 640 313 L 641 313 L 649 306 L 650 306 L 653 303 L 654 301 L 655 301 L 655 300 L 662 292 L 662 290 L 664 288 L 667 282 L 667 280 L 668 279 L 668 277 L 670 273 L 670 270 L 671 269 L 671 248 L 670 247 L 670 244 L 669 243 L 668 238 L 665 232 L 662 229 L 661 226 L 655 220 L 654 220 L 648 215 L 640 211 L 638 211 L 637 210 L 633 210 L 632 209 L 627 209 L 626 208 L 553 208 L 552 207 L 550 207 L 544 204 L 537 197 L 535 193 L 534 188 L 533 187 L 533 180 L 534 179 L 534 176 L 537 170 L 537 168 L 539 166 L 539 165 L 549 155 L 554 153 L 558 150 L 561 150 L 562 149 L 565 149 L 566 148 L 570 148 L 571 147 L 670 147 L 671 146 L 671 141 L 672 140 L 672 137 L 674 133 L 674 129 L 675 128 L 675 124 L 676 123 L 676 121 Z
2787
- M 333 132 L 331 134 L 328 135 L 326 137 L 321 139 L 311 148 L 310 148 L 296 163 L 296 164 L 290 172 L 288 177 L 286 179 L 286 181 L 282 188 L 281 193 L 279 196 L 279 198 L 277 202 L 277 206 L 276 207 L 276 212 L 275 213 L 275 220 L 274 221 L 274 237 L 275 238 L 275 244 L 276 245 L 277 254 L 278 255 L 279 260 L 281 263 L 282 268 L 286 276 L 288 278 L 289 281 L 294 287 L 294 288 L 305 300 L 306 300 L 311 305 L 315 307 L 318 310 L 320 310 L 323 313 L 327 315 L 329 315 L 336 319 L 339 319 L 340 320 L 342 320 L 343 321 L 345 321 L 349 323 L 353 323 L 354 324 L 363 324 L 364 325 L 434 325 L 435 324 L 435 319 L 436 318 L 436 309 L 437 308 L 437 301 L 438 300 L 438 298 L 437 297 L 364 297 L 363 296 L 354 295 L 348 292 L 346 292 L 340 289 L 338 287 L 335 286 L 332 283 L 331 283 L 322 275 L 322 274 L 315 266 L 312 260 L 310 258 L 310 256 L 306 249 L 306 245 L 305 244 L 305 241 L 304 240 L 304 237 L 303 236 L 303 216 L 304 215 L 304 211 L 305 210 L 306 203 L 315 185 L 317 183 L 319 179 L 324 174 L 324 173 L 326 172 L 329 168 L 330 168 L 334 164 L 337 163 L 340 160 L 345 158 L 347 156 L 351 154 L 356 153 L 359 151 L 361 151 L 362 150 L 367 150 L 368 149 L 373 149 L 374 148 L 445 148 L 447 144 L 447 136 L 448 135 L 448 124 L 449 122 L 447 120 L 378 120 L 377 121 L 367 121 L 366 122 L 362 122 L 361 123 L 358 123 L 357 124 L 350 125 L 342 129 L 340 129 L 337 131 L 335 131 Z
2788
- M 181 132 L 179 134 L 174 136 L 172 138 L 168 140 L 165 143 L 164 143 L 159 148 L 158 148 L 156 150 L 156 151 L 154 152 L 152 154 L 152 155 L 147 160 L 147 161 L 143 165 L 143 166 L 139 171 L 138 174 L 136 176 L 130 188 L 130 190 L 129 191 L 129 193 L 128 194 L 128 196 L 126 200 L 126 203 L 125 204 L 125 208 L 124 209 L 124 213 L 123 214 L 123 222 L 122 223 L 122 232 L 123 233 L 123 241 L 124 242 L 124 246 L 125 247 L 125 252 L 126 253 L 126 256 L 129 262 L 130 267 L 135 277 L 137 279 L 138 282 L 144 289 L 144 290 L 156 302 L 157 302 L 160 305 L 164 307 L 167 310 L 167 311 L 169 310 L 174 314 L 176 315 L 178 315 L 185 319 L 188 319 L 189 320 L 191 320 L 195 322 L 198 322 L 199 323 L 204 323 L 205 324 L 214 324 L 215 325 L 286 325 L 287 324 L 287 319 L 288 318 L 288 302 L 289 301 L 289 298 L 288 297 L 214 297 L 213 296 L 208 296 L 207 295 L 200 294 L 195 291 L 193 291 L 189 289 L 187 287 L 184 286 L 178 281 L 177 281 L 168 272 L 168 271 L 164 267 L 163 264 L 159 259 L 159 257 L 155 250 L 155 248 L 154 247 L 154 243 L 152 239 L 152 233 L 151 232 L 151 221 L 152 220 L 152 214 L 153 213 L 153 210 L 154 209 L 154 205 L 157 199 L 157 197 L 159 194 L 159 192 L 163 187 L 163 185 L 167 181 L 168 178 L 170 177 L 171 175 L 184 163 L 185 163 L 190 159 L 200 154 L 202 154 L 205 152 L 207 152 L 210 150 L 215 150 L 216 149 L 222 149 L 223 148 L 295 148 L 296 147 L 296 140 L 297 139 L 297 128 L 298 127 L 298 121 L 297 120 L 227 120 L 226 121 L 215 121 L 214 122 L 209 122 L 208 123 L 205 123 L 201 125 L 198 125 L 197 126 L 192 127 L 185 131 L 183 131 Z
2789
- M 1506 121 L 1499 127 L 1497 131 L 1497 138 L 1496 139 L 1496 143 L 1495 144 L 1495 147 L 1494 148 L 1494 151 L 1493 152 L 1493 155 L 1492 156 L 1491 163 L 1489 167 L 1489 170 L 1488 171 L 1488 175 L 1487 176 L 1487 179 L 1485 183 L 1485 186 L 1484 187 L 1484 190 L 1483 191 L 1483 195 L 1482 196 L 1482 199 L 1481 200 L 1481 202 L 1480 203 L 1480 206 L 1479 207 L 1479 212 L 1478 213 L 1478 216 L 1476 220 L 1476 223 L 1475 224 L 1475 227 L 1474 228 L 1474 232 L 1473 233 L 1472 240 L 1470 244 L 1470 249 L 1469 250 L 1468 257 L 1466 261 L 1466 265 L 1465 266 L 1465 270 L 1464 271 L 1464 274 L 1463 275 L 1463 277 L 1462 278 L 1462 281 L 1461 282 L 1461 287 L 1460 288 L 1460 290 L 1459 291 L 1459 294 L 1457 298 L 1456 307 L 1455 308 L 1455 311 L 1454 312 L 1454 314 L 1453 315 L 1453 318 L 1452 319 L 1452 325 L 1478 325 L 1479 324 L 1479 321 L 1481 317 L 1481 312 L 1482 311 L 1482 308 L 1483 307 L 1483 304 L 1484 303 L 1484 300 L 1485 299 L 1485 296 L 1486 295 L 1486 290 L 1488 286 L 1488 283 L 1489 282 L 1489 279 L 1490 278 L 1490 274 L 1491 273 L 1491 270 L 1492 269 L 1492 267 L 1493 266 L 1493 263 L 1494 262 L 1495 253 L 1496 252 L 1496 249 L 1497 248 L 1497 245 L 1498 244 L 1498 241 L 1499 240 L 1499 235 L 1500 234 L 1500 232 L 1502 228 L 1502 225 L 1503 224 L 1503 220 L 1504 219 L 1504 216 L 1506 212 L 1506 209 L 1507 208 L 1507 205 L 1508 204 L 1508 199 L 1509 198 L 1509 195 L 1511 191 L 1511 188 L 1512 187 L 1512 183 L 1513 182 L 1513 179 L 1515 175 L 1516 168 L 1517 167 L 1519 169 L 1519 171 L 1520 172 L 1521 170 L 1521 167 L 1519 165 L 1518 167 L 1517 166 L 1518 159 L 1520 156 L 1522 159 L 1522 162 L 1523 163 L 1524 170 L 1525 171 L 1525 173 L 1527 177 L 1527 180 L 1528 181 L 1528 183 L 1530 187 L 1530 190 L 1532 194 L 1532 197 L 1533 198 L 1533 200 L 1534 201 L 1534 203 L 1536 207 L 1536 211 L 1537 212 L 1537 215 L 1538 216 L 1538 218 L 1539 219 L 1539 221 L 1541 225 L 1541 229 L 1542 230 L 1542 232 L 1543 233 L 1543 235 L 1545 239 L 1546 246 L 1547 247 L 1547 249 L 1548 250 L 1548 252 L 1550 256 L 1550 261 L 1551 262 L 1551 264 L 1552 265 L 1552 267 L 1554 271 L 1555 278 L 1556 279 L 1556 281 L 1558 285 L 1558 288 L 1559 289 L 1560 296 L 1561 297 L 1561 299 L 1563 303 L 1563 307 L 1564 308 L 1564 310 L 1566 314 L 1568 316 L 1568 317 L 1570 319 L 1571 319 L 1573 321 L 1577 323 L 1579 323 L 1580 324 L 1595 324 L 1596 323 L 1598 323 L 1606 318 L 1610 310 L 1610 306 L 1612 302 L 1612 299 L 1613 298 L 1613 296 L 1614 295 L 1614 292 L 1615 291 L 1615 287 L 1616 286 L 1616 284 L 1617 283 L 1617 280 L 1619 276 L 1619 272 L 1620 271 L 1620 269 L 1621 268 L 1621 265 L 1623 261 L 1623 258 L 1624 257 L 1624 253 L 1625 252 L 1625 250 L 1627 246 L 1627 243 L 1628 242 L 1628 238 L 1629 237 L 1629 235 L 1631 231 L 1631 228 L 1632 227 L 1632 223 L 1633 222 L 1633 220 L 1634 219 L 1634 216 L 1635 215 L 1635 213 L 1637 209 L 1637 205 L 1638 204 L 1638 202 L 1639 201 L 1639 198 L 1641 194 L 1641 190 L 1642 189 L 1642 186 L 1643 185 L 1643 183 L 1645 179 L 1646 172 L 1647 171 L 1647 169 L 1648 168 L 1648 165 L 1650 161 L 1650 157 L 1651 156 L 1651 154 L 1652 153 L 1652 151 L 1654 147 L 1654 144 L 1655 143 L 1655 139 L 1656 138 L 1656 136 L 1657 135 L 1657 133 L 1659 129 L 1659 125 L 1661 122 L 1661 120 L 1660 119 L 1635 119 L 1632 123 L 1632 125 L 1631 126 L 1631 129 L 1630 130 L 1630 134 L 1629 135 L 1629 137 L 1627 141 L 1627 144 L 1626 145 L 1626 149 L 1625 150 L 1625 152 L 1624 153 L 1624 155 L 1622 159 L 1622 162 L 1621 163 L 1621 167 L 1620 168 L 1620 170 L 1618 174 L 1618 177 L 1617 178 L 1617 182 L 1616 183 L 1616 185 L 1614 189 L 1614 192 L 1612 196 L 1612 200 L 1611 201 L 1611 203 L 1610 204 L 1610 207 L 1608 211 L 1608 215 L 1606 219 L 1606 222 L 1604 226 L 1604 229 L 1603 230 L 1602 237 L 1600 241 L 1600 244 L 1599 245 L 1599 249 L 1598 250 L 1598 253 L 1597 254 L 1597 256 L 1595 260 L 1595 264 L 1594 265 L 1594 268 L 1592 272 L 1592 275 L 1590 278 L 1588 274 L 1587 274 L 1587 277 L 1590 281 L 1590 284 L 1588 288 L 1586 287 L 1586 285 L 1585 284 L 1585 281 L 1583 277 L 1583 273 L 1582 272 L 1582 270 L 1581 269 L 1581 267 L 1579 263 L 1579 260 L 1578 259 L 1578 256 L 1577 255 L 1577 253 L 1575 249 L 1575 246 L 1574 245 L 1573 238 L 1572 237 L 1572 235 L 1570 231 L 1569 224 L 1568 223 L 1568 221 L 1566 217 L 1565 210 L 1564 209 L 1564 207 L 1562 203 L 1562 200 L 1561 199 L 1560 192 L 1559 191 L 1559 189 L 1557 185 L 1557 182 L 1556 181 L 1556 179 L 1555 178 L 1555 176 L 1553 172 L 1552 165 L 1550 161 L 1550 158 L 1548 154 L 1548 151 L 1547 150 L 1547 147 L 1545 143 L 1545 140 L 1544 139 L 1543 134 L 1541 130 L 1534 123 L 1530 121 L 1528 121 L 1524 119 L 1513 119 L 1512 120 L 1509 120 L 1508 121 Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"/>
2790
- </svg>
2778
+ <h1 class="brand-logo"><a class="brand-home" href="#overview" title="Overview"><svg xmlns="http://www.w3.org/2000/svg" viewBox="-4 -4 476.62 104" role="img" aria-label="CC Safety Net"><defs><style>@font-face{font-family:'Exo 2 Kit';font-style:italic;font-weight:700;src:url(data:font/woff2;base64,d09GMgABAAAAAAbUAA8AAAAADAQAAAZ7AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjYbgyQcVgZgP1NUQVRAAGwRCAqJMIdOCxgAATYCJAMsBCAFhDAHIBsHClEU84FMI2Xh/P0gqJpmz2glW7tm2AMGEwsNLDMfvC6JFAYQpPIEwhmU0xSaCF+QTsL/fr9W/1uXRBItlZA9tc/Z9Yv5Q0SSmDWGUAhNRJtlK9FLKKzDiVzMJj0vnDSdSSQEYLKYQBuCGLPALmhtxAISi2ZWHkV0ILcjDR6rs5GDaEcLyx1kdcyODZDVPebrJ2ugbWKILNkBQClYW9HvGxsiWjnNmOQ2JJovesQSRNmQRxoiskig7/FcAHZApkhZYgQ4vYi+qS95Gzs6m+iq/1ig/tdrUQqZrv4fjgwrgfpH/e7GW5n6Rzb9rL5X3/AAgsmcGyQaVq7JNiJbGiDQZxuRxpooiyzIdHCygPSC5IIkIFKwSFffp0/wUjYjKS5NoogLGOjtbnM8VaGhpYcTCWfSUjvZhhtRk4XySaxdpF961G+UqQ3YJJrZLFYS7HMtUh3GLHs+p7KqsoDrMJm1fKF2iC7aKbHDRFwSXCG+l/fnQdB25gYOKUdhafl0d8/Ev9X3TrQNCAYogYfEsePJ6XcDIkE+aQUGZDElS2BgChoenkQCb1eZHKGSOtroYoLZtB/wLvNdq75WT6sH1b3qBnWtukCdgz+U6igQShF/JUOyNCFZJfr1MiFZOyaLnIwFRmUW0AYPWrx061Lb+kxrvDXVyMy0tjTqLbHTwJjYnJjGp/YHQi8tc9z88su6/9Vng45g6C0jENnhfDGo+8Nhd0R+6HTjpbfquv/2rPrLr8/ST16b4dFbrrjDMAK3ZXovuy/TuPyG7Ib+QKjAcXM4rPsfvPHSjEsvu22Z87X3QmZQ3Fv3h13ul0IvGYFX7si+4vLbl7tefz+cf0NEFHQHQnb9D3+x/633mtcGb1txyzsfbFh3r8g+Gpy3czo9uns56BDzymeDRx1u9y2P/CLj4aXwT+UEQ48ZgUhkhfPGoK9H9QdeemmZQ/c/mtMY8MztbiPwRH5LJOJ0xLjd/Z4PFZ3Y2KYtKytYWYfM1o6jlwQ37O/v73Ps7++bmI0fbR0JDx8dmWNZVmJjm1AeGdoMne0IeN3GBh0HOR0H+47/9ql9Gn1m9n0WfSBpVlAV3nVM7PeauM3NbuRAaYXWwDZF2iOE1W3gy8gAWmccde8oddY6wmQ8F/50bf1ARjA/aBkrVUGtQ+mZVuBZ+mCJQ80mLVFUYBErNUGtRWlVmmNbxhaHh8ssJZYHzOfEQnHscF1eNIA2YKd06v4TI/YqqooRdgvH13JC60gb+dNZsyZgaeLjeTeYQgsIuaV6ZFg9EyySJdSi8LVsPNg1lNjs8IDyH5UCXAnVyeKiH6gIaBlPziUdcoFCeEFDY1VLvZSGhaPgkAJURRI/Etcax4TPRV3ADq+EqBCtdBkM8acG8n/WTmyMOum+94aU9/8kWIZ7JE1cEmziR2Lb9NVzFDEYBVzFT24KZagafAljfa6Nr4tkcvaRZg7DmKF1uBxVxJzJgMw2SeOKCqmtJbuMhakeWlnf0JhSETFCaifPzmNurIelamAwcovrEIBtbQEH3GHKZ1LEtMpIF1YNYgJVNa16jW9UBq5DCLa1PRzIPwZQuTI6s1ix6NIKmnp7RwtrwvDMtBSp1iS1Vk95QpnScY0vOaMZCCXYHVzJ/0V0Z4D0CrFjsjCpnT67jIWJMkZZz9CYUhExQmon72HF3qK6I/aC6qrHjZTrXjya2uRdsdfj2G8/WlVdm3VQeyi1af/KvcV1++0F1dUPfBzTGtEbvBoA6lkEIOU5eY+UL7TE7/0t2mL5EuCta2OSAD5Zdv4v/7v//0j7WSvBQguGTaGAOu3L1vj/3f/9qf1s+ZKzaorXNGQla2UJS+Vb5MgC4mUNGXIrGeJcdZG4FFMWsEz+oS7iw/pscwadRDFAVM3j1AUG/mu6Zh/brxcaWorkv2WoJI1PQy1s5V5RFi3mbBlqJYuJUBt5uArj2F4Xi9IvegbJKZJp8mhKaDVeephhBuikhAnaGKCXDtz46KWbHib2nScYYZzdbBj5hnWdjyG6RkVDTIDxdtE4PtYzzBjdFDCjVt/MOmzmahhjnF7zk0w2s56NbGKjCd5SzeVkczwA9lf2UEkVlRSwx9UIUAa4oSOESmYZI4wAOPjqFkwc9ODD9Cu/mrFxQx8+OoD8EJM8gfj645is5Ix30xt51CTtrKeDYQYD+g8zTDcD+NgsGmeDm+R1RP2rWpqtqT9BXclmNgA=) format('woff2')}</style></defs><svg x="0" y="0" width="96" height="96" viewBox="-172.38 -172.38 824.77 824.77"><g transform="rotate(45 240 240)"><rect x="-30" y="14" width="195" height="52" rx="9" fill="currentColor"/><rect x="315" y="14" width="195" height="52" rx="9" fill="currentColor"/><rect x="-30" y="94" width="115" height="52" rx="9" fill="currentColor"/><rect x="235" y="94" width="170" height="52" rx="9" fill="currentColor"/><rect x="155" y="174" width="170" height="52" rx="9" fill="currentColor"/><rect x="75" y="254" width="170" height="52" rx="9" fill="currentColor"/><rect x="395" y="254" width="115" height="52" rx="9" fill="currentColor"/><rect x="-30" y="334" width="195" height="52" rx="9" fill="currentColor"/><rect x="315" y="334" width="195" height="52" rx="9" fill="currentColor"/><rect x="-30" y="414" width="115" height="52" rx="9" fill="currentColor"/><rect x="235" y="414" width="170" height="52" rx="9" fill="currentColor"/><rect x="14" y="155" width="52" height="170" rx="9" fill="#e5602a"/><rect x="94" y="75" width="52" height="170" rx="9" fill="#e5602a"/><rect x="94" y="395" width="52" height="115" rx="9" fill="#e5602a"/><rect x="174" y="-30" width="52" height="195" rx="9" fill="#e5602a"/><rect x="174" y="315" width="52" height="195" rx="9" fill="#e5602a"/><rect x="254" y="-30" width="52" height="115" rx="9" fill="#e5602a"/><rect x="254" y="235" width="52" height="170" rx="9" fill="#e5602a"/><rect x="334" y="155" width="52" height="170" rx="9" fill="#e5602a"/><rect x="414" y="75" width="52" height="170" rx="9" fill="#e5602a"/><rect x="414" y="395" width="52" height="115" rx="9" fill="#e5602a"/></g></svg><text x="115.98" y="62.42" font-family="'Exo 2 Kit','Exo 2',sans-serif" font-style="italic" font-weight="700" font-size="56" letter-spacing="-0.56" fill="currentColor">CC Safety Net</text></svg>
2791
2779
  </a></h1>
2792
2780
  </div>
2793
2781
  <nav class="sidenav" aria-label="Sections">
@@ -3217,6 +3205,13 @@ var SAFETY_LEVEL_CAPABILITIES = {
3217
3205
  };
3218
3206
 
3219
3207
  // src/hosts/catalog.ts
3208
+ var DEEPSEEK_HARNESS_NPM_PROBE = [
3209
+ "npx",
3210
+ "--offline",
3211
+ "--no-install",
3212
+ "@deepseek-ai/dsh",
3213
+ "--version"
3214
+ ];
3220
3215
  var catalog = [
3221
3216
  {
3222
3217
  id: "antigravity-cli",
@@ -3274,7 +3269,7 @@ var catalog = [
3274
3269
  {
3275
3270
  id: "copilot-cli",
3276
3271
  displayName: "GitHub Copilot CLI",
3277
- doctorOrder: 7,
3272
+ doctorOrder: 8,
3278
3273
  runtime: {
3279
3274
  order: 6,
3280
3275
  flags: ["-cp", "--copilot-cli"],
@@ -3282,7 +3277,7 @@ var catalog = [
3282
3277
  legacyTopLevelFlags: ["-cp", "--copilot-cli"]
3283
3278
  },
3284
3279
  install: {
3285
- order: 7,
3280
+ order: 8,
3286
3281
  flag: "--copilot-cli",
3287
3282
  artifactKind: "plugin",
3288
3283
  probeCommand: ["copilot", "--binary-version"]
@@ -3291,7 +3286,7 @@ var catalog = [
3291
3286
  {
3292
3287
  id: "gemini-cli",
3293
3288
  displayName: "Gemini CLI",
3294
- doctorOrder: 6,
3289
+ doctorOrder: 7,
3295
3290
  runtime: {
3296
3291
  order: 5,
3297
3292
  flags: ["-gc", "--gemini-cli"],
@@ -3299,7 +3294,7 @@ var catalog = [
3299
3294
  legacyTopLevelFlags: ["-gc", "--gemini-cli"]
3300
3295
  },
3301
3296
  install: {
3302
- order: 6,
3297
+ order: 7,
3303
3298
  flag: "--gemini-cli",
3304
3299
  artifactKind: "extension",
3305
3300
  probeCommand: ["gemini", "--version"]
@@ -3308,7 +3303,7 @@ var catalog = [
3308
3303
  {
3309
3304
  id: "grok-build",
3310
3305
  displayName: "Grok Build",
3311
- doctorOrder: 8,
3306
+ doctorOrder: 9,
3312
3307
  runtime: {
3313
3308
  order: 7,
3314
3309
  flags: ["-gb", "--grok-build"],
@@ -3316,7 +3311,7 @@ var catalog = [
3316
3311
  legacyTopLevelFlags: []
3317
3312
  },
3318
3313
  install: {
3319
- order: 8,
3314
+ order: 9,
3320
3315
  flag: "--grok-build",
3321
3316
  artifactKind: "hook config",
3322
3317
  probeCommand: ["grok", "--version"]
@@ -3325,7 +3320,7 @@ var catalog = [
3325
3320
  {
3326
3321
  id: "hermes-agent",
3327
3322
  displayName: "Hermes Agent",
3328
- doctorOrder: 9,
3323
+ doctorOrder: 10,
3329
3324
  runtime: {
3330
3325
  order: 8,
3331
3326
  flags: ["-ha", "--hermes-agent"],
@@ -3333,7 +3328,7 @@ var catalog = [
3333
3328
  legacyTopLevelFlags: []
3334
3329
  },
3335
3330
  install: {
3336
- order: 9,
3331
+ order: 10,
3337
3332
  flag: "--hermes-agent",
3338
3333
  artifactKind: "plugin",
3339
3334
  probeCommand: ["hermes", "--version"]
@@ -3342,7 +3337,7 @@ var catalog = [
3342
3337
  {
3343
3338
  id: "kimi-code",
3344
3339
  displayName: "Kimi Code",
3345
- doctorOrder: 10,
3340
+ doctorOrder: 11,
3346
3341
  runtime: {
3347
3342
  order: 9,
3348
3343
  flags: ["-kc", "--kimi-code"],
@@ -3350,7 +3345,7 @@ var catalog = [
3350
3345
  legacyTopLevelFlags: []
3351
3346
  },
3352
3347
  install: {
3353
- order: 10,
3348
+ order: 11,
3354
3349
  flag: "--kimi-code",
3355
3350
  artifactKind: "hook config",
3356
3351
  probeCommand: ["kimi", "--version"]
@@ -3359,9 +3354,9 @@ var catalog = [
3359
3354
  {
3360
3355
  id: "openclaw",
3361
3356
  displayName: "OpenClaw",
3362
- doctorOrder: 11,
3357
+ doctorOrder: 12,
3363
3358
  install: {
3364
- order: 11,
3359
+ order: 12,
3365
3360
  flag: "--openclaw",
3366
3361
  artifactKind: "plugin",
3367
3362
  probeCommand: ["openclaw", "--version"]
@@ -3370,9 +3365,9 @@ var catalog = [
3370
3365
  {
3371
3366
  id: "opencode",
3372
3367
  displayName: "OpenCode",
3373
- doctorOrder: 12,
3368
+ doctorOrder: 13,
3374
3369
  install: {
3375
- order: 12,
3370
+ order: 13,
3376
3371
  flag: "--opencode",
3377
3372
  artifactKind: "plugin",
3378
3373
  probeCommand: ["opencode", "--version"]
@@ -3381,9 +3376,9 @@ var catalog = [
3381
3376
  {
3382
3377
  id: "pi",
3383
3378
  displayName: "Pi",
3384
- doctorOrder: 13,
3379
+ doctorOrder: 14,
3385
3380
  install: {
3386
- order: 13,
3381
+ order: 14,
3387
3382
  flag: "--pi",
3388
3383
  artifactKind: "package",
3389
3384
  probeCommand: ["pi", "--version"]
@@ -3406,6 +3401,17 @@ var catalog = [
3406
3401
  probeCommand: ["cursor", "--version"]
3407
3402
  }
3408
3403
  },
3404
+ {
3405
+ id: "deepseek-harness",
3406
+ displayName: "DeepSeek Harness",
3407
+ doctorOrder: 6,
3408
+ install: {
3409
+ order: 6,
3410
+ flag: "--deepseek-harness",
3411
+ artifactKind: "package",
3412
+ probeCommand: DEEPSEEK_HARNESS_NPM_PROBE
3413
+ }
3414
+ },
3409
3415
  {
3410
3416
  id: "amp",
3411
3417
  displayName: "Amp Code",
@@ -5925,6 +5931,6 @@ load().then((loaded) => {
5925
5931
  </script>
5926
5932
  </body>
5927
5933
  </html>
5928
- `;var Ud='<script id="ccsn-data" type="application/json">';function Gd(P){return Hd.replace(Ud,()=>Ud+JSON.stringify({token:P}).replaceAll("<","\\u003c"))}var oo="kenryu42/cc-safety-net",Ly=`https://github.com/${oo}`,Mi=1e4,wy=7,ky="The project draft directory changed; reload the draft before applying.",xy="audit settings are user scope only; remove the audit section from a project proposal";async function Jd(P,A={}){let q=xt({label:"gui",booleans:{noOpen:["--no-open"]}},P),V=A.log??console.log,ee=A.error??console.error;if(q.errors.length>0){for(let ce of q.errors)ee(ce);return ee("Usage: cc-safety-net gui [--no-open]"),1}let ne=await Cy(c,A);if(V(`CC Safety Net policy GUI: ${ne.url}`),!q.flags.noOpen)try{await(A.openBrowser??Oy)(ne.url)}catch(ce){ee(`Failed to open browser: ${ce instanceof Error?ce.message:String(ce)}`),ee(`Open this URL manually: ${ne.url}`)}if(A.keepAlive===!1)return await ne.close(),0;return await $y(ne),0}async function Cy(P,A={}){let q=hy(24).toString("base64url"),V={dir:null,revision:0},ee=vy((he,ye)=>{Sy(P,he,ye,q,A,V)});await new Promise((he,ye)=>{ee.once("error",ye),ee.listen(0,"127.0.0.1",()=>{ee.off("error",ye),he()})});let ce=`http://127.0.0.1:${ee.address().port}`;return{origin:ce,token:q,url:`${ce}/?token=${encodeURIComponent(q)}`,close:()=>Iy(ee)}}async function Sy(P,A,q,V,ee,ne){let ce=P(),he=new URL(A.url??"/","http://127.0.0.1");if(A.method==="GET"&&he.pathname==="/favicon.ico"){q.writeHead(204,{"cache-control":"no-store"}),q.end();return}if(!Ay(A,he,V)){ht(q,403,{error:"Forbidden"});return}if(A.method==="GET"&&he.pathname==="/"){Ty(q,Gd(V));return}if(A.method==="GET"&&he.pathname==="/api/policy"){let ye=Gc(ce,ee),be=E(ce,Ni(ee));ht(q,200,{...ye,configState:Ne(be),...be.policyScopes?{projectPolicy:{path:b(ee.cwd??process.cwd()),weakenings:be.policyScopes.weakenings}}:{},destructiveCommandRules:G,secretPatterns:Ke,version:wt(),preview:ye.errors.length>0?null:Ae(ye.policy,ce.env)});return}if(A.method==="POST"&&he.pathname==="/api/policy/preview"){let ye=await tr(A);if(!ye.ok){ht(q,ye.status,{errors:[ye.error]});return}let be=Bc(ce,ye.value);ht(q,be.errors.length>0?400:200,be);return}if(A.method==="POST"&&he.pathname==="/api/policy/explain"){let ye=await tr(A);if(!ye.ok){ht(q,ye.status,{errors:[ye.error]});return}let be=ye.value;if(be===null||typeof be.command!=="string"){ht(q,400,{errors:["command must be a string"]});return}let xe=Yn(be.policy,ce.home);if(xe.length>0){ht(q,400,{errors:xe});return}ht(q,200,Ey(ce,be.command,be.policy,ee));return}if(A.method==="POST"&&he.pathname==="/api/policy"){let ye=await tr(A);if(!ye.ok){ht(q,ye.status,{errors:[ye.error]});return}let be=Vt(ce,ye.value,ee);ht(q,be.errors.length>0?400:200,be);return}if(A.method==="POST"&&he.pathname==="/api/reset"){ht(q,200,Vt(ce,X,ee));return}if(A.method==="POST"&&he.pathname==="/api/repair"){ht(q,200,qc(ce,ee));return}if(A.method==="POST"&&he.pathname==="/api/policy/project/choose-directory"){let ye=await(ee.chooseDirectory??Fi)();if("path"in ye)ne.dir=ye.path,ne.revision+=1;ht(q,200,{cancelled:"cancelled"in ye,..."error"in ye?{error:ye.error}:{}});return}if(A.method==="GET"&&he.pathname==="/api/policy/project"){let ye=Wd(ne,ee),be=Bd(ye,ce.home),xe=Xn(ce,ee);ht(q,200,{path:b(ye),revision:ne.revision,baseline:xe.baseline,userPolicyDiagnostics:xe.diagnostics,projection:be.projection,projectionDiagnostics:be.diagnostics,canPickDirectory:Oi(process.platform,process.env)});return}if(A.method==="POST"&&he.pathname==="/api/policy/project/diff"){let ye=await qd(ce,A,q,ne,ee);if(!ye)return;let be=Bd(ye.dir,ce.home),xe=Xn(ce,ee).baseline,Ie=Z(xe,ae(ye.proposal,ce.home).policy);ht(q,200,{rows:qr(Z(xe,be.projection).policy,Ie.policy,!1),weakenings:Ie.weakenings,existingFileDiagnostics:be.diagnostics});return}if(A.method==="POST"&&he.pathname==="/api/policy/project/apply"){let ye=await qd(ce,A,q,ne,ee);if(!ye)return;let be=Py(ye.dir,ye.proposal,ce.home);ht(q,be.errors.length>0?500:200,be);return}if(A.method==="GET"&&he.pathname==="/api/activity"){let ye=te(ce,ee),be=Dy(he.searchParams.get("days"),ye);if(be===null){ht(q,400,{error:`days must be an integer between 1 and ${ye}`});return}ht(q,200,Fd(ce,be,ee.activityLogsDir));return}if(A.method==="POST"&&he.pathname==="/api/rules/choose-directory"){ht(q,200,await Fi());return}if(A.method==="GET"&&he.pathname==="/api/rules"){let ye=Y(ce,Ni(ee)),be=new Map(ye.rules.map((xe)=>[xe.name,xe]));ht(q,200,{projectPath:ee.cwd??process.cwd(),canPickDirectory:Oi(process.platform,process.env),rulebooks:ye.rulebooks.map((xe)=>({source:xe.source,spec:xe.spec,name:xe.name,version:xe.version,rules:xe.rules.flatMap((Ie)=>{let Xe=be.get(Ie);if(!Xe)return[];return[{name:Xe.name,command:Xe.command,subcommand:Xe.subcommand,block_args:Xe.block_args,reason:Xe.reason}]})})),errors:ye.errors,warnings:ye.warnings});return}if(A.method==="GET"&&he.pathname==="/api/star/context"){ht(q,200,await(ee.fetchStarContext??(()=>Uy(ce,{logsDir:ee.activityLogsDir})))());return}if(A.method==="POST"&&he.pathname==="/api/star"){let ye=await(ee.starRepo??Fy)();ht(q,200,ye.ok?{ok:!0}:{ok:!1,fallbackUrl:Ly});return}if(A.method==="GET"&&he.pathname==="/api/integrations"){ht(q,200,await(ee.fetchIntegrations??(()=>Ny(ce)))());return}if(A.method==="GET"&&he.pathname==="/api/health"){ht(q,200,await(ee.fetchHealth??My)());return}if(A.method==="POST"&&(he.pathname==="/api/install"||he.pathname==="/api/uninstall")){let ye=await tr(A);if(!ye.ok){ht(q,ye.status,{errors:[ye.error]});return}let be=ye.value?.target;if(typeof be!=="string"||!Ht.some((Ie)=>Ie.target===be)){ht(q,400,{error:"unknown target"});return}let xe=he.pathname==="/api/install"?"install":"uninstall";ht(q,200,await(ee.runIntegration??Hy)(xe,be));return}ht(q,404,{error:"Not found"})}function Ni(P){return{...P,cwd:P.cwd??process.cwd()}}function Wd(P,A){return P.dir??A.cwd??process.cwd()}function Bd(P,A){let q=b(P),V=yy(q)?pn(q):{value:void 0,errors:[]},ee=ae(V.value,A);return{projection:ee.policy,diagnostics:[...V.errors,...ee.diagnostics]}}async function qd(P,A,q,V,ee){let ne=Wd(V,ee),ce=V.revision,he=await tr(A);if(!he.ok)return ht(q,he.status,{errors:[he.error]}),null;let ye=he.value;if(typeof ye?.revision!=="number")return ht(q,400,{errors:["revision must be a number"]}),null;if(ye.revision!==ce)return ht(q,409,{errors:[ky]}),null;let be=Ry(ye.proposal,P.home);if(be.length>0)return ht(q,400,{errors:be}),null;return{dir:ne,proposal:ye.proposal}}function Ry(P,A){let q=Yn(P,A);if(q.length>0)return q;return P?.audit===void 0?[]:[xy]}function Py(P,A,q){let V=b(P),ee=Vr(A,C(A,q));try{return g(i(v(P,"project policy"),V),`${JSON.stringify(ee,null,2)}
5929
- `),{path:V,errors:[]}}catch(ne){return{path:V,errors:[ne instanceof Error?ne.message:String(ne)]}}}function Ey(P,A,q,V){let ee=C(q,P.home),ne=E(P,Ni(V)),ce=Ee({rules:ne.policy.rules,transparentWrappers:ne.policy.transparentWrappers,safety:De(ee.safety),worktreeMode:ee.workflow.worktree_mode,destructiveCommandProtectionEnabled:ee.destructive_command_protection.enabled,destructiveCommandRuleOverrides:ee.destructive_command_protection.overrides,destructiveCommandAllowPaths:ee.destructive_command_protection.allow_paths,secretProtection:{enabled:ee.secret_protection.enabled,disabledRules:Oe(ee.secret_protection.overrides),denyPaths:ee.secret_protection.deny_paths,allowPaths:ee.secret_protection.allow_paths}});return qn(A,{policySnapshot:ce,cwd:V.cwd,userConfigDir:V.userConfigDir},P)}function Dy(P,A){if(P===null)return Math.min(wy,A);let q=Number(P);if(!Number.isInteger(q)||q<1||q>A)return null;return q}function Ay(P,A,q){if(A.searchParams.get("token")!==q)return!1;if(P.method!=="POST")return!0;return P.headers["x-cc-safety-net-token"]===q}var _y=1048576;async function tr(P){let A=[],q=0;for await(let V of P){let ee=V;if(q+=ee.byteLength,q>_y)return{ok:!1,status:413,error:"Request body is too large"};A.push(ee)}try{return{ok:!0,value:JSON.parse(Buffer.concat(A).toString("utf-8")||"{}")}}catch(V){return{ok:!1,status:400,error:`Invalid JSON: ${V instanceof Error?V.message:String(V)}`}}}function Ty(P,A){P.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),P.end(A)}function ht(P,A,q){P.writeHead(A,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),P.end(JSON.stringify(q))}function Iy(P){return new Promise((A,q)=>{P.close((V)=>V?q(V):A())})}function $y(P){return new Promise((A)=>{let q=()=>{process.off("SIGINT",V),process.off("SIGTERM",V)},V=()=>{q(),P.close().then(A)};process.once("SIGINT",V),process.once("SIGTERM",V)})}function Oy(P){let A=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",q=process.platform==="win32"?["/c","start","",P]:[P];return new Promise((V,ee)=>{let ne=zd(A,q,{detached:!0,stdio:"ignore"}),ce=(ye)=>{ne.off("spawn",he),ee(ye)},he=()=>{ne.off("error",ce),ne.unref(),V()};ne.once("error",ce),ne.once("spawn",he)})}async function Fy(P="gh",A=Mi){return{ok:await ji(P,["api","-X","PUT",`/user/starred/${oo}`],A)===0}}async function Ny(P,A={}){let q=await pr((ee)=>kn({environment:P,cwd:process.cwd(),openCodeVersion:ee}).status!=="n/a",A.fetcher),V=jy(P,q);return{targets:$t.map((ee)=>{let ne=V.find((ce)=>ce.platform===ee.id);return{target:ee.id,label:bt(ee.id),version:q.versions[ee.id]??null,status:ne?.configured?"active":ne?.detected?"disabled":ne?.inspectionStatus==="not-inspected"?"not-inspected":"not-installed"}}),system:{version:q.version,nodeVersion:q.nodeVersion,platform:q.platform}}}function jy(P,A){return xn(P,process.cwd(),{ampPluginListOutput:A.ampPluginListOutput,codexPluginListOutput:A.codexPluginListOutput,copilotCliVersion:A.versions["copilot-cli"],openCodeVersion:A.versions.opencode,openCodePluginListOutput:A.openCodePluginListOutput})}async function My(P={}){let A=await(P.checkUpdates??Wt)();return{update:{latestVersion:A.latestVersion??null,updateAvailable:A.updateAvailable}}}var Vd=Promise.resolve();function Hy(P,A,q={}){let V=async()=>{let ne=[],{log:ce,error:he}=console;console.log=(...ye)=>ne.push(ye.map(String).join(" ")),console.error=console.log;try{return{ok:await Kn(P,[],{selectTargets:async()=>[A],output:new by({write(be,xe,Ie){ne.push(String(be).replace(/\n$/,"")),Ie()}}),...q})===0,output:ne.join(`
5930
- `)}}finally{console.log=ce,console.error=he}},ee=Vd.then(V);return Vd=ee.then(()=>{return},()=>{return}),ee}async function Uy(P,A={}){let[q,V,ee]=await Promise.all([Gy(A.command),By(A.fetchRepo),Promise.resolve(ar(P,te(P),A.logsDir).totalBlocked)]);return{starred:q,starCount:V,blockedTotal:ee}}async function Gy(P="gh",A=Mi){if(await ji(P,["auth","status"],A)!==0)return null;let q=await ji(P,["api",`/user/starred/${oo}`],A);if(q===0)return!0;if(q===null)return null;return!1}function ji(P,A,q){return new Promise((V)=>{let ee=zd(P,A,{stdio:"ignore",windowsHide:!0}),ne=!1,ce=setTimeout(()=>{ee.kill(),he(null)},q),he=(ye)=>{if(ne)return;ne=!0,clearTimeout(ce),V(ye)};ee.once("error",()=>he(null)),ee.once("close",he)})}async function By(P=fetch){try{let A=await P(`https://api.github.com/repos/${oo}`,{headers:{accept:"application/vnd.github+json"},signal:AbortSignal.timeout(Mi)});if(!A.ok)return null;let q=await A.json();return typeof q.stargazers_count==="number"?q.stargazers_count:null}catch{return null}}function qy(P){if(P[0]!=="help")return!1;let A=P[1];if(!A)di(),process.exit(0);if(Vn(A))process.exit(0);console.error(`Unknown command: ${A}`),console.error("Run 'cc-safety-net --help' for available commands."),process.exit(1)}var Vy={hook:async()=>{console.error("hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code"),Vn("hook",console.error),process.exit(1)},install:async(P)=>{process.exit(await Kn("install",P))},update:async(P)=>{process.exit(await xi(P))},uninstall:async(P)=>{process.exit(await Kn("uninstall",P))},rule:async(P)=>{process.exit(await Id(c(),P))},policy:async(P)=>{process.exit(await Wc(c(),P))},status:async(P)=>{if(Ut(xt({label:"status"},P).errors))process.exit(1);Od(c())},statusline:async(P)=>{let A=xt({label:"statusline",booleans:{claudeCode:["-cc","--claude-code"]}},P);if(A.errors.length===0&&A.flags.claudeCode){await $i(c());return}if(Ut(A.errors),!A.flags.claudeCode)console.error("statusline requires --claude-code (-cc)");Vn("statusline",console.error),process.exit(1)},doctor:async(P)=>{let A=ni(P);if(!A)process.exit(1);let q=await Ll(c(),{json:A.json,skipUpdateCheck:A.skipUpdateCheck});process.exit(q)},logs:async(P)=>{process.exit(await Ji(c(),P))},gui:async(P)=>{process.exit(await Jd(P))},explain:async(P)=>{process.exit(await _l(c(),P))}};async function zy(P){let A=xt({label:"cc-safety-net",booleans:{version:["-V","--version"]},positionals:"list"},P);if(qy(P))return;let q=P[0],V=q?sr(q):void 0;if(A.help&&V&&V.name!=="rule")Vn(V.name),process.exit(0);if(!q||A.help&&!V)di(),process.exit(0);if(A.flags.version)$l(),process.exit(0);if(V){await Vy[V.name](P.slice(1));return}if(q==="--statusline"){await $i(c());return}console.error(q.startsWith("-")?`Unknown option: ${q}`:`Unknown command: ${q}`),console.error("Run 'cc-safety-net --help' for usage."),process.exit(1)}export{zy as runCli};
5934
+ `;var cu='<script id="ccsn-data" type="application/json">';function du(_){return lu.replace(cu,()=>cu+JSON.stringify({token:_}).replaceAll("<","\\u003c"))}var ao="kenryu42/cc-safety-net",Jv=`https://github.com/${ao}`,Ki=1e4,Wv=7,Kv="The project draft directory changed; reload the draft before applying.",Yv="audit settings are user scope only; remove the audit section from a project proposal";async function gu(_,I={}){let O=gn({label:"gui",booleans:{noOpen:["--no-open"]}},_),L=I.log??console.log,J=I.error??console.error;if(O.errors.length>0){for(let ne of O.errors)J(ne);return J("Usage: cc-safety-net gui [--no-open]"),1}let K=await Zv(c,I);if(L(`CC Safety Net policy GUI: ${K.url}`),!O.flags.noOpen)try{await(I.openBrowser??lb)(K.url)}catch(ne){J(`Failed to open browser: ${ne instanceof Error?ne.message:String(ne)}`),J(`Open this URL manually: ${K.url}`)}if(I.keepAlive===!1)return await K.close(),0;return await ab(K),0}async function Zv(_,I={}){let O=Bv(24).toString("base64url"),L={dir:null,revision:0},J=Vv((oe,de)=>{Xv(_,oe,de,O,I,L)});await new Promise((oe,de)=>{J.once("error",de),J.listen(0,"127.0.0.1",()=>{J.off("error",de),oe()})});let ne=`http://127.0.0.1:${J.address().port}`;return{origin:ne,token:O,url:`${ne}/?token=${encodeURIComponent(O)}`,close:()=>sb(J)}}async function Xv(_,I,O,L,J,K){let ne=_(),oe=new URL(I.url??"/","http://127.0.0.1");if(I.method==="GET"&&oe.pathname==="/favicon.ico"){O.writeHead(204,{"cache-control":"no-store"}),O.end();return}if(!rb(I,oe,L)){ln(O,403,{error:"Forbidden"});return}if(I.method==="GET"&&oe.pathname==="/"){ib(O,du(L));return}if(I.method==="GET"&&oe.pathname==="/api/policy"){let de=dd(ne,J),ue=E(ne,Ji(J));ln(O,200,{...de,configState:$e(ue),...ue.policyScopes?{projectPolicy:{path:b(J.cwd??process.cwd()),weakenings:ue.policyScopes.weakenings}}:{},destructiveCommandRules:W,secretPatterns:Xe,version:fn(),preview:de.errors.length>0?null:Ne(de.policy,ne.env)});return}if(I.method==="POST"&&oe.pathname==="/api/policy/preview"){let de=await or(I);if(!de.ok){ln(O,de.status,{errors:[de.error]});return}let ue=ud(ne,de.value);ln(O,ue.errors.length>0?400:200,ue);return}if(I.method==="POST"&&oe.pathname==="/api/policy/explain"){let de=await or(I);if(!de.ok){ln(O,de.status,{errors:[de.error]});return}let ue=de.value;if(ue===null||typeof ue.command!=="string"){ln(O,400,{errors:["command must be a string"]});return}let ve=Qt(ue.policy,ne.home);if(ve.length>0){ln(O,400,{errors:ve});return}ln(O,200,nb(ne,ue.command,ue.policy,J));return}if(I.method==="POST"&&oe.pathname==="/api/policy"){let de=await or(I);if(!de.ok){ln(O,de.status,{errors:[de.error]});return}let ue=Hn(ne,de.value,J);ln(O,ue.errors.length>0?400:200,ue);return}if(I.method==="POST"&&oe.pathname==="/api/reset"){ln(O,200,Hn(ne,ee,J));return}if(I.method==="POST"&&oe.pathname==="/api/repair"){ln(O,200,pd(ne,J));return}if(I.method==="POST"&&oe.pathname==="/api/policy/project/choose-directory"){let de=await(J.chooseDirectory??zi)();if("path"in de)K.dir=de.path,K.revision+=1;ln(O,200,{cancelled:"cancelled"in de,..."error"in de?{error:de.error}:{}});return}if(I.method==="GET"&&oe.pathname==="/api/policy/project"){let de=hu(K,J),ue=uu(de,ne.home),ve=er(ne,J);ln(O,200,{path:b(de),revision:K.revision,baseline:ve.baseline,userPolicyDiagnostics:ve.diagnostics,projection:ue.projection,projectionDiagnostics:ue.diagnostics,canPickDirectory:Vi(process.platform,process.env)});return}if(I.method==="POST"&&oe.pathname==="/api/policy/project/diff"){let de=await pu(ne,I,O,K,J);if(!de)return;let ue=uu(de.dir,ne.home),ve=er(ne,J).baseline,xe=Q(ve,le(de.proposal,ne.home).policy);ln(O,200,{rows:Jr(Q(ve,ue.projection).policy,xe.policy,!1),weakenings:xe.weakenings,existingFileDiagnostics:ue.diagnostics});return}if(I.method==="POST"&&oe.pathname==="/api/policy/project/apply"){let de=await pu(ne,I,O,K,J);if(!de)return;let ue=eb(de.dir,de.proposal,ne.home);ln(O,ue.errors.length>0?500:200,ue);return}if(I.method==="GET"&&oe.pathname==="/api/activity"){let de=re(ne,J),ue=tb(oe.searchParams.get("days"),de);if(ue===null){ln(O,400,{error:`days must be an integer between 1 and ${de}`});return}ln(O,200,ou(ne,ue,J.activityLogsDir));return}if(I.method==="POST"&&oe.pathname==="/api/rules/choose-directory"){ln(O,200,await zi());return}if(I.method==="GET"&&oe.pathname==="/api/rules"){let de=X(ne,Ji(J)),ue=new Map(de.rules.map((ve)=>[ve.name,ve]));ln(O,200,{projectPath:J.cwd??process.cwd(),canPickDirectory:Vi(process.platform,process.env),rulebooks:de.rulebooks.map((ve)=>({source:ve.source,spec:ve.spec,name:ve.name,version:ve.version,rules:ve.rules.flatMap((xe)=>{let Se=ue.get(xe);if(!Se)return[];return[{name:Se.name,command:Se.command,subcommand:Se.subcommand,block_args:Se.block_args,reason:Se.reason}]})})),errors:de.errors,warnings:de.warnings});return}if(I.method==="GET"&&oe.pathname==="/api/star/context"){ln(O,200,await(J.fetchStarContext??(()=>mb(ne,{logsDir:J.activityLogsDir})))());return}if(I.method==="POST"&&oe.pathname==="/api/star"){let de=await(J.starRepo??cb)();ln(O,200,de.ok?{ok:!0}:{ok:!1,fallbackUrl:Jv});return}if(I.method==="GET"&&oe.pathname==="/api/integrations"){ln(O,200,await(J.fetchIntegrations??(()=>db(ne)))());return}if(I.method==="GET"&&oe.pathname==="/api/health"){ln(O,200,await(J.fetchHealth??pb)());return}if(I.method==="POST"&&(oe.pathname==="/api/install"||oe.pathname==="/api/uninstall")){let de=await or(I);if(!de.ok){ln(O,de.status,{errors:[de.error]});return}let ue=de.value?.target;if(typeof ue!=="string"||!$n.some((xe)=>xe.target===ue)){ln(O,400,{error:"unknown target"});return}let ve=oe.pathname==="/api/install"?"install":"uninstall";ln(O,200,await(J.runIntegration??fb)(ve,ue));return}ln(O,404,{error:"Not found"})}function Ji(_){return{..._,cwd:_.cwd??process.cwd()}}function hu(_,I){return _.dir??I.cwd??process.cwd()}function uu(_,I){let O=b(_),L=qv(O)?mt(O):{value:void 0,errors:[]},J=le(L.value,I);return{projection:J.policy,diagnostics:[...L.errors,...J.diagnostics]}}async function pu(_,I,O,L,J){let K=hu(L,J),ne=L.revision,oe=await or(I);if(!oe.ok)return ln(O,oe.status,{errors:[oe.error]}),null;let de=oe.value;if(typeof de?.revision!=="number")return ln(O,400,{errors:["revision must be a number"]}),null;if(de.revision!==ne)return ln(O,409,{errors:[Kv]}),null;let ue=Qv(de.proposal,_.home);if(ue.length>0)return ln(O,400,{errors:ue}),null;return{dir:K,proposal:de.proposal}}function Qv(_,I){let O=Qt(_,I);if(O.length>0)return O;return _?.audit===void 0?[]:[Yv]}function eb(_,I,O){let L=b(_),J=Wr(I,C(I,O));try{return g(i(v(_,"project policy"),L),`${JSON.stringify(J,null,2)}
5935
+ `),{path:L,errors:[]}}catch(K){return{path:L,errors:[K instanceof Error?K.message:String(K)]}}}function nb(_,I,O,L){let J=C(O,_.home),K=E(_,Ji(L)),ne=Te({rules:K.policy.rules,transparentWrappers:K.policy.transparentWrappers,safety:Me(J.safety),worktreeMode:J.workflow.worktree_mode,destructiveCommandProtectionEnabled:J.destructive_command_protection.enabled,destructiveCommandRuleOverrides:J.destructive_command_protection.overrides,destructiveCommandAllowPaths:J.destructive_command_protection.allow_paths,secretProtection:{enabled:J.secret_protection.enabled,disabledRules:Fe(J.secret_protection.overrides),denyPaths:J.secret_protection.deny_paths,allowPaths:J.secret_protection.allow_paths}});return zt(I,{policySnapshot:ne,cwd:L.cwd,userConfigDir:L.userConfigDir},_)}function tb(_,I){if(_===null)return Math.min(Wv,I);let O=Number(_);if(!Number.isInteger(O)||O<1||O>I)return null;return O}function rb(_,I,O){if(I.searchParams.get("token")!==O)return!1;if(_.method!=="POST")return!0;return _.headers["x-cc-safety-net-token"]===O}var ob=1048576;async function or(_){let I=[],O=0;for await(let L of _){let J=L;if(O+=J.byteLength,O>ob)return{ok:!1,status:413,error:"Request body is too large"};I.push(J)}try{return{ok:!0,value:JSON.parse(Buffer.concat(I).toString("utf-8")||"{}")}}catch(L){return{ok:!1,status:400,error:`Invalid JSON: ${L instanceof Error?L.message:String(L)}`}}}function ib(_,I){_.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),_.end(I)}function ln(_,I,O){_.writeHead(I,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),_.end(JSON.stringify(O))}function sb(_){return new Promise((I,O)=>{_.close((L)=>L?O(L):I())})}function ab(_){return new Promise((I)=>{let O=()=>{process.off("SIGINT",L),process.off("SIGTERM",L)},L=()=>{O(),_.close().then(I)};process.once("SIGINT",L),process.once("SIGTERM",L)})}function lb(_){let I=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",O=process.platform==="win32"?["/c","start","",_]:[_];return new Promise((L,J)=>{let K=mu(I,O,{detached:!0,stdio:"ignore"}),ne=(de)=>{K.off("spawn",oe),J(de)},oe=()=>{K.off("error",ne),K.unref(),L()};K.once("error",ne),K.once("spawn",oe)})}async function cb(_="gh",I=Ki){return{ok:await Wi(_,["api","-X","PUT",`/user/starred/${ao}`],I)===0}}async function db(_,I={}){let O=await gr((J)=>Ct({environment:_,cwd:process.cwd(),openCodeVersion:J}).status!=="n/a",I.fetcher),L=ub(_,O);return{targets:En.map((J)=>{let K=L.find((ne)=>ne.platform===J.id);return{target:J.id,label:pn(J.id),version:O.versions[J.id]??null,status:K?.configured?"active":K?.detected?"disabled":K?.inspectionStatus==="not-inspected"?"not-inspected":"not-installed"}}),system:{version:O.version,nodeVersion:O.nodeVersion,platform:O.platform}}}function ub(_,I){return Rt(_,process.cwd(),{ampPluginListOutput:I.ampPluginListOutput,codexPluginListOutput:I.codexPluginListOutput,copilotCliVersion:I.versions["copilot-cli"],openCodeVersion:I.versions.opencode,openCodePluginListOutput:I.openCodePluginListOutput})}async function pb(_={}){let I=await(_.checkUpdates??Gn)();return{update:{latestVersion:I.latestVersion??null,updateAvailable:I.updateAvailable}}}var fu=Promise.resolve();function fb(_,I,O={}){let L=async()=>{let K=[],{log:ne,error:oe}=console;console.log=(...de)=>K.push(de.map(String).join(" ")),console.error=console.log;try{return{ok:await Xt(_,[],{selectTargets:async()=>[I],output:new zv({write(ue,ve,xe){K.push(String(ue).replace(/\n$/,"")),xe()}}),...O})===0,output:K.join(`
5936
+ `)}}finally{console.log=ne,console.error=oe}},J=fu.then(L);return fu=J.then(()=>{return},()=>{return}),J}async function mb(_,I={}){let[O,L,J]=await Promise.all([gb(I.command),hb(I.fetchRepo),Promise.resolve(dr(_,re(_),I.logsDir).totalBlocked)]);return{starred:O,starCount:L,blockedTotal:J}}async function gb(_="gh",I=Ki){if(await Wi(_,["auth","status"],I)!==0)return null;let O=await Wi(_,["api",`/user/starred/${ao}`],I);if(O===0)return!0;if(O===null)return null;return!1}function Wi(_,I,O){return new Promise((L)=>{let J=mu(_,I,{stdio:"ignore",windowsHide:!0}),K=!1,ne=setTimeout(()=>{J.kill(),oe(null)},O),oe=(de)=>{if(K)return;K=!0,clearTimeout(ne),L(de)};J.once("error",()=>oe(null)),J.once("close",oe)})}async function hb(_=fetch){try{let I=await _(`https://api.github.com/repos/${ao}`,{headers:{accept:"application/vnd.github+json"},signal:AbortSignal.timeout(Ki)});if(!I.ok)return null;let O=await I.json();return typeof O.stargazers_count==="number"?O.stargazers_count:null}catch{return null}}function yb(_){if(_[0]!=="help")return!1;let I=_[1];if(!I)vi(),process.exit(0);if(Jt(I))process.exit(0);console.error(`Unknown command: ${I}`),console.error("Run 'cc-safety-net --help' for available commands."),process.exit(1)}var vb={hook:async()=>{console.error("hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code"),Jt("hook",console.error),process.exit(1)},install:async(_)=>{process.exit(await Xt("install",_))},update:async(_)=>{process.exit(await Oi(_))},uninstall:async(_)=>{process.exit(await Xt("uninstall",_))},rule:async(_)=>{process.exit(await nu(c(),_))},policy:async(_)=>{process.exit(await hd(c(),_))},status:async(_)=>{if(On(gn({label:"status"},_).errors))process.exit(1);ru(c())},statusline:async(_)=>{let I=gn({label:"statusline",booleans:{claudeCode:["-cc","--claude-code"]}},_);if(I.errors.length===0&&I.flags.claudeCode){await qi(c());return}if(On(I.errors),!I.flags.claudeCode)console.error("statusline requires --claude-code (-cc)");Jt("statusline",console.error),process.exit(1)},doctor:async(_)=>{let I=di(_);if(!I)process.exit(1);let O=await $l(c(),{json:I.json,skipUpdateCheck:I.skipUpdateCheck});process.exit(O)},logs:async(_)=>{process.exit(await rs(c(),_))},gui:async(_)=>{process.exit(await gu(_))},explain:async(_)=>{process.exit(await Bl(c(),_))}};async function bb(_){let I=gn({label:"cc-safety-net",booleans:{version:["-V","--version"]},positionals:"list"},_);if(yb(_))return;let O=_[0],L=O?cr(O):void 0;if(I.help&&L&&L.name!=="rule")Jt(L.name),process.exit(0);if(!O||I.help&&!L)vi(),process.exit(0);if(I.flags.version)zl(),process.exit(0);if(L){await vb[L.name](_.slice(1));return}if(O==="--statusline"){await qi(c());return}console.error(O.startsWith("-")?`Unknown option: ${O}`:`Unknown command: ${O}`),console.error("Run 'cc-safety-net --help' for usage."),process.exit(1)}export{bb as runCli};