cc-safety-net 2.1.1 → 2.2.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.
@@ -1,42 +1,43 @@
1
1
  #!/usr/bin/env node
2
- import{b as Oo,c as $o,d as G,e as No,f as Vn,g as Qe,h as De,i as lr,j as ue,k as Pi,l as hr,m as zt,n as Ti,o as Ii,p as Kt}from"../chunks/index-gdm1kya3.js";import{$a as Bc,A as Cc,Aa as fr,B as Xo,Ba as mr,C as Qo,Ca as gi,D as ei,Da as hi,E as ht,Ea as Go,F as Wn,Fa as Ze,G as or,Ga as Zn,H as ti,Ha as Xn,Ia as ri,J as ni,Ja as Ve,K as X,Ka as Hc,La as qo,M as Q,Ma as Vo,N as Je,Na as gr,O as Ye,Oa as zo,P as yt,Pa as Ko,Q as gc,Qa as Y,R as ee,Ra as Qn,S as J,Sa as sr,T as ir,Ta as ar,U as Jn,Ua as Z,V as Vt,Va as Mc,W as Yn,Wa as wt,Xa as jc,Y as Pe,Ya as Eo,Z as fe,Za as Uc,_ as qi,_a as Gc,aa as Re,ab as Cn,ba as Wt,bb as qc,ca as kt,cb as Vc,da as Ct,db as yi,ea as di,eb as Li,fa as Lt,fb as vi,ga as Ae,gb as bi,ha as cr,hb as vc,ia as pe,ib as oi,ja as _i,jb as ii,ka as yr,kb as er,la as Ni,lb as si,ma as Fi,mb as ai,na as dr,nb as Le,oa as ui,ob as Se,pa as jo,pb as ce,qa as pi,qb as li,ra as fi,rb as B,s as N,sa as mi,sb as xt,t as x,ta as ur,tb as vt,u as mt,ua as Uo,ub as $i,v as w,va as S,w as ke,wa as pr,x as Zo,xa as Oi,y as Ce,ya as de,z as Ke,za as bt}from"../chunks/index-4g6x1r63.js";var Zc=["-h","--help"];function T(e,t){let n=Object.entries(e.booleans??{}),r=Object.entries(e.values??{}),o=Object.fromEntries(n.map(([d])=>[d,!1])),i={},s=[],a=[],l=!1,c=-1;for(let[d,p]of t.entries()){if(d<=c)continue;if(p==="--"){s.push(...t.slice(d+1));break}if(Zc.includes(p)){l=!0;continue}let g=n.find(([,m])=>m.includes(p));if(g){o[g[0]]=!0;continue}let u=r.find(([,m])=>m.includes(p));if(u){let m=t[d+1];if(m===void 0||m.startsWith("-")){a.push(`${p} requires a value`);continue}i[u[0]]=m,c=d+1;continue}if(p.startsWith("-")){a.push(`Unknown option for ${e.label}: ${p}`);continue}if(e.positionals==="tail"){s.push(...t.slice(d));break}s.push(p)}if(e.positionals!=="list"&&e.positionals!=="tail")a.push(...s.map((d)=>`Unexpected argument for ${e.label}: ${d}`));return{flags:o,values:i,positionals:s,help:l,errors:a}}function ae(e){for(let t of e)console.error(t);return e.length>0}import{readdirSync as Fd,statSync as xi,unlinkSync as Hd}from"node:fs";import{basename as ki,dirname as Md,join as jd,resolve as Ud}from"node:path";function I(e){return Array.from(e,(t)=>{let n=t.charCodeAt(0);if(n<=31||n>=127&&n<=159)return`\\x${n.toString(16).padStart(2,"0")}`;return t}).join("")}var Un=(e)=>{let t=Date.now()-new Date(e).getTime();if(!Number.isFinite(t))return"";let n=Math.floor(t/60000),r=Math.floor(n/60),o=Math.floor(r/24);if(o>0)return`${o}d ago`;if(r>0)return`${r}h ago`;if(n>0)return`${n}m ago`;return"just now"},Ge=(e)=>{let t=(e??"").trim().split(/\s+/).filter((o)=>o&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(o)),n=t[0]?.split("/").pop();if(!n)return null;let r=t[1];return r&&/^[a-z][a-z0-9-]*$/.test(r)?`${n} ${r}`:n};import{existsSync as Xc,readdirSync as Qc,readFileSync as ed}from"node:fs";import{join as td}from"node:path";function ye(e,t){try{return Qc(e,{withFileTypes:!0,encoding:"utf8"}).flatMap((n)=>{let r=td(e,n.name);if(n.isDirectory())return ye(r,t);if(n.name.endsWith(".jsonl"))return[r];return[]})}catch{if(t&&Xc(e))t.count++;return[]}}function Gn(e){let t=(o)=>`${o.sessionId}
3
- ${Ge(o.segment||o.command)}`,n=e.filter((o)=>o.decision!=="allow"),r=n.filter((o)=>o.sessionId).reduce((o,i)=>o.set(t(i),(o.get(t(i))??0)+1),new Map);return new Set(n.filter((o)=>o.failureStage||(r.get(t(o))??0)>=2))}var nd=["segment","reason","sessionId","decision","agent","ruleId","failureStage"];function rd(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e;if(typeof t.ts!=="string"||typeof t.command!=="string")return!1;return nd.every((n)=>t[n]===void 0||typeof t[n]==="string")}function xe(e,t){try{return ed(e,"utf-8").split(`
4
- `).filter(Boolean).flatMap((n)=>{try{let r=JSON.parse(n);if(!rd(r)){if(t)t.count++;return[]}return[r]}catch{if(t)t.count++;return[]}})}catch{if(t)t.count++;return[]}}import{resolve as Ed}from"node:path";var od=["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 Fo(e){let t=0,n={allocateSegment(){return t++},getNextSegmentIndex(){return t},recordGlobal(r){e.record({kind:"step",scope:"global",step:r})},recordSegment(r,o=n.currentSegmentIndex){if(o===void 0)return;e.record({kind:"step",scope:"segment",segmentIndex:o,step:r})}};return n}function Ho(e={}){let t=[],n=e.maxEvents??512,r={maxTextLength:e.maxTextLength??2048,maxListLength:e.maxListLength??128,maxObjectProperties:e.maxObjectProperties??e.maxListLength??128,maxDepth:e.maxDepth??16},o=0,i,s=new Set;return{record(a){if(i)return;try{if(!a||t.length>=n){o++;return}t.push(qn(id(a,r,s)))}catch{o++}},finish(a){if(i)return i;try{i=qn({events:Object.freeze(t),droppedEvents:o,terminal:sd(a,r,s)})}catch{o++,i=Object.freeze({events:Object.freeze(t),droppedEvents:o,terminal:Object.freeze({result:"blocked",reason:"trace unavailable".slice(0,r.maxTextLength),segment:"trace unavailable".slice(0,r.maxTextLength)})})}return i}}}function id(e,t,n){if(e.kind!=="step")throw TypeError("invalid trace event");let{scope:r,step:o}=e;Bt(o,n,t);let i=Be(o,t,n);if(r==="global")return{kind:"step",scope:"global",step:i};if(r!=="segment")throw TypeError("invalid trace event scope");return{kind:"step",scope:"segment",segmentIndex:e.segmentIndex,step:i}}function sd(e,t,n){let r=e.result;if(r==="allowed")return Object.freeze({result:"allowed"});if(r!=="blocked")throw TypeError("invalid trace terminal");let o=e.ruleId;return Object.freeze({result:"blocked",reason:Be(e.reason,t,n),segment:Be(e.segment,t,n),...o?{ruleId:Be(o,t,n)}:{}})}function Bt(e,t,n,r=0,o=new WeakSet){if(typeof e==="string"){let a=e.slice(0,n.maxTextLength);if(!Vn(a))return;for(let l of No(a))for(let c of l.match(/[^\s"'()$]+/g)??[])t.add(Mo(c));return}if(!e||typeof e!=="object"||r>=n.maxDepth||o.has(e))return;if(o.add(e),Array.isArray(e)){let a=Math.min(e.length,n.maxListLength);for(let l=0;l<a;l++)Bt(e[l],t,n,r+1,o);return}let i=0,s=new Set;for(let a in e){if(!Object.hasOwn(e,a))continue;if(i>=n.maxObjectProperties)break;i++,Bt(a,t,n);let l=Bn(a,n,t);if(s.has(l))continue;s.add(l),Bt(e[a],t,n,r+1,o)}}function Be(e,t,n,r=0,o=new WeakSet){if(typeof e==="string")return Bn(e,t,n);if(!e||typeof e!=="object")return e;if(r>=t.maxDepth)return;if(o.has(e))return;if(o.add(e),Array.isArray(e)){let a=[],l=Math.min(e.length,t.maxListLength);for(let c=0;c<l;c++)a.push(Be(e[c],t,n,r+1,o));return a}let i={},s=0;for(let a in e){if(!Object.hasOwn(e,a))continue;if(s>=t.maxObjectProperties)break;s++;let l=Bn(a,t,n);if(Object.hasOwn(i,l))continue;Object.defineProperty(i,l,{value:Be(e[a],t,n,r+1,o),enumerable:!0,configurable:!0,writable:!0})}return i}function Bn(e,t,n){let r=e.slice(0,t.maxTextLength),o=Vn(r)?$o(r):r,i=n.size>0?ld(o,n):o;return(ad(i)?Oo(i):i).slice(0,t.maxTextLength)}function ad(e){return e.includes("PRIVATE KEY")||e.includes("://")||e.includes("eyJ")||e.includes(":")&&/(?:authorization|cookie|x-api-key|api-key|(?:^|\s)(?:-u|--user)(?:\s|=))/i.test(e)||e.length>=14&&od.some((t)=>e.includes(t))||e.length>=49&&/\b[a-f0-9]{32}\.[A-Za-z0-9]{16}\b/.test(e)}function ld(e,t){return e.replace(/[^\s"'()$]+/g,(n)=>t.has(Mo(n))?"<redacted>":n)}function Mo(e){let t=2166136261,n=2166136261;for(let r=0;r<e.length;r++)t=Math.imul(t^e.charCodeAt(r),16777619),n=Math.imul(n^e.charCodeAt(e.length-r-1),16777619);return`${t>>>0}:${n>>>0}:${e.length}`}function qn(e){if(e&&typeof e==="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))qn(t);Object.freeze(e)}return e}function Bo(e,t,n){let r=n??jo(),o=r.getCommandProgram(e,t.shell??"auto"),i=Ho(),s=Fo(i),a=o.dialect==="powershell"?r.getCommandProgram(e,"posix"):o,l=Uo(a);s.recordGlobal({type:"parse",input:e,segments:l.map((p)=>[...p])});let c=Go(e,{...t,analyzePartialProgram:!0,trace:s},o,r),d=s.getNextSegmentIndex();if(c&&d>0&&d<l.length)s.recordSegment({type:"segment-skipped",index:d,reason:"prior-segment-blocked"},d);return Object.freeze({decision:c,trace:i.finish(c?{result:"blocked",reason:c.reason,segment:c.evidence.find((p)=>p.kind==="command")?.segment??e,...c.ruleId?{ruleId:c.ruleId}:{}}:{result:"allowed"}),program:o})}import{resolve as cd}from"node:path";function zn(e){let t=qo().safeParse(e);return{errors:t.success?[]:zo(t.error.issues),ruleNames:new Set(Vo(e).map((n)=>n.toLowerCase()))}}function Kn(e){let t=Wo(e);if(!t.ok)return t.result;return zn(t.parsed)}function Wo(e){let t=[],n=new Set;try{let r=typeof e==="string"?mt(e):e,o=w(r);if(o===null)return t.push(`File not found: ${r.path}`),{ok:!1,result:{errors:t,ruleNames:n}};if(!o.trim())return t.push("Config file is empty"),{ok:!1,result:{errors:t,ruleNames:n}};return{ok:!0,parsed:JSON.parse(o)}}catch(r){if(r instanceof N)return t.push(r.message),{ok:!1,result:{errors:t,ruleNames:n}};let o=r instanceof Error?r.message:String(r);return t.push(r instanceof SyntaxError?"Invalid JSON":o),{ok:!1,result:{errors:t,ruleNames:n}}}}function Jo(e){return cd(e??process.cwd(),".safety-net.json")}function le(e){let t=Wo(e);if(!t.ok)return t.result;let n=Ko(t.parsed);return{errors:n.errors,ruleNames:n.sources}}import{isAbsolute as dd,join as gt,relative as ud,resolve as Yo,sep as pd}from"node:path";async function We(e={}){let t=nr(e);return fd(t,await qt(t,Ve()))}function fd(e,t){if(!t.ok)return t;let n=J(e),r=[...new Set(ce(n.configPath,n.lockPath,e,n.filesystemScope))];if(r.length===0)return t;return{ok:!1,errors:r,warnings:t.warnings,entries:t.entries}}async function qt(e,t,n,r={}){let o=null,i=!1;try{let s=J(e),a=Qn(s.configTarget);if(!a.ok)return a.result;let l=a.config;if(e.check)return vd(l,s,e);o={target:s.lockTarget,content:w(s.lockTarget)};let c=er(s.lockTarget);if(c.errors.some((L)=>L.startsWith("Unable to access ")))return{ok:!1,errors:c.errors,warnings:[],entries:[]};if(e.only&&c.errors.length>0)return{ok:!1,errors:c.errors,warnings:[],entries:[]};let d=c.errors.length>0?null:c.lock,p=e.only?oi(l,d,e.only):{ok:!0,specs:l.rules};if(!p.ok)return p.result;if(e.only&&!d&&p.specs.length<l.rules.length)return{ok:!1,errors:[`No lockfile available for partial update; run ${ni}`],warnings:[],entries:[]};let g=(await gd(p.specs,(L)=>si(L,s.configDir,e,d,s.filesystemScope,t),t)).map((L)=>bd(L,d,n));for(let L of g)kd(L.content,L.entry,s.configDir,e,s.filesystemScope);let u=e.only?wd(l,d,g):g.map((L)=>L.entry);i=!0,Z(s.lockTarget,{version:1,rulebooks:u},void 0,r._testAfterPolicyRename);let m=new Map(g.map((L)=>[L.entry.spec,L.rulebook.rules.length])),f=Cd(u,s.configDir,e,s.filesystemScope,r);return{ok:!0,errors:[],warnings:f,entries:u.map((L)=>xd(L,m))}}catch(s){if(i&&o)try{qe(o.target,o.content)}catch(a){return ze(a)}return ze(s)}}async function tr(e,t={}){return md(e,nr(t),Ve())}async function md(e,t,n,r={}){let o=null,i=!1;try{let s=J(t),a=w(s.configTarget);o={target:s.configTarget,content:a};let l=Qn(s.configTarget);if(!l.ok)return l.result;let c=l.config,d=ti(e)?await ai(e,n):[{spec:e}],p=d.map((m)=>m.spec),g=[...new Set([...c.rules,...p])];if(g.length>Zn)return hd();if(g.length!==c.rules.length)i=!0,Z(s.configTarget,{version:1,rules:g,overrides:c.overrides??{},transparent_wrappers:c.transparent_wrappers??[]},void 0,r._testAfterPolicyRename);let u=await qt(t,n,new Map(d.filter((m)=>!!m.display_ref).map((m)=>[m.spec,m.display_ref])),r);if(!u.ok)qe(s.configTarget,a);return u}catch(s){if(i&&o)try{qe(o.target,o.content)}catch(a){return ze(a)}return ze(s)}}async function gd(e,t,n=Ve()){if(e.length>Zn)throw Error(Xn);let r=Array(e.length),o=0,i,s=Array.from({length:Math.min(e.length,ri.concurrency)},async()=>{while(!i){let a=o;if(a>=e.length)return;o++;try{r[a]=await t(e[a],a,n.controller.signal)}catch(l){if(!i)i={value:l},o=e.length,n.controller.abort(l);return}}});if(await Promise.all(s),i)throw i.value;return r}function hd(){return{ok:!1,errors:[Xn],warnings:[],entries:[]}}function nr(e){return{cwd:e.cwd,cacheConfigDir:e.cacheConfigDir,userConfigDir:e.userConfigDir,userConfigPath:e.userConfigPath,projectConfigPath:e.projectConfigPath,global:e.global,check:e.check,only:e.only,refresh:e.refresh}}function yd(e){return{...nr(e),deleteSource:e.deleteSource}}async function rr(e,t={}){try{return await Ld(e,yd(t),{})}catch(n){return ze(n)}}async function Ld(e,t,n){let r=J(t),o=Y(r.configTarget);if(o.errors.length>0)return{ok:!1,errors:o.errors,warnings:[],entries:[]};if(!o.config)return{ok:!1,errors:[`No config found at ${r.configPath}`],warnings:[],entries:[]};let i=er(r.lockTarget);if(i.errors.length>0)return{ok:!1,errors:i.errors,warnings:[],entries:[]};let s=ii(o.config.rules,i.lock,e);if(!s.ok)return s.result;let a=t.deleteSource?Sd(r.configDir,s.specs,i.lock,r.filesystemScope):{ok:!0,dirs:[]};if(!a.ok)return a.result;let l=w(r.configTarget);if(l===null)return ze(Error("Rules config is unavailable."));try{Z(r.configTarget,{version:1,rules:o.config.rules.filter((p)=>!s.specs.includes(p)),overrides:o.config.overrides??{},transparent_wrappers:o.config.transparent_wrappers??[]},void 0,n._testAfterPolicyRename)}catch(p){throw qe(r.configTarget,l),p}let c=await qt(t,Ve(),void 0,n);if(!c.ok)return qe(r.configTarget,l),c;let d=Dd(r.configDir,a.dirs,n,r.filesystemScope);if(!d.ok){qe(r.configTarget,l);let p=await qt(t,Ve(),void 0,n);if(!p.ok)return{ok:!1,errors:[...d.result.errors,...p.errors],warnings:p.warnings,entries:p.entries};return d.result}return c}async function vd(e,t,n){let r=li(e,t.lockPath,t.configDir,n,n.global?"user":"project",t.filesystemScope);return{ok:r.errors.length===0&&r.warnings.length===0,errors:[...r.errors,...r.warnings],warnings:[],entries:r.entries}}function bd(e,t,n){let r=t?.rulebooks.find((i)=>i.spec===e.entry.spec&&i.kind==="github"),o=n?.get(e.entry.spec)??(r?.kind==="github"?r.display_ref:void 0);if(!o||e.entry.kind!=="github")return e;return{...e,entry:{...e.entry,display_ref:o}}}function wd(e,t,n){let r=new Set(e.rules),o=new Set(t?.rulebooks.map((s)=>s.spec)??[]),i=new Map(n.map((s)=>[s.entry.spec,s.entry]));return[...(t?.rulebooks.filter((s)=>r.has(s.spec))??[]).map((s)=>i.get(s.spec)??s),...n.filter((s)=>!o.has(s.entry.spec)).map((s)=>s.entry)]}function xd(e,t){return{...e,ruleCount:t.get(e.spec)}}function kd(e,t,n,r,o){let i=Jn(t,Yn(n,r));ke(x(o,i),e)}function Cd(e,t,n,r,o){let i=Yn(t,n),s=Vt(i),a=x(r,s),l=Ce(a);if(!l)return[];let c=e.map((p)=>x(r,Jn(p,i))),d=l.filter((p)=>p.kind==="directory").map((p)=>({directory:x(r,gt(s,p.name)),identity:x(r,gt(s,p.name,Wn))})).filter((p)=>!c.some((g)=>Zo(p.identity,g))).map((p)=>p.directory);for(let p of d)ei(p);return d.flatMap((p)=>{try{return Rd(p,o),[]}catch{return["Unable to prune rules policy cache safely."]}})}function Sd(e,t,n,r){let o=new Map(n?.rulebooks.map((c)=>[c.spec,c])??[]),i=t.flatMap((c)=>{let d=o.get(c);if(!d)return ht.test(c)?[]:["--delete-source can only delete local rulebook sources"];return d.kind==="local-directory"?[]:["--delete-source can only delete local rulebook sources"]}),s=t.map((c)=>{let d=o.get(c);return gt(e,d?.kind==="local-directory"?d.path:c)}),a=i.length>0?[]:s.flatMap((c)=>ci(e,c,r)),l=[...i,...a];return l.length>0?{ok:!1,result:{ok:!1,errors:l,warnings:[],entries:[]}}:{ok:!0,dirs:s}}function ci(e,t,n){let r=Yo(e),o=Yo(t),i=ud(r,o);if(i===""||i===".."||i.startsWith(`..${pd}`)||dd(i))return[`Refusing to delete local rulebook source outside ${e}: ${t}`];let s=x(n,o),a=Ce(s);if(!a)return[`Local rulebook source directory not found: ${t}`];let l=a.find((c)=>c.name==="rulebook.json");if(!l)return[`Local rulebook source directory is missing rulebook.json: ${t}`];if(l.kind!=="file")throw new N(n.label);if(w(x(n,gt(o,"rulebook.json"))),a.length>1)return[`Local rulebook source directory contains extra files: ${t}. delete manually if you really want to remove the directory.`];return[]}function Dd(e,t,n,r){let o=t.flatMap((i)=>{try{if(!Ce(x(r,i)))return[];let s=ci(e,i,r);if(s.length>0)return s;return Ad(i,n,r),[]}catch(s){return[`Failed to delete local rulebook source ${i}: ${s instanceof Error?s.message:String(s)}`]}});return o.length>0?{ok:!1,result:{ok:!1,errors:o,warnings:[],entries:[]}}:{ok:!0}}function Rd(e,t){if(t._testPruneRulebookCacheDir){t._testPruneRulebookCacheDir(e.path);return}Xo(e)}function Ad(e,t,n){if(t._testDeleteLocalSourceDir){t._testDeleteLocalSourceDir(e);return}Ke(x(n,gt(e,Wn))),Qo(x(n,e))}function qe(e,t){if(t===null){Ke(e);return}ke(e,t)}function ze(e){return{ok:!1,errors:[e instanceof Error?e.message:String(e)],warnings:[],entries:[]}}function Xe(e,t){let n=Td(t),r=gi(n),o={effectiveLevel:r.effectiveLevel,selectedPreset:n.policySnapshot.policy.safety.level??"standard",effectiveCapabilities:r.effectiveCapabilities,destructiveCommandRuleOverrides:n.policySnapshot.policy.destructiveCommandRuleOverrides},{configSource:i,configValid:s}=Pd({cwd:t?.cwd,userConfigDir:t?.userConfigDir});if(!e||!e.trim())return{trace:{steps:[{type:"error",message:"No command provided"}],segments:[]},result:"allowed",configSource:i,configValid:s,...o};let a=Id(e,n);if(a)return{trace:{steps:[],segments:[{index:0,steps:[{type:"rule-check",rule:a.rule,matched:!0,reason:a.reason}]}]},result:"blocked",reason:G(a.reason),segment:G(a.target),...a.ruleId?{ruleId:G(a.ruleId)}:{},configSource:i,configValid:s,...o};let l=Bo(e,n),c=l.decision,d=c?.ruleId??_d(e,n),p=Lt.find((u)=>u.id===d&&u.activationCapability),g=p?r.policy.effectiveDestructiveCommandRules[p.id]:void 0;return{trace:$d(l.trace),result:c?"blocked":"allowed",reason:c?G(c.reason):void 0,segment:c?G(c.evidence.find((u)=>u.kind==="command")?.segment??e):void 0,ruleId:c?.ruleId?G(c.ruleId):void 0,customRule:Od(Nd(c?.ruleId,n.policySnapshot)),configSource:i,configValid:s,...o,...p&&g?{ruleActivation:{id:p.id,...g}}:{}}}function Pd(e){let t=X(e?.cwd),n=e?.userConfigPath??Q(e),r=ee({cwd:e?.cwd,userConfigDir:e?.userConfigDir,userConfigPath:e?.userConfigPath});try{if(w(r.projectConfigTarget)!==null){if(le(r.projectConfigTarget).errors.length===0)return{configSource:t,configValid:!0};return{configSource:t,configValid:!1}}}catch(o){if(o instanceof N)return{configSource:t,configValid:!1};throw o}try{if(w(r.userConfigTarget)!==null){let o=le(r.userConfigTarget);return{configSource:n,configValid:o.errors.length===0}}return{configSource:null,configValid:!0}}catch(o){if(o instanceof N)return{configSource:n,configValid:!1};throw o}}function Td(e){let t=Ed(e?.cwd??process.cwd()),n=e?.policySnapshot??B({cwd:t,userConfigDir:e?.userConfigDir}),r=de(n.policy);return{cwd:t,effectiveCwd:t,policySnapshot:n,environment:di(),protectedGitMetadata:mi([t]),effectiveCapabilities:r.capabilities,strict:e?.strict??r.strict,paranoidRm:r.paranoidRm,paranoidInterpreters:r.paranoidInterpreters,worktreeMode:r.worktreeMode}}function Id(e,t){let n=t.cwd??process.cwd(),r=ui(Ze("",{command:e},{kind:"command",shell:"posix"},{executionCwd:n,configCwd:n},e)),o=Li(r);if(o)return{reason:yi,target:o.target,ruleId:"policy-protection",rule:"policy-protection:findPolicyConfigMutationTargetInSemanticFacts"};let i=fi(r,t.protectedGitMetadata);if(i)return{reason:pi,target:i.target,ruleId:"git-metadata-protection",rule:"git-metadata-protection:findGitMetadataMutationTargetInSemanticFacts"};let s=t.policySnapshot.policy,a=s.secretProtection.enabled===!1?null:bi(r,s.secretProtection,{strict:t.strict});if(a)return{reason:vi,target:a.target,ruleId:a.ruleId,rule:"secret-protection:findSensitiveTargetInSemanticFacts"};return null}function _d(e,t){let n=t.policySnapshot.policy,r=vt({...n,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:{...n.destructiveCommandRuleOverrides,...Object.fromEntries(Lt.flatMap((o)=>o.activationCapability?[[o.id,"on"]]:[]))}},t.policySnapshot.state==="degraded"?{diagnostics:t.policySnapshot.diagnostics,reason:t.policySnapshot.reason}:void 0);return hi(e,{...t,policySnapshot:r,strict:!0,paranoidRm:!0,paranoidInterpreters:!0})?.ruleId}function Od(e){if(!e)return;return{id:G(e.id),...e.rulebook?{rulebook:{name:G(e.rulebook.name),version:G(e.rulebook.version)}}:{},...e.source?{source:G(e.source)}:{},...e.override?{override:{type:"reason",reason:G(e.override.reason)}}:{}}}function $d(e){let t=e.events.flatMap((r)=>r.kind==="step"&&r.scope==="global"?[r.step]:[]),n=new Map;for(let r of e.events){if(r.kind!=="step"||r.scope!=="segment")continue;let o=n.get(r.segmentIndex)??{index:r.segmentIndex,steps:[]};o.steps.push(r.step),n.set(r.segmentIndex,o)}return{steps:t,segments:[...n.values()]}}function Nd(e,t){let n=e?.replace(/^custom\./,"");if(!n||!t.policy.rules.some((r)=>r.name===n))return;return t.ruleMetadata[n]??Object.freeze({id:n})}function Gd(e){let t=Qe(),n=T({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"]}},e);if(ae(n.errors))return null;if(n.values.id!==void 0&&!/^[a-f0-9]{16}$/.test(n.values.id))return console.error("--id must be 16 hexadecimal characters"),null;let r=n.values.limit===void 0?20:wi(n.values.limit);if(r===null)return console.error("--limit must be a positive number"),null;let o=n.values.since===void 0?Math.min(30,t):wi(n.values.since);if(o===null||o>t)return console.error(`--since must be a positive number of days no greater than ${t}`),null;let i={limit:r,limitExplicit:n.values.limit!==void 0,since:o,sinceExplicit:n.values.since!==void 0,all:n.flags.all,json:n.flags.json,suspect:n.flags.suspect,pruneLegacy:n.flags.pruneLegacy,dryRun:n.flags.dryRun,id:n.values.id,agent:n.values.agent,rule:n.values.rule,session:n.values.session,project:n.values.project===void 0?void 0:Ud(n.values.project)};if(i.id&&(i.agent!==void 0||i.rule!==void 0||i.session!==void 0||i.project!==void 0||i.suspect||i.sinceExplicit||i.limitExplicit))return console.error("--id cannot be combined with --agent, --rule, --session, --project, --suspect, --since, or --limit"),null;if(i.pruneLegacy&&(i.id!==void 0||i.agent!==void 0||i.rule!==void 0||i.session!==void 0||i.project!==void 0||i.suspect||i.all||i.sinceExplicit||i.limitExplicit))return console.error("--prune-legacy cannot be combined with --id, --agent, --rule, --session, --project, --suspect, --all, --since, or --limit"),null;if(i.dryRun&&!i.pruneLegacy)return console.error("--dry-run requires --prune-legacy"),null;return i}async function Ci(e,t={}){let n=Gd(e);if(!n)return 1;let r=t.logsDir??ue();if(n.pruneLegacy)return Bd(r,n.json,n.dryRun);if(!r)return console.log(n.json?"[]":n.id?`No retained audit log entry found for id ${I(n.id)}.`:"No audit log entries found."),0;De(r);let o={count:0},i=ye(r,o).flatMap((d)=>xe(d,o).map((p)=>({entry:p,file:d})));if(o.count>0)console.error(`warning: ${o.count} audit log ${o.count===1?"source":"sources"} could not be read; these results are incomplete`);if(n.id)return Kd(i,n,t.timeZone);let s=Date.now()-n.since*24*60*60*1000,a=i.filter((d)=>Wd(d,n,r,s)),l=n.suspect?Gn(a.map((d)=>d.entry)):null,c=(l?a.filter((d)=>l.has(d.entry)):a).sort((d,p)=>Date.parse(p.entry.ts)-Date.parse(d.entry.ts)).slice(0,n.limit);if(n.json)return console.log(JSON.stringify(c.map((d)=>d.entry),null,2)),0;if(c.length===0)return console.log("No audit log entries found."),0;for(let d of c)console.log(Zd(d.entry,t.timeZone));return 0}function Bd(e,t,n){let r=e?Vd(e).map((a)=>jd(e,a)):[];if(n)return qd(r,t);let o=[],i=0,s=0;for(let a of r){let l=xi(a,{throwIfNoEntry:!1})?.size??0,c=zd(a);if(c){o.push(`${ki(a)}: ${c}`);continue}i++,s+=l}if(t)return console.log(JSON.stringify({removedFiles:i,removedBytes:s,failedFiles:o.length})),o.length===0?0:1;console.log(i===0&&o.length===0?"No legacy audit log files found.":`Removed ${i} legacy audit log ${i===1?"file":"files"} (${Si(s)}).`);for(let a of o)console.error(`Could not remove ${I(a)}`);if(console.log("Nested v2 audit logs were not changed."),i>0)console.log("This deletion cannot be undone.");return o.length===0?0:1}function qd(e,t){let n=e.reduce((r,o)=>r+(xi(o,{throwIfNoEntry:!1})?.size??0),0);if(t)return console.log(JSON.stringify({dryRun:!0,files:e.length,bytes:n})),0;if(console.log(e.length===0?"No legacy audit log files found.":`Would remove ${e.length} legacy audit log ${e.length===1?"file":"files"} (${Si(n)}).`),console.log("Nested v2 audit logs are not included."),e.length>0)console.log("Run the same command without --dry-run to delete them.");return 0}function Vd(e){try{return Fd(e,{withFileTypes:!0}).filter((t)=>t.isFile()&&t.name.endsWith(".jsonl")).map((t)=>t.name)}catch{return[]}}function zd(e){try{return Hd(e),null}catch(t){return t instanceof Error?t.message:String(t)}}function Si(e){let t=["B","KiB","MiB","GiB"],n=Math.min(Math.floor(Math.log2(Math.max(e,1))/10),t.length-1);return`${Math.round(e/1024**n*10)/10} ${t[n]}`}function Kd(e,t,n){let r=e.filter((i)=>i.entry.id===t.id);if(r.length>1)return console.error(`Multiple audit log entries found for id ${I(t.id??"")}.`),1;if(t.json)return console.log(JSON.stringify(r.map((i)=>i.entry),null,2)),0;let o=r[0];if(!o)return console.log(`No retained audit log entry found for id ${I(t.id??"")}.`),0;return console.log(Xd(o.entry,n)),0}function Wd(e,t,n,r){if(!t.all&&e.entry.decision==="allow")return!1;if(Date.parse(e.entry.ts)<r)return!1;if(t.agent!==void 0&&e.entry.agent!==t.agent)return!1;if(t.rule!==void 0&&e.entry.ruleId!==t.rule)return!1;if(t.session!==void 0&&!Jd(e,n,t.session))return!1;if(t.project!==void 0&&!Yd(e.entry.cwd,t.project))return!1;return!0}function Jd(e,t,n){if(e.entry.sessionId===n)return!0;return Md(e.file)===t&&ki(e.file,".jsonl")===n}function Yd(e,t){if(!e)return!1;return e===t||e.startsWith(`${t}/`)}function Zd(e,t){let n=I(e.id??"-"),r=I(e.decision??"deny"),o=e.cwd?` [${I(e.cwd)}]`:"",i=e.segment||e.command,s=i===e.command?"":"↳ ",a=i.length>50?`${i.slice(0,50)}…`:i;return`${n.padEnd(16)} ${I(Di(e.ts,t))} ${r.padEnd(5)} ${I(e.agent??"-").padEnd(15)} ${I(e.ruleId??"-").padEnd(20)} ${s}${I(a)}${o}`}function Xd(e,t){let n=(o)=>I(o===void 0||o===null||o===""?"-":o),r=e.shape?`${e.agent??"-"} (shape: ${e.shape})`:e.agent??"-";return[`id: ${n(e.id)}`,`ts: ${n(Di(e.ts,t))}`,`decision: ${n(e.decision)}`,`agent: ${n(r)}`,`level: ${n(e.level)}`,`tool: ${n(e.toolName)}`,`rule: ${n(e.ruleId)}`,`intent: ${n(e.intent)}`,`stage: ${n(e.failureStage)}`,`error: ${n(e.errorCode)}`,`session: ${n(e.sessionId)}`,`cwd: ${n(e.cwd)}`,`version: ${n(e.v)}`,`truncated: ${n(e.truncated===!0?"yes":void 0)}`,`reason: ${n(e.reason)}`,`command: ${n(e.command)}`,`segment: ${n(e.segment)}`].join(`
5
- `)}function Di(e,t){let n=new Date(e);if(Number.isNaN(n.getTime()))return e;return new Intl.DateTimeFormat("sv-SE",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hourCycle:"h23",timeZone:t}).format(n)}function wi(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}var Ri={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 Ai={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 Ei={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"]};import{isAbsolute as Hi,join as cu,relative as du}from"node:path";var Qd=8388608;function eu(e,t){console.log(JSON.stringify(e(Ti(t))))}async function tu(e){let t;try{t=(await Lr(process.stdin)).trim()}catch{e({reason:"Failed to parse hook input JSON."});return}if(!t){e({reason:"Missing hook input JSON."});return}return vr(t,e,"Failed to parse hook input JSON.")}async function Lr(e){let t=[],n=0;for await(let r of e){let o=typeof r==="string"?Buffer.from(r,"utf-8"):Buffer.from(r.buffer,r.byteOffset,r.byteLength);if(n+=o.byteLength,n>Qd)throw nu(e),Error("hook input byte limit exceeded");t.push(o)}return Buffer.concat(t,n).toString("utf-8")}function nu(e){let t=e.destroy??e.cancel;if(!t)return;try{Promise.resolve(t.call(e)).catch(()=>{})}catch{}}function vr(e,t,n){try{return JSON.parse(e)}catch{t({reason:n});return}}function M(e,t){let n=t.get(e);return n?{kind:"command",shell:n}:{kind:_i(e)}}function te(e,t,n,r){let o=e===void 0?process.cwd():e,i=typeof o==="string"&&o.trim()!==""?fe([o]):void 0;if(i)return{configCwd:i,executionCwd:i};return O(r,t,n,su(o)),null}function O(e,t,n,r){let o;try{o=yr(t)}catch(i){if(!(i instanceof pe))throw i}e(zt({command:o,segment:r,toolName:n}))}async function ru(e){let t=await tu(e.outputDeny);if(t===void 0)return;if(!t||typeof t!=="object"||Array.isArray(t)){O(e.outputDeny);return}if(!e.isSupported(t))return;let n=e.getAgent?.(t)??e.agent,r=e.agent===n?void 0:e.agent,o=lu(t),i=(u,m)=>{Pi(u,()=>e.getSessionId(t),{agent:n,shape:r,toolName:m,cwd:o}),e.outputDeny(u)},s=e.getToolName(t);if(typeof s!=="string"||s.trim()===""){O((u)=>i(u),au(t));return}let a=s,l=(u)=>i(u,a),c;try{c=e.getToolInput(t,a,l)}catch(u){if(!(u instanceof pe))throw u;O(l,void 0,a);return}if(!c.ok)return;let d=e.getContext(t,c.input,a,l);if(!d)return;let p;try{p=yr(c.input)}catch(u){if(!(u instanceof pe))throw u;O(l,void 0,a);return}let g=Ze(a,c.input,c.route,d,p??null);try{let u=Kt(g,{guard:{auditAllowed:Oi(),dependencies:e.guardDependencies},audit:{agent:n,shape:r,getSessionId:()=>e.getSessionId(t)}}),m=hr(u,{includeEvidence:!0,toolName:u.stage==="command-analysis"?void 0:a});if(m){e.outputDeny(m);return}e.outputAllow?.()}catch(u){if(!(u instanceof $i))throw u;ou(u);let m=hr(u.evaluation,{includeEvidence:!0,toolName:u.evaluation.stage==="command-analysis"?void 0:a});if(m)e.outputDeny(m);return}}function ou(e){if(!bt(S.debug))return;console.error(`CC Safety Net debug: ${iu(e.stage)}: ${Ii(e.cause)}`)}function iu(e){if(e==="policy-protection")return"hook policy protection failed";if(e==="config-load")return"hook config loading failed";if(e==="secret-protection")return"hook secret protection failed";return"hook analysis failed"}function su(e){return typeof e==="string"?e:void 0}function au(e){if(!e||typeof e!=="object"||Array.isArray(e))return;if(Object.hasOwn(e,"tool_input"))return e.tool_input;let t=e.toolCall;if(t&&typeof t==="object"&&!Array.isArray(t))return t.args;return}function lu(e){if(!e||typeof e!=="object"||Array.isArray(e))return null;let t=e.cwd;if(typeof t==="string")return t;let n=e.toolCall;if(!n||typeof n!=="object"||Array.isArray(n))return null;let r=n.args;if(!r||typeof r!=="object"||Array.isArray(r))return null;let o=r.Cwd;return typeof o==="string"?o:null}async function j(e){let t=(o)=>eu(e.createDenyOutput,o),n=e.createAllowOutput;await ru({...e,outputDeny:t,outputAllow:n?()=>console.log(JSON.stringify(n())):void 0})}function St(e){return cu(e,".gemini","config","hooks.json")}var uu=new Map([["run_command","auto"]]),pu=new Set(["absolutepath","directorypath","file_path","filepath","path","searchdirectory","searchpath","target_file","targetfile"]);function Mi(e){return M(e,uu)}async function ji(){await j({agent:"antigravity-cli",createDenyOutput:(e)=>({decision:"deny",reason:e}),isSupported:()=>!0,getToolName:(e)=>e.toolCall?.name,getToolInput:(e,t)=>({ok:!0,input:yu(e.toolCall?.args,t),route:Mi(t)}),getContext:fu,getSessionId:(e)=>e.conversationId})}function fu(e,t,n,r){let i=hu(e).flatMap((c)=>{let d=fe([c]);return d?[d]:[]});if(!i[0])return Ee(r,t,n),null;if(n!=="run_command"){let c;try{c=mu(t,n,i)}catch(d){if(d instanceof pe)return Ee(r,void 0,n),null;if(!(d instanceof Re))throw d;return Ee(r,t,n),null}if(!c)return Ee(r,t,n),null;return{configCwd:c,executionCwd:c}}let s=e.toolCall?.args;if(!s||!Object.hasOwn(s,"Cwd"))return{configCwd:i[0],executionCwd:i[0]};let a=s.Cwd;if(typeof a!=="string"||a.trim()==="")return Ee(r,t,n),null;let l=Pe(a,i);if(l){let c=Ui(l,i);if(!c)return Ee(r,t,n,a),null;return{configCwd:c,executionCwd:l}}return Ee(r,t,n,a),null}function mu(e,t,n){let r=Mi(t),o=[...Ni(e,pu),...r.kind==="patch"?Fi(e):[]].filter(Hi),i=Wt(),s=new Set(o.flatMap((a)=>{let l=Ui(kt(a,Ct,i),n);return l?[l]:[]}));if(s.size>1)return null;return[...s][0]??n[0]??null}function Ui(e,t){return t.filter((n)=>gu(e,n)).reduce((n,r)=>r.length>n.length?r:n,"")||null}function gu(e,t){let n=du(t,e);return n===""||!n.startsWith("..")&&!Hi(n)}function Ee(e,t,n,r){let o=t&&typeof t==="object"?t.command:void 0;e(zt({command:typeof o==="string"?o:void 0,segment:r,toolName:n}))}function hu(e){if(e.workspacePaths===void 0)return[process.cwd()];let t=Array.isArray(e.workspacePaths)?e.workspacePaths.filter((n)=>typeof n==="string"&&n.trim()!==""):[];return fe(t)?t:[]}function yu(e,t){if(!e)return;if(t!=="run_command")return e;return{...e,command:typeof e.CommandLine==="string"&&e.CommandLine!==""?e.CommandLine:void 0}}var Dt=[{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,install:{order:4,flag:"--codex",artifactKind:"plugin",probeCommand:["codex","--version"]}},{id:"copilot-cli",displayName:"GitHub Copilot CLI",doctorOrder:7,runtime:{order:5,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:4,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:"hermes-agent",displayName:"Hermes Agent",doctorOrder:8,runtime:{order:6,flags:["-ha","--hermes-agent"],description:"Run as Hermes Agent pre_tool_call hook",legacyTopLevelFlags:[]},install:{order:8,flag:"--hermes-agent",artifactKind:"plugin",probeCommand:["hermes","--version"]}},{id:"kimi-code",displayName:"Kimi Code",doctorOrder:9,runtime:{order:7,flags:["-kc","--kimi-code"],description:"Run as Kimi Code PreToolUse hook",legacyTopLevelFlags:[]},install:{order:9,flag:"--kimi-code",artifactKind:"hook config",probeCommand:["kimi","--version"]}},{id:"openclaw",displayName:"OpenClaw",doctorOrder:10,install:{order:10,flag:"--openclaw",artifactKind:"plugin",probeCommand:["openclaw","--version"]}},{id:"opencode",displayName:"OpenCode",doctorOrder:11,install:{order:11,flag:"--opencode",artifactKind:"plugin",probeCommand:["opencode","--version"]}},{id:"pi",displayName:"Pi",doctorOrder:12,install:{order:12,flag:"--pi",artifactKind:"package",probeCommand:["pi","--version"]}},{id:"cursor",displayName:"Cursor",doctorOrder:5,runtime:{order:3,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"]}}],Jt=Dt.slice().sort((e,t)=>e.doctorOrder-t.doctorOrder).map((e)=>e.id),Gi=Dt.filter((e)=>("runtime"in e)).slice().sort((e,t)=>e.runtime.order-t.runtime.order).map((e)=>({id:e.id,displayName:"displayName"in e.runtime?e.runtime.displayName:e.displayName,flags:e.runtime.flags,legacyFlags:"legacyFlags"in e.runtime?e.runtime.legacyFlags:[],description:e.runtime.description,legacyTopLevelFlags:e.runtime.legacyTopLevelFlags})),V=Dt.slice().sort((e,t)=>e.install.order-t.install.order).map((e)=>({id:e.id,...e.install})).map(({order:e,...t})=>t),oh=Object.fromEntries(Dt.map((e)=>[e.id,e.displayName]));function R(e){return Dt.find((t)=>t.id===e)?.displayName??e}import{homedir as Lu}from"node:os";import{isAbsolute as Bi,join as br}from"node:path";function Vi(e){if(e!==void 0&&e!==null&&typeof e!=="string")return"unknown";if(typeof e==="string"&&!Bi(e))return"unknown";try{let t=Wt(),n=typeof e==="string"&&e?kt(e,Ct,t):void 0,r=process.env.HOME||Lu(),o=[["codex",process.env.CODEX_HOME||br(r,".codex")],["copilot-cli",process.env.COPILOT_HOME||br(r,".copilot")],["claude-code",process.env.CLAUDE_CONFIG_DIR||br(r,".claude")]],i=n?o.flatMap(([s,a])=>{if(!Bi(a))return[];return qi(n,kt(a,Ct,t))?[s]:[]}):[];if(i.length===1)return i[0]??"unknown";if(i.length>1)return"unknown"}catch(t){if(t instanceof Re)return"unknown";return"unknown"}if(process.env.CLAUDECODE==="1"||Boolean(process.env.CLAUDE_CODE_ENTRYPOINT))return"claude-code";return"unknown"}var wr="PreToolUse",zi="BeforeTool",Ki="pre_tool_call",xr="PreToolUse";var vu=new Map([["Bash","posix"],["PowerShell","powershell"]]);function bu(e){return M(e,vu)}async function Wi(){await j({agent:"claude-code",getAgent:(e)=>Vi(e.transcript_path),createDenyOutput:(e)=>({hookSpecificOutput:{hookEventName:wr,permissionDecision:"deny",permissionDecisionReason:e}}),isSupported:(e)=>e.hook_event_name===wr,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:bu(t)}),getContext:(e,t,n,r)=>te(e.cwd,t,n,r),getSessionId:(e)=>e.session_id})}var wu=new Map([["bash","auto"],["Bash","auto"],["powershell","powershell"],["PowerShell","powershell"]]);function xu(e){return M(e,wu)}async function Ji(){await j({agent:"copilot-cli",createDenyOutput:(e)=>({permissionDecision:"deny",permissionDecisionReason:e}),isSupported:()=>!0,getToolName:(e)=>e.toolName,getToolInput:(e,t,n)=>{if(typeof e.toolArgs!=="string")return n({reason:"Failed to parse toolArgs JSON."}),{ok:!1};let r=vr(e.toolArgs,n,"Failed to parse toolArgs JSON.");if(r===void 0)return{ok:!1};return{ok:!0,input:r,route:xu(t)}},getContext:(e,t,n,r)=>te(e.cwd,t,n,r),getSessionId:(e)=>typeof e.sessionId==="string"&&e.sessionId.trim()?e.sessionId:void 0})}var ku=new Map([["Shell","auto"]]);function Cu(e){return M(e,ku)}async function Yi(){await j({agent:"cursor",createDenyOutput:(e)=>({permission:"deny",user_message:e,agent_message:e}),createAllowOutput:()=>({permission:"allow"}),isSupported:()=>!0,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:Cu(t)}),getContext:Su,getSessionId:(e)=>e.conversation_id})}function Su(e,t,n,r){let o=Du(e);if(!o[0])return O(r,t,n),null;let i=Pe(Au(e.cwd),o);if(!i)return O(r,t,n,typeof e.cwd==="string"?e.cwd:void 0),null;if(t===null||typeof t!=="object"||Array.isArray(t))return{configCwd:i,executionCwd:i};if(!Object.hasOwn(t,"working_directory"))return{configCwd:i,executionCwd:i};let s=t.working_directory;if(typeof s!=="string"||s.trim()==="")return O(r,t,n),null;let a=Pe(s,o);if(!a)return O(r,t,n,s),null;return{configCwd:i,executionCwd:a}}function Du(e){return Ru(e).flatMap((t)=>{let n=fe([t]);return n?[n]:[]})}function Ru(e){if(e.workspace_roots===void 0)return typeof e.cwd==="string"&&e.cwd.trim()!==""?[e.cwd]:[];if(!Array.isArray(e.workspace_roots))return[];return e.workspace_roots.filter((t)=>typeof t==="string"&&t.trim()!=="")}function Au(e){return typeof e==="string"&&e.trim()!==""?e:"."}var Eu=new Map([["run_shell_command","auto"]]);function Pu(e){return M(e,Eu)}async function Zi(){await j({agent:"gemini-cli",createDenyOutput:(e)=>({decision:"deny",reason:e,systemMessage:e}),isSupported:(e)=>e.hook_event_name===zi,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:Pu(t)}),getContext:(e,t,n,r)=>te(e.cwd,t,n,r),getSessionId:(e)=>e.session_id})}import{resolve as Tu}from"node:path";var Iu=new Map([["terminal","posix"]]);async function Xi(){await j({agent:"hermes-agent",createDenyOutput:(e)=>({action:"block",message:e}),isSupported:(e)=>e.hook_event_name===Ki,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:M(t,Iu)}),getContext:_u,getSessionId:(e)=>e.session_id})}function _u(e,t,n,r){let o=te(e.cwd,t,n,r);if(!o)return null;if(!t||typeof t!=="object"||Array.isArray(t))return o;if(!Object.hasOwn(t,"workdir"))return o;let i=t.workdir;if(typeof i!=="string"||i.trim()==="")return O(r,t,n),null;let s=fe([Tu(o.configCwd,i)]);if(!s)return O(r,t,n,i),null;return{...o,executionCwd:s}}var Qi=new Map([["Bash","posix"]]);function Ou(e){return M(e,Qi)}async function es(){await j({agent:"kimi-code",createDenyOutput:(e)=>({hookSpecificOutput:{hookEventName:xr,permissionDecision:"deny",permissionDecisionReason:e}}),isSupported:(e)=>e.hook_event_name===xr,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:Ou(t)}),getContext:(e,t,n,r)=>{let o=te(e.cwd,t,n,r);if(!o)return null;let i=e.tool_input;if(!Qi.has(n)||!i||!Object.hasOwn(i,"cwd"))return o;let s=i.cwd;if(typeof s!=="string"||s.trim()==="")return O(r,t,n),null;let a=Pe(s,[o.configCwd]);if(!a)return O(r,t,n,s),null;return{configCwd:o.configCwd,executionCwd:a}},getSessionId:(e)=>e.session_id})}var $u={"antigravity-cli":ji,"claude-code":Wi,"copilot-cli":Ji,cursor:Yi,"gemini-cli":Zi,"hermes-agent":Xi,"kimi-code":es},et=Gi.map((e)=>({...e,run:$u[e.id]}));function ts(e){let t=T({label:"hook",booleans:Object.fromEntries(et.map((r)=>[r.id,[...r.flags,...r.legacyFlags]]))},e);if(t.errors.length>0)return;let n=et.filter((r)=>t.flags[r.id]);return n.length===1?n[0]:void 0}function ns(e){return et.find((t)=>t.legacyTopLevelFlags.some((n)=>n===e))}var Nu=et.map((e)=>({flags:e.flags.join(", "),description:e.description})),Fu=et.flatMap((e)=>e.flags.map((t)=>`cc-safety-net hook ${t}`)),rs={name:"hook",description:"Run as an agent CLI hook (reads JSON from stdin)",usage:"hook INTEGRATION_FLAG",options:[...Nu,{flags:"-h, --help",description:"Show this help"}],examples:Fu};var os={name:"install",description:"Install CC Safety Net into a coding agent CLI",usage:"install [TARGET_FLAG]",options:[...V.map((e)=>({flags:e.flag,description:`Install ${R(e.id)} ${e.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net install",...V.map((e)=>`cc-safety-net install ${e.flag}`)]},is={name:"uninstall",description:"Uninstall CC Safety Net from a coding agent CLI",usage:"uninstall [TARGET_FLAG]",options:[...V.map((e)=>({flags:e.flag,description:`Uninstall ${R(e.id)} ${e.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net uninstall",...V.map((e)=>`cc-safety-net uninstall ${e.flag}`)]},ss={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 as={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 tt={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>",description:"Add a rulebook source and sync"},{usage:"remove <source>",description:"Remove a rulebook source and sync"},{usage:"update [source]",description:"Refresh rulebook lock/cache state"},{usage:"sync",description:"Sync configured rulebooks"},{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:"--check",description:"Check without changing lock/cache state"},{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"},{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","cc-safety-net rule add project-rules","cc-safety-net rule sync","cc-safety-net rule migrate --cleanup","cc-safety-net rule verify"]};var ls={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 cs={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 Yt=[ls,Ri,as,Ai,tt,os,ss,is,rs,Ei,cs];function Hu(e){return e.aliases??[]}function Zt(e){let t=e.toLowerCase();return Yt.find((n)=>n.name.toLowerCase()===t||Hu(n).some((r)=>r.toLowerCase()===t))}import{basename as Mu}from"node:path";function Xt(e=7,t=ue()){let n=Date.now()-e*24*60*60*1000,r=[],o=new Set,i=0,s,a,l,c;if(t)De(t);let d={count:0},p=t?ye(t,d):[];for(let u of p)for(let m of xe(u,d)){if(m.decision==="allow")continue;let f=new Date(m.ts).getTime();if(f>=n){if(i++,o.add(m.sessionId??Mu(u,".jsonl")),a===void 0||f<=a)s=m.ts,a=f;if(c===void 0||f>c)l=m.ts,c=f;ju(r,m,f)}}let g=r.map((u)=>({timestamp:u.ts,command:u.command,reason:u.reason,relativeTime:Un(new Date(u.ts))}));return{totalBlocked:i,sessionCount:o.size,recentEntries:g,oldestEntry:s,newestEntry:l,unreadable:d.count}}function ju(e,t,n){let r=e.findIndex((o)=>n>new Date(o.ts).getTime());if(r===-1){if(e.length<3)e.push(t);return}if(e.splice(r,0,t),e.length>3)e.pop()}import{dirname as Uu}from"node:path";function ds(e,t,n,r,o){let i;try{if(w(r)===null)return{path:e,exists:!1,valid:!1,ruleCount:0};i=le(r),i.errors.push(...ce(e,t,{userConfigDir:n},o))}catch(s){if(!(s instanceof N))throw s;i={errors:[s.message],ruleNames:new Set}}return{path:e,exists:!0,valid:i.errors.length===0,ruleCount:i.ruleNames.size,...i.errors.length>0?{errors:i.errors}:{}}}function Gu(e,t){return{source:t,name:e.name,command:e.command,subcommand:e.subcommand,blockArgs:[...e.block_args],reason:e.reason}}function us(e,t){let n=t?.userConfigPath??Q(),r=t?.projectConfigPath??X(e),o=Uu(n),i=Le({cwd:e,userConfigPath:n,projectConfigPath:r,userConfigDir:o}),s=ee({cwd:e,userConfigPath:n,projectConfigPath:r,userConfigDir:o}),a=new Map(i.rulebooks.flatMap((l)=>l.rules.map((c)=>[c,l.source])));return{userConfig:ds(n,Je({userConfigPath:n}),o,s.userConfigTarget,s.userScope),projectConfig:ds(r,Ye(r),o,s.projectConfigTarget,s.projectScope),effectiveRules:i.rules.map((l)=>Gu(l,a.get(l.name)??"project")),shadowedRules:[]}}var Bu=[{flag:S.level,description:"Safety level preset: standard, strict, or paranoid",defaultBehavior:"standard"},{flag:S.strict,description:"Legacy; equivalent to safety.overrides.fail_closed",defaultBehavior:"permissive"},{flag:S.paranoid,description:"Legacy; equivalent to safety.overrides.paranoid_rm and paranoid_interpreters",defaultBehavior:"off"},{flag:S.paranoidRm,description:"Legacy; equivalent to safety.overrides.paranoid_rm",defaultBehavior:"off"},{flag:S.paranoidInterpreters,description:"Legacy; equivalent to safety.overrides.paranoid_interpreters",defaultBehavior:"off"},{flag:S.worktree,description:"Allow local git discards in linked worktrees",defaultBehavior:"off"},{flag:S.debug,description:"Print diagnostic messages to stderr",defaultBehavior:"off"},{flag:S.auditScope,description:"Command decisions recorded: all, or blocked (privacy-minimizing, denials only)",defaultBehavior:"all"}];function ps(){return[...Bu.map((e)=>({name:e.flag.name,value:fr(e.flag),isSet:mr(e.flag),legacyName:e.flag.legacyName,legacyValue:e.flag.legacyName?process.env[e.flag.legacyName]:void 0,legacyIsSet:e.flag.legacyName?process.env[e.flag.legacyName]!==void 0:void 0,description:e.description,defaultBehavior:e.defaultBehavior})),{name:"CC_SAFETY_NET_HOME",value:process.env.CC_SAFETY_NET_HOME,isSet:process.env.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(e){return e.map((t)=>{if(t==="ownership")return"is not owned by the current user";if(t==="permissions")return"has unsafe permissions";if(t==="symlink")return"is a symbolic link";return"is not a directory"}).join(" and ")}var zu=[{derive:(e)=>e.hooks.length>0&&e.hooks.every((t)=>!t.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:(e)=>e.hooks.filter((t)=>t.inspectionStatus==="failed").map((t)=>{let n=R(t.platform);return{checkId:"integration.inspection-failed",severity:"error",title:`${n} inspection failed`,detail:`Doctor could not verify the ${n} integration configuration.`,fixHint:`Correct the reported ${n} configuration error, then run \`cc-safety-net doctor\` again.`,integration:t.platform}})},{derive:(e)=>e.userConfig.exists&&!e.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:e.userConfig.path}]:[]},{derive:(e)=>e.projectConfig.exists&&!e.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:e.projectConfig.path}]:[]},{derive:(e)=>e.configState.state==="degraded"?[{checkId:"config.runtime-degraded",severity:"warning",title:"Runtime is enforcing a fallback configuration",detail:`The rejected candidate configuration is not active: ${e.configState.reason}`,fixHint:"Correct the named source, run `cc-safety-net rule sync` for a rule source, then rerun doctor."}]:[]},{derive:(e)=>{let t=e.environment.find((n)=>n.name==="CC_SAFETY_NET_AUDIT_SCOPE");return pr(t?.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((e)=>({derive:(t)=>t.posture.directories.filter((n)=>n.kind===e&&n.status==="unsafe").map((n)=>({checkId:`posture.${e}-directory-unsafe`,severity:"error",title:`${e[0]?.toUpperCase()}${e.slice(1)} directory is unsafe`,detail:`The ${e} directory ${Vu(n.issues)}.`,fixHint:"Ensure this is a real directory owned by the current user with no group or other write access, then rerun doctor.",...n.path?{path:n.path}:{}}))})),{derive:(e)=>{let t=[...e.effectiveSafety.weakenedRuleOverrides].sort();return t.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: ${t.join(", ")}.`,fixHint:`Remove these \`off\` overrides or set them to \`on\`: ${t.join(", ")}.`}]:[]}}];function ms(e){return zu.flatMap((t,n)=>t.derive(e).map((r,o)=>({finding:r,catalogOrder:n,occurrence:o}))).sort((t,n)=>fs[t.finding.severity]-fs[n.finding.severity]||t.catalogOrder-n.catalogOrder||t.occurrence-n.occurrence).map((t)=>t.finding)}function ne(){return Boolean(process.stdout.isTTY&&!process.env.NO_COLOR)}var Ku=(e)=>ne()?`\x1B[32m${e}\x1B[0m`:e,Wu=(e)=>ne()?`\x1B[33m${e}\x1B[0m`:e,Ju=(e)=>ne()?`\x1B[34m${e}\x1B[0m`:e,Yu=(e)=>ne()?`\x1B[35m${e}\x1B[0m`:e,Zu=(e)=>ne()?`\x1B[36m${e}\x1B[0m`:e,Xu=(e)=>ne()?`\x1B[31m${e}\x1B[0m`:e,Qu=(e)=>ne()?`\x1B[2m${e}\x1B[0m`:e,ep=(e)=>ne()?`\x1B[1m${e}\x1B[0m`:e,h={green:Ku,yellow:Wu,blue:Ju,magenta:Yu,cyan:Zu,red:Xu,dim:Qu,bold:ep},tp="\x1B[0m",np=[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 rp(e){let t=e;return()=>(t=(t*1664525+1013904223)%4294967296,t/4294967296)}function op(e){let t=[...np],n=rp(e);for(let r=t.length-1;r>0;r--){let o=Math.floor(n()*(r+1)),i=t[r];t[r]=t[o],t[o]=i}return t}function ip(e,t=0){if(!ne())return"";let n=op(t);return`\x1B[38;5;${n[e%n.length]}m`}function gs(e,t,n=0){if(!ne())return`"${e}"`;return`${ip(t,n)}"${e}"${tp}`}var sp=new RegExp("\x1B\\[[0-9;]*m","g"),kr=(e)=>e.replace(sp,"").length;function Te(e){let t=(e.headers??e.rows[0]??[]).map((s,a)=>{let l=Math.max(...e.rows.map((c)=>kr(c[a]??"")));return Math.max(kr(s),l)}),n=(s,a)=>s+" ".repeat(Math.max(0,a-kr(s))),r=(s,a)=>a[0]+t.map((l)=>s.repeat(l+2)).join(a[1])+a[2],o=(s)=>`│ ${s.map((a,l)=>n(a,t[l]??0)).join(" │ ")} │`,i=e.headers?[` ${o(e.headers)}`,` ${r("─",["├","┼","┤"])}`]:[];return[` ${r("─",["┌","┬","┐"])}`,...i,...e.rows.map((s)=>` ${o(s)}`),` ${r("─",["└","┴","┘"])}`].join(`
6
- `)}function hs(e){let t=[];t.push("Hook Integration"),t.push(ap(e));let n=[],r=[];for(let o of e){let i=R(o.platform);if(o.errors&&o.errors.length>0)for(let s of o.errors)if(o.configured)n.push({platform:i,message:s});else r.push({platform:i,message:s})}for(let o of n)t.push(` Warning (${o.platform}): ${o.message}`);for(let o of r)t.push(h.red(` Error (${o.platform}): ${o.message}`));return t.join(`
7
- `)}function ap(e){let t=["Platform","Discovery","Configuration","Inspection"],n=e.map((r)=>{let o=R(r.platform);if(r.inspectionStatus==="not-inspected"){let l=h.dim("Not inspected");return[o,l,l,l]}let i=r.detected?h.green("Detected"):r.inspectionStatus==="failed"?h.red("Unknown"):h.dim("Not detected"),s=r.configured?h.green("Configured"):r.detected?h.yellow("Not configured"):r.inspectionStatus==="failed"?h.red("Unknown"):h.dim("Not applicable"),a=r.inspectionStatus==="verified"?h.green("Verified"):r.inspectionStatus==="failed"?h.red("Failed"):h.dim("Not applicable");return[o,i,s,a]});return Te({headers:t,rows:n})}function ys(e){let n=["Guard Engine Verification",` Synthetic self-test: ${e.failed>0?h.red(`${e.passed}/${e.total} FAIL`):h.green(`${e.passed}/${e.total} passed`)}`],r=e.results.filter((o)=>!o.passed);if(r.length>0){n.push(""),n.push(h.red(" Failures:"));for(let o of r)n.push(h.red(` • ${o.description}`)),n.push(h.red(` expected ${o.expected}, got ${o.actual}`))}return n.join(`
8
- `)}function lp(e){if(e.length===0)return" (no custom rules)";let t=["Source","Name","Command","Block Args"],n=e.map((r)=>[r.source,r.name,r.subcommand?`${r.command} ${r.subcommand}`:r.command,r.blockArgs.join(", ")]);return Te({headers:t,rows:n})}function Ls(e){let t=[];if(t.push("Configuration"),t.push(cp(e.userConfig,e.projectConfig)),t.push(""),e.effectiveRules.length>0)t.push(` Effective rules (${e.effectiveRules.length} total):`),t.push(lp(e.effectiveRules));else t.push(" Effective rules: (none - using built-in rules only)");for(let n of e.shadowedRules)t.push(""),t.push(` Note: Project rule "${n.name}" shadows user rule with same name`);return t.join(`
9
- `)}function cp(e,t){let n=["Scope","Status"],r=(i)=>{if(!i.exists)return h.dim("N/A");if(!i.valid)return h.red(`Invalid (${i.errors?.[0]??"unknown error"})`);return h.green("Configured")},o=[["User",r(e)],["Project",r(t)]];return Te({headers:n,rows:o})}function vs(e){let t=[];return t.push("Environment"),t.push(dp(e)),t.join(`
10
- `)}function bs(e){let t=["Effective Safety",` Selected preset: ${e.effectiveSafety.selectedPreset}`,` Effective: ${e.effectiveSafety.level}`],n=[["fail_closed","fail_closed"],["paranoid_rm","paranoid_rm"],["paranoid_interpreters","paranoid_interpreters"]];for(let[r,o]of n){let i=e.effectiveSafety.capabilities[r],s=i.enabled?h.green("ON"):h.dim("OFF"),a=i.sources.length>0?` (${i.sources.join(", ")})`:"";t.push(` ${o}: ${s} via ${i.source}${a}`)}t.push(` Stored rule customizations: ${e.effectiveSafety.ruleCounts.stored}`),t.push(` Effective rule customizations: ${e.effectiveSafety.ruleCounts.effective}`);for(let[r,o]of Object.entries(e.effectiveSafety.ruleOverrides))t.push(` ${r}: ${o}`);return t.join(`
11
- `)}function ws(e){let t=["Findings"];if(e.length===0)return t.push(" No findings from inspected doctor facts."),t.join(`
12
- `);for(let n of e){let r=`[${n.severity.toUpperCase()}] ${n.checkId}: ${I(n.title)}`,o=n.severity==="error"?h.red:n.severity==="warning"?h.yellow:h.blue;if(t.push(` ${o(r)}`),t.push(` ${I(n.detail)}`),n.path)t.push(` Path: ${I(n.path)}`);if(n.fixHint)t.push(` Fix: ${I(n.fixHint)}`)}return t.join(`
13
- `)}function dp(e){let t=["Variable","Status","Legacy"],n=e.map((r)=>{let o=r.isSet?h.green("✓"):h.dim("✗"),i=r.legacyName&&r.legacyIsSet?`${r.legacyName} ${h.green("✓")}`:r.legacyName??"";return[r.name,o,i]});return Te({headers:t,rows:n})}function xs(e){let t=[];if(e.totalBlocked===0)t.push("Recent Activity"),t.push(" No blocked commands in the last 7 days"),t.push(" Tip: This is normal for new installations");else t.push(`Recent Activity · last 7 days (${e.totalBlocked} blocked / ${e.sessionCount} sessions)`),t.push(up(e.recentEntries));if(e.unreadable>0)t.push(` Warning: ${e.unreadable} audit log ${e.unreadable===1?"source":"sources"} could not be read; this summary is incomplete`);return t.join(`
14
- `)}function up(e){let t=["Time","Command"],n=e.map((r)=>{let o=I(r.command.replace(/\r\n|\r|\n/g," ↵ ").replace(/\t/g," ")),i=o.length>40?`${o.slice(0,37)}...`:o;return[r.relativeTime,i]});return Te({headers:t,rows:n})}function ks(e){let t=[];if(t.push("Update Check"),e.latestVersion===null&&!e.error)return t.push(Qt([["Status",h.dim("Skipped")],["Installed",e.currentVersion]])),t.join(`
15
- `);if(e.error)return t.push(Qt([["Status",`${h.yellow("⚠")} Error`],["Installed",e.currentVersion],["Error",h.dim(e.error)]])),t.join(`
16
- `);if(e.updateAvailable)return t.push(Qt([["Status",`${h.yellow("⚠")} Update Available`],["Current",e.currentVersion],["Latest",h.green(e.latestVersion??"")]])),t.push(""),t.push(" Run: bunx cc-safety-net@latest doctor"),t.push(" Or: npx cc-safety-net@latest doctor"),t.join(`
17
- `);return t.push(Qt([["Status",`${h.green("✓")} Up to date`],["Version",e.currentVersion]])),t.join(`
18
- `)}function Qt(e){return Te({rows:e})}function Cs(e){let t=[];return t.push("System Info"),t.push(pp(e)),t.join(`
19
- `)}function pp(e){let t=["Component","Version"],n=(i)=>{if(i===null)return h.dim("not found");return i},o=[{label:"cc-safety-net",value:e.version},...Jt.map((i)=>({label:R(i),value:e.versions[i]??null})),{label:"Node.js",value:e.nodeVersion},{label:"npm",value:e.npmVersion},{label:"Bun",value:e.bunVersion},{label:"Platform",value:e.platform}].map((i)=>[i.label,n(i.value)]);return Te({headers:t,rows:o})}function Ss(e){if(e.findings.length===0)return h.green(`
2
+ import{b as Uo,c as Go,d as G,e as Bo,f as Xn,g as tt,h as Ae,i as gr,j as pe,k as Fi,l as xr,m as Jt,n as Hi,o as Mi,p as Yt}from"../chunks/index-t98xeq4f.js";import{$ as V,$a as ad,A as De,Aa as br,B as Je,Ba as wr,C as Gc,Ca as ki,D as ii,Da as xi,E as si,Ea as Jo,F as ai,Fa as Qe,G as yt,Ga as or,H as tr,Ha as ir,I as ur,Ia as di,J as li,Ja as Ke,Ka as nd,L as ci,La as Zo,M as Q,Ma as Xo,Na as kr,O as ee,Oa as Qo,P as Ze,Pa as ei,Q as Xe,Qa as Z,R as Lt,Ra as sr,S as _c,Sa as fr,T as te,Ta as mr,U as Y,Ua as X,V as pr,Va as rd,W as nr,Wa as kt,X as Wt,Xa as od,Y as rr,Ya as No,Za as id,_ as me,_a as sd,aa as Zi,ab as Tn,bb as ld,ca as Ee,cb as cd,da as Zt,db as Ci,ea as St,eb as Si,fa as vt,fb as Di,ga as Pe,gb as Ri,ha as hr,hb as Fc,ia as fe,ib as ui,ja as ji,jb as pi,ka as Cr,kb as ar,la as Bi,lb as fi,ma as qi,mb as mi,na as yr,nb as ve,oa as Li,ob as Re,pa as Ko,pb as de,qa as vi,qb as gi,ra as bi,rb as B,s as Ct,sa as wi,sb as xt,t as yi,ta as Lr,tb as bt,u as H,ua as Wo,ub as Gi,v as k,va as S,w as gt,wa as vr,x as w,xa as Ui,y as Se,ya as ue,z as oi,za as wt}from"../chunks/index-pb6n3mp5.js";var gd=["-h","--help"];function _(e,t){let n=Object.entries(e.booleans??{}),r=Object.entries(e.values??{}),o=Object.fromEntries(n.map(([d])=>[d,!1])),i={},s=[],a=[],l=!1,c=-1;for(let[d,p]of t.entries()){if(d<=c)continue;if(p==="--"){s.push(...t.slice(d+1));break}if(gd.includes(p)){l=!0;continue}let g=n.find(([,m])=>m.includes(p));if(g){o[g[0]]=!0;continue}let u=r.find(([,m])=>m.includes(p));if(u){let m=t[d+1];if(m===void 0||m.startsWith("-")){a.push(`${p} requires a value`);continue}i[u[0]]=m,c=d+1;continue}if(p.startsWith("-")){a.push(`Unknown option for ${e.label}: ${p}`);continue}if(e.positionals==="tail"){s.push(...t.slice(d));break}s.push(p)}if(e.positionals!=="list"&&e.positionals!=="tail")a.push(...s.map((d)=>`Unexpected argument for ${e.label}: ${d}`));return{flags:o,values:i,positionals:s,help:l,errors:a}}function le(e){for(let t of e)console.error(t);return e.length>0}import{readdirSync as tu,statSync as Ei,unlinkSync as nu}from"node:fs";import{basename as Pi,dirname as ru,join as ou,resolve as iu}from"node:path";function O(e){return Array.from(e,(t)=>{let n=t.charCodeAt(0);if(n<=31||n>=127&&n<=159)return`\\x${n.toString(16).padStart(2,"0")}`;return t}).join("")}var Wn=(e)=>{let t=Date.now()-new Date(e).getTime();if(!Number.isFinite(t))return"";let n=Math.floor(t/60000),r=Math.floor(n/60),o=Math.floor(r/24);if(o>0)return`${o}d ago`;if(r>0)return`${r}h ago`;if(n>0)return`${n}m ago`;return"just now"},qe=(e)=>{let t=(e??"").trim().split(/\s+/).filter((o)=>o&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(o)),n=t[0]?.split("/").pop();if(!n)return null;let r=t[1];return r&&/^[a-z][a-z0-9-]*$/.test(r)?`${n} ${r}`:n};import{existsSync as hd,readdirSync as yd,readFileSync as Ld}from"node:fs";import{join as vd}from"node:path";function Le(e,t){try{return yd(e,{withFileTypes:!0,encoding:"utf8"}).flatMap((n)=>{let r=vd(e,n.name);if(n.isDirectory())return Le(r,t);if(n.name.endsWith(".jsonl"))return[r];return[]})}catch{if(t&&hd(e))t.count++;return[]}}function Jn(e){let t=(o)=>`${o.sessionId}
3
+ ${qe(o.segment||o.command)}`,n=e.filter((o)=>o.decision!=="allow"),r=n.filter((o)=>o.sessionId).reduce((o,i)=>o.set(t(i),(o.get(t(i))??0)+1),new Map);return new Set(n.filter((o)=>o.failureStage||(r.get(t(o))??0)>=2))}var bd=["segment","reason","sessionId","decision","agent","ruleId","failureStage"];function wd(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e;if(typeof t.ts!=="string"||typeof t.command!=="string")return!1;return bd.every((n)=>t[n]===void 0||typeof t[n]==="string")}function Ce(e,t){try{return Ld(e,"utf-8").split(`
4
+ `).filter(Boolean).flatMap((n)=>{try{let r=JSON.parse(n);if(!wd(r)){if(t)t.count++;return[]}return[r]}catch{if(t)t.count++;return[]}})}catch{if(t)t.count++;return[]}}import{resolve as Kd}from"node:path";var kd=["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 qo(e){let t=0,n={allocateSegment(){return t++},getNextSegmentIndex(){return t},recordGlobal(r){e.record({kind:"step",scope:"global",step:r})},recordSegment(r,o=n.currentSegmentIndex){if(o===void 0)return;e.record({kind:"step",scope:"segment",segmentIndex:o,step:r})}};return n}function Vo(e={}){let t=[],n=e.maxEvents??512,r={maxTextLength:e.maxTextLength??2048,maxListLength:e.maxListLength??128,maxObjectProperties:e.maxObjectProperties??e.maxListLength??128,maxDepth:e.maxDepth??16},o=0,i,s=new Set;return{record(a){if(i)return;try{if(!a||t.length>=n){o++;return}t.push(Zn(xd(a,r,s)))}catch{o++}},finish(a){if(i)return i;try{i=Zn({events:Object.freeze(t),droppedEvents:o,terminal:Cd(a,r,s)})}catch{o++,i=Object.freeze({events:Object.freeze(t),droppedEvents:o,terminal:Object.freeze({result:"blocked",reason:"trace unavailable".slice(0,r.maxTextLength),segment:"trace unavailable".slice(0,r.maxTextLength)})})}return i}}}function xd(e,t,n){if(e.kind!=="step")throw TypeError("invalid trace event");let{scope:r,step:o}=e;zt(o,n,t);let i=Ve(o,t,n);if(r==="global")return{kind:"step",scope:"global",step:i};if(r!=="segment")throw TypeError("invalid trace event scope");return{kind:"step",scope:"segment",segmentIndex:e.segmentIndex,step:i}}function Cd(e,t,n){let r=e.result;if(r==="allowed")return Object.freeze({result:"allowed"});if(r!=="blocked")throw TypeError("invalid trace terminal");let o=e.ruleId;return Object.freeze({result:"blocked",reason:Ve(e.reason,t,n),segment:Ve(e.segment,t,n),...o?{ruleId:Ve(o,t,n)}:{}})}function zt(e,t,n,r=0,o=new WeakSet){if(typeof e==="string"){let a=e.slice(0,n.maxTextLength);if(!Xn(a))return;for(let l of Bo(a))for(let c of l.match(/[^\s"'()$]+/g)??[])t.add(zo(c));return}if(!e||typeof e!=="object"||r>=n.maxDepth||o.has(e))return;if(o.add(e),Array.isArray(e)){let a=Math.min(e.length,n.maxListLength);for(let l=0;l<a;l++)zt(e[l],t,n,r+1,o);return}let i=0,s=new Set;for(let a in e){if(!Object.hasOwn(e,a))continue;if(i>=n.maxObjectProperties)break;i++,zt(a,t,n);let l=Yn(a,n,t);if(s.has(l))continue;s.add(l),zt(e[a],t,n,r+1,o)}}function Ve(e,t,n,r=0,o=new WeakSet){if(typeof e==="string")return Yn(e,t,n);if(!e||typeof e!=="object")return e;if(r>=t.maxDepth)return;if(o.has(e))return;if(o.add(e),Array.isArray(e)){let a=[],l=Math.min(e.length,t.maxListLength);for(let c=0;c<l;c++)a.push(Ve(e[c],t,n,r+1,o));return a}let i={},s=0;for(let a in e){if(!Object.hasOwn(e,a))continue;if(s>=t.maxObjectProperties)break;s++;let l=Yn(a,t,n);if(Object.hasOwn(i,l))continue;Object.defineProperty(i,l,{value:Ve(e[a],t,n,r+1,o),enumerable:!0,configurable:!0,writable:!0})}return i}function Yn(e,t,n){let r=e.slice(0,t.maxTextLength),o=Xn(r)?Go(r):r,i=n.size>0?Dd(o,n):o;return(Sd(i)?Uo(i):i).slice(0,t.maxTextLength)}function Sd(e){return e.includes("PRIVATE KEY")||e.includes("://")||e.includes("eyJ")||e.includes(":")&&/(?:authorization|cookie|x-api-key|api-key|(?:^|\s)(?:-u|--user)(?:\s|=))/i.test(e)||e.length>=14&&kd.some((t)=>e.includes(t))||e.length>=49&&/\b[a-f0-9]{32}\.[A-Za-z0-9]{16}\b/.test(e)}function Dd(e,t){return e.replace(/[^\s"'()$]+/g,(n)=>t.has(zo(n))?"<redacted>":n)}function zo(e){let t=2166136261,n=2166136261;for(let r=0;r<e.length;r++)t=Math.imul(t^e.charCodeAt(r),16777619),n=Math.imul(n^e.charCodeAt(e.length-r-1),16777619);return`${t>>>0}:${n>>>0}:${e.length}`}function Zn(e){if(e&&typeof e==="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))Zn(t);Object.freeze(e)}return e}function Yo(e,t,n){let r=n??Ko(),o=r.getCommandProgram(e,t.shell??"auto"),i=Vo(),s=qo(i),a=o.dialect==="powershell"?r.getCommandProgram(e,"posix"):o,l=Wo(a);s.recordGlobal({type:"parse",input:e,segments:l.map((p)=>[...p])});let c=Jo(e,{...t,analyzePartialProgram:!0,trace:s},o,r),d=s.getNextSegmentIndex();if(c&&d>0&&d<l.length)s.recordSegment({type:"segment-skipped",index:d,reason:"prior-segment-blocked"},d);return Object.freeze({decision:c,trace:i.finish(c?{result:"blocked",reason:c.reason,segment:c.evidence.find((p)=>p.kind==="command")?.segment??e,...c.ruleId?{ruleId:c.ruleId}:{}}:{result:"allowed"}),program:o})}import{resolve as Rd}from"node:path";function Qn(e){let t=Zo().safeParse(e);return{errors:t.success?[]:Qo(t.error.issues),ruleNames:new Set(Xo(e).map((n)=>n.toLowerCase()))}}function er(e){let t=ti(e);if(!t.ok)return t.result;return Qn(t.parsed)}function ti(e){let t=[],n=new Set;try{let r=typeof e==="string"?gt(e):e,o=w(r);if(o===null)return t.push(`File not found: ${r.path}`),{ok:!1,result:{errors:t,ruleNames:n}};if(!o.trim())return t.push("Config file is empty"),{ok:!1,result:{errors:t,ruleNames:n}};return{ok:!0,parsed:JSON.parse(o)}}catch(r){if(r instanceof H)return t.push(r.message),{ok:!1,result:{errors:t,ruleNames:n}};let o=r instanceof Error?r.message:String(r);return t.push(r instanceof SyntaxError?"Invalid JSON":o),{ok:!1,result:{errors:t,ruleNames:n}}}}function ni(e){return Rd(e??process.cwd(),".safety-net.json")}function ce(e){let t=ti(e);if(!t.ok)return t.result;let n=ei(t.parsed);return{errors:n.errors,ruleNames:n.sources}}import{isAbsolute as Ad,join as ht,relative as Ed,resolve as ri,sep as Pd}from"node:path";async function Ye(e={}){let t=cr(e);return Td(t,await Kt(t,Ke()))}function Td(e,t){if(!t.ok)return t;let n=Y(e),r=[...new Set(de(n.configPath,n.lockPath,e,n.filesystemScope))];if(r.length===0)return t;return{ok:!1,errors:r,warnings:t.warnings,entries:t.entries}}async function Kt(e,t,n,r={}){let o=null,i=!1;try{let s=Y(e),a=sr(s.configTarget);if(!a.ok)return a.result;let l=a.config;if(e.check)return Fd(l,s,e);o={target:s.lockTarget,content:w(s.lockTarget)};let c=ar(s.lockTarget);if(c.errors.some((L)=>L.startsWith("Unable to access ")))return{ok:!1,errors:c.errors,warnings:[],entries:[]};if(e.only&&c.errors.length>0)return{ok:!1,errors:c.errors,warnings:[],entries:[]};let d=c.errors.length>0?null:c.lock,p=e.only?ui(l,d,e.only):{ok:!0,specs:l.rules};if(!p.ok)return p.result;if(e.only&&!d&&p.specs.length<l.rules.length)return{ok:!1,errors:[`No lockfile available for partial update; run ${ci}`],warnings:[],entries:[]};let g=(await _d(p.specs,(L)=>fi(L,s.configDir,e,d,s.filesystemScope,t),t)).map((L)=>Hd(L,d,n));for(let L of g)Ud(L.content,L.entry,s.configDir,e,s.filesystemScope);let u=e.only?Md(l,d,g):g.map((L)=>L.entry);i=!0,X(s.lockTarget,{version:1,rulebooks:u},void 0,r._testAfterPolicyRename);let m=new Map(g.map((L)=>[L.entry.spec,L.rulebook.rules.length])),f=Gd(u,s.configDir,e,s.filesystemScope,r);return{ok:!0,errors:[],warnings:f,entries:u.map((L)=>jd(L,m))}}catch(s){if(i&&o)try{ze(o.target,o.content)}catch(a){return We(a)}return We(s)}}async function lr(e,t={}){return Id(e,cr(t),Ke())}async function Id(e,t,n,r={}){let o=null,i=!1;try{let s=Y(t),a=w(s.configTarget);o={target:s.configTarget,content:a};let l=sr(s.configTarget);if(!l.ok)return l.result;let c=l.config,d=li(e)?await mi(e,n):[{spec:e}],p=d.map((m)=>m.spec),g=[...new Set([...c.rules,...p])];if(g.length>or)return Od();if(g.length!==c.rules.length)i=!0,X(s.configTarget,{version:1,rules:g,overrides:c.overrides??{},transparent_wrappers:c.transparent_wrappers??[]},void 0,r._testAfterPolicyRename);let u=await Kt(t,n,new Map(d.filter((m)=>!!m.display_ref).map((m)=>[m.spec,m.display_ref])),r);if(!u.ok)ze(s.configTarget,a);return u}catch(s){if(i&&o)try{ze(o.target,o.content)}catch(a){return We(a)}return We(s)}}async function _d(e,t,n=Ke()){if(e.length>or)throw Error(ir);let r=Array(e.length),o=0,i,s=Array.from({length:Math.min(e.length,di.concurrency)},async()=>{while(!i){let a=o;if(a>=e.length)return;o++;try{r[a]=await t(e[a],a,n.controller.signal)}catch(l){if(!i)i={value:l},o=e.length,n.controller.abort(l);return}}});if(await Promise.all(s),i)throw i.value;return r}function Od(){return{ok:!1,errors:[ir],warnings:[],entries:[]}}function cr(e){return{cwd:e.cwd,cacheConfigDir:e.cacheConfigDir,userConfigDir:e.userConfigDir,userConfigPath:e.userConfigPath,projectConfigPath:e.projectConfigPath,global:e.global,check:e.check,only:e.only,refresh:e.refresh}}function $d(e){return{...cr(e),deleteSource:e.deleteSource}}async function dr(e,t={}){try{return await Nd(e,$d(t),{})}catch(n){return We(n)}}async function Nd(e,t,n){let r=Y(t),o=Z(r.configTarget);if(o.errors.length>0)return{ok:!1,errors:o.errors,warnings:[],entries:[]};if(!o.config)return{ok:!1,errors:[`No config found at ${r.configPath}`],warnings:[],entries:[]};let i=ar(r.lockTarget);if(i.errors.length>0)return{ok:!1,errors:i.errors,warnings:[],entries:[]};let s=pi(o.config.rules,i.lock,e);if(!s.ok)return s.result;let a=t.deleteSource?Bd(r.configDir,s.specs,i.lock,r.filesystemScope):{ok:!0,dirs:[]};if(!a.ok)return a.result;let l=w(r.configTarget);if(l===null)return We(Error("Rules config is unavailable."));try{X(r.configTarget,{version:1,rules:o.config.rules.filter((p)=>!s.specs.includes(p)),overrides:o.config.overrides??{},transparent_wrappers:o.config.transparent_wrappers??[]},void 0,n._testAfterPolicyRename)}catch(p){throw ze(r.configTarget,l),p}let c=await Kt(t,Ke(),void 0,n);if(!c.ok)return ze(r.configTarget,l),c;let d=qd(r.configDir,a.dirs,n,r.filesystemScope);if(!d.ok){ze(r.configTarget,l);let p=await Kt(t,Ke(),void 0,n);if(!p.ok)return{ok:!1,errors:[...d.result.errors,...p.errors],warnings:p.warnings,entries:p.entries};return d.result}return c}async function Fd(e,t,n){let r=gi(e,t.lockPath,t.configDir,n,n.global?"user":"project",t.filesystemScope);return{ok:r.errors.length===0&&r.warnings.length===0,errors:[...r.errors,...r.warnings],warnings:[],entries:r.entries}}function Hd(e,t,n){let r=t?.rulebooks.find((i)=>i.spec===e.entry.spec&&i.kind==="github"),o=n?.get(e.entry.spec)??(r?.kind==="github"?r.display_ref:void 0);if(!o||e.entry.kind!=="github")return e;return{...e,entry:{...e.entry,display_ref:o}}}function Md(e,t,n){let r=new Set(e.rules),o=new Set(t?.rulebooks.map((s)=>s.spec)??[]),i=new Map(n.map((s)=>[s.entry.spec,s.entry]));return[...(t?.rulebooks.filter((s)=>r.has(s.spec))??[]).map((s)=>i.get(s.spec)??s),...n.filter((s)=>!o.has(s.entry.spec)).map((s)=>s.entry)]}function jd(e,t){return{...e,ruleCount:t.get(e.spec)}}function Ud(e,t,n,r,o){let i=nr(t,rr(n,r));Se(k(o,i),e)}function Gd(e,t,n,r,o){let i=rr(t,n),s=Wt(i),a=k(r,s),l=De(a);if(!l)return[];let c=e.map((p)=>k(r,nr(p,i))),d=l.filter((p)=>p.kind==="directory").map((p)=>({directory:k(r,ht(s,p.name)),identity:k(r,ht(s,p.name,tr))})).filter((p)=>!c.some((g)=>oi(p.identity,g))).map((p)=>p.directory);for(let p of d)ai(p);return d.flatMap((p)=>{try{return Vd(p,o),[]}catch{return["Unable to prune rules policy cache safely."]}})}function Bd(e,t,n,r){let o=new Map(n?.rulebooks.map((c)=>[c.spec,c])??[]),i=t.flatMap((c)=>{let d=o.get(c);if(!d)return yt.test(c)?[]:["--delete-source can only delete local rulebook sources"];return d.kind==="local-directory"?[]:["--delete-source can only delete local rulebook sources"]}),s=t.map((c)=>{let d=o.get(c);return ht(e,d?.kind==="local-directory"?d.path:c)}),a=i.length>0?[]:s.flatMap((c)=>hi(e,c,r)),l=[...i,...a];return l.length>0?{ok:!1,result:{ok:!1,errors:l,warnings:[],entries:[]}}:{ok:!0,dirs:s}}function hi(e,t,n){let r=ri(e),o=ri(t),i=Ed(r,o);if(i===""||i===".."||i.startsWith(`..${Pd}`)||Ad(i))return[`Refusing to delete local rulebook source outside ${e}: ${t}`];let s=k(n,o),a=De(s);if(!a)return[`Local rulebook source directory not found: ${t}`];let l=a.find((c)=>c.name==="rulebook.json");if(!l)return[`Local rulebook source directory is missing rulebook.json: ${t}`];if(l.kind!=="file")throw new H(n.label);if(w(k(n,ht(o,"rulebook.json"))),a.length>1)return[`Local rulebook source directory contains extra files: ${t}. delete manually if you really want to remove the directory.`];return[]}function qd(e,t,n,r){let o=t.flatMap((i)=>{try{if(!De(k(r,i)))return[];let s=hi(e,i,r);if(s.length>0)return s;return zd(i,n,r),[]}catch(s){return[`Failed to delete local rulebook source ${i}: ${s instanceof Error?s.message:String(s)}`]}});return o.length>0?{ok:!1,result:{ok:!1,errors:o,warnings:[],entries:[]}}:{ok:!0}}function Vd(e,t){if(t._testPruneRulebookCacheDir){t._testPruneRulebookCacheDir(e.path);return}ii(e)}function zd(e,t,n){if(t._testDeleteLocalSourceDir){t._testDeleteLocalSourceDir(e);return}Je(k(n,ht(e,tr))),si(k(n,e))}function ze(e,t){if(t===null){Je(e);return}Se(e,t)}function We(e){return{ok:!1,errors:[e instanceof Error?e.message:String(e)],warnings:[],entries:[]}}function et(e,t){let n=Jd(t),r=ki(n),o={effectiveLevel:r.effectiveLevel,selectedPreset:n.policySnapshot.policy.safety.level??"standard",effectiveCapabilities:r.effectiveCapabilities,destructiveCommandRuleOverrides:n.policySnapshot.policy.destructiveCommandRuleOverrides},{configSource:i,configValid:s}=Wd({cwd:t?.cwd,userConfigDir:t?.userConfigDir});if(!e||!e.trim())return{trace:{steps:[{type:"error",message:"No command provided"}],segments:[]},result:"allowed",configSource:i,configValid:s,...o};let a=Yd(e,n);if(a)return{trace:{steps:[],segments:[{index:0,steps:[{type:"rule-check",rule:a.rule,matched:!0,reason:a.reason}]}]},result:"blocked",reason:G(a.reason),segment:G(a.target),...a.ruleId?{ruleId:G(a.ruleId)}:{},configSource:i,configValid:s,...o};let l=Yo(e,n),c=l.decision,d=c?.ruleId??Zd(e,n),p=vt.find((u)=>u.id===d&&u.activationCapability),g=p?r.policy.effectiveDestructiveCommandRules[p.id]:void 0;return{trace:Qd(l.trace),result:c?"blocked":"allowed",reason:c?G(c.reason):void 0,segment:c?G(c.evidence.find((u)=>u.kind==="command")?.segment??e):void 0,ruleId:c?.ruleId?G(c.ruleId):void 0,customRule:Xd(eu(c?.ruleId,n.policySnapshot)),configSource:i,configValid:s,...o,...p&&g?{ruleActivation:{id:p.id,...g}}:{}}}function Wd(e){let t=Q(e?.cwd),n=e?.userConfigPath??ee(e),r=te({cwd:e?.cwd,userConfigDir:e?.userConfigDir,userConfigPath:e?.userConfigPath});try{if(w(r.projectConfigTarget)!==null){if(ce(r.projectConfigTarget).errors.length===0)return{configSource:t,configValid:!0};return{configSource:t,configValid:!1}}}catch(o){if(o instanceof H)return{configSource:t,configValid:!1};throw o}try{if(w(r.userConfigTarget)!==null){let o=ce(r.userConfigTarget);return{configSource:n,configValid:o.errors.length===0}}return{configSource:null,configValid:!0}}catch(o){if(o instanceof H)return{configSource:n,configValid:!1};throw o}}function Jd(e){let t=Kd(e?.cwd??process.cwd()),n=e?.policySnapshot??B({cwd:t,userConfigDir:e?.userConfigDir}),r=ue(n.policy);return{cwd:t,effectiveCwd:t,policySnapshot:n,environment:yi(),protectedGitMetadata:wi([t]),effectiveCapabilities:r.capabilities,strict:e?.strict??r.strict,paranoidRm:r.paranoidRm,paranoidInterpreters:r.paranoidInterpreters,worktreeMode:r.worktreeMode}}function Yd(e,t){let n=t.cwd??process.cwd(),r=Li(Qe("",{command:e},{kind:"command",shell:"posix"},{executionCwd:n,configCwd:n},e)),o=Si(r);if(o)return{reason:Ci,target:o.target,ruleId:"policy-protection",rule:"policy-protection:findPolicyConfigMutationTargetInSemanticFacts"};let i=bi(r,t.protectedGitMetadata);if(i)return{reason:vi,target:i.target,ruleId:"git-metadata-protection",rule:"git-metadata-protection:findGitMetadataMutationTargetInSemanticFacts"};let s=t.policySnapshot.policy,a=s.secretProtection.enabled===!1?null:Ri(r,s.secretProtection,{strict:t.strict});if(a)return{reason:Di,target:a.target,ruleId:a.ruleId,rule:"secret-protection:findSensitiveTargetInSemanticFacts"};return null}function Zd(e,t){let n=t.policySnapshot.policy,r=bt({...n,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:{...n.destructiveCommandRuleOverrides,...Object.fromEntries(vt.flatMap((o)=>o.activationCapability?[[o.id,"on"]]:[]))}},t.policySnapshot.state==="degraded"?{diagnostics:t.policySnapshot.diagnostics,reason:t.policySnapshot.reason}:void 0);return xi(e,{...t,policySnapshot:r,strict:!0,paranoidRm:!0,paranoidInterpreters:!0})?.ruleId}function Xd(e){if(!e)return;return{id:G(e.id),...e.rulebook?{rulebook:{name:G(e.rulebook.name),version:G(e.rulebook.version)}}:{},...e.source?{source:G(e.source)}:{},...e.override?{override:{type:"reason",reason:G(e.override.reason)}}:{}}}function Qd(e){let t=e.events.flatMap((r)=>r.kind==="step"&&r.scope==="global"?[r.step]:[]),n=new Map;for(let r of e.events){if(r.kind!=="step"||r.scope!=="segment")continue;let o=n.get(r.segmentIndex)??{index:r.segmentIndex,steps:[]};o.steps.push(r.step),n.set(r.segmentIndex,o)}return{steps:t,segments:[...n.values()]}}function eu(e,t){let n=e?.replace(/^custom\./,"");if(!n||!t.policy.rules.some((r)=>r.name===n))return;return t.ruleMetadata[n]??Object.freeze({id:n})}function su(e){let t=tt(),n=_({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"]}},e);if(le(n.errors))return null;if(n.values.id!==void 0&&!/^[a-f0-9]{16}$/.test(n.values.id))return console.error("--id must be 16 hexadecimal characters"),null;let r=n.values.limit===void 0?20:Ai(n.values.limit);if(r===null)return console.error("--limit must be a positive number"),null;let o=n.values.since===void 0?Math.min(30,t):Ai(n.values.since);if(o===null||o>t)return console.error(`--since must be a positive number of days no greater than ${t}`),null;let i={limit:r,limitExplicit:n.values.limit!==void 0,since:o,sinceExplicit:n.values.since!==void 0,all:n.flags.all,json:n.flags.json,suspect:n.flags.suspect,pruneLegacy:n.flags.pruneLegacy,dryRun:n.flags.dryRun,id:n.values.id,agent:n.values.agent,rule:n.values.rule,session:n.values.session,project:n.values.project===void 0?void 0:iu(n.values.project)};if(i.id&&(i.agent!==void 0||i.rule!==void 0||i.session!==void 0||i.project!==void 0||i.suspect||i.sinceExplicit||i.limitExplicit))return console.error("--id cannot be combined with --agent, --rule, --session, --project, --suspect, --since, or --limit"),null;if(i.pruneLegacy&&(i.id!==void 0||i.agent!==void 0||i.rule!==void 0||i.session!==void 0||i.project!==void 0||i.suspect||i.all||i.sinceExplicit||i.limitExplicit))return console.error("--prune-legacy cannot be combined with --id, --agent, --rule, --session, --project, --suspect, --all, --since, or --limit"),null;if(i.dryRun&&!i.pruneLegacy)return console.error("--dry-run requires --prune-legacy"),null;return i}async function Ti(e,t={}){let n=su(e);if(!n)return 1;let r=t.logsDir??pe();if(n.pruneLegacy)return au(r,n.json,n.dryRun);if(!r)return console.log(n.json?"[]":n.id?`No retained audit log entry found for id ${O(n.id)}.`:"No audit log entries found."),0;Ae(r);let o={count:0},i=Le(r,o).flatMap((d)=>Ce(d,o).map((p)=>({entry:p,file:d})));if(o.count>0)console.error(`warning: ${o.count} audit log ${o.count===1?"source":"sources"} could not be read; these results are incomplete`);if(n.id)return uu(i,n,t.timeZone);let s=Date.now()-n.since*24*60*60*1000,a=i.filter((d)=>pu(d,n,r,s)),l=n.suspect?Jn(a.map((d)=>d.entry)):null,c=(l?a.filter((d)=>l.has(d.entry)):a).sort((d,p)=>Date.parse(p.entry.ts)-Date.parse(d.entry.ts)).slice(0,n.limit);if(n.json)return console.log(JSON.stringify(c.map((d)=>d.entry),null,2)),0;if(c.length===0)return console.log("No audit log entries found."),0;for(let d of c)console.log(gu(d.entry,t.timeZone));return 0}function au(e,t,n){let r=e?cu(e).map((a)=>ou(e,a)):[];if(n)return lu(r,t);let o=[],i=0,s=0;for(let a of r){let l=Ei(a,{throwIfNoEntry:!1})?.size??0,c=du(a);if(c){o.push(`${Pi(a)}: ${c}`);continue}i++,s+=l}if(t)return console.log(JSON.stringify({removedFiles:i,removedBytes:s,failedFiles:o.length})),o.length===0?0:1;console.log(i===0&&o.length===0?"No legacy audit log files found.":`Removed ${i} legacy audit log ${i===1?"file":"files"} (${Ii(s)}).`);for(let a of o)console.error(`Could not remove ${O(a)}`);if(console.log("Nested v2 audit logs were not changed."),i>0)console.log("This deletion cannot be undone.");return o.length===0?0:1}function lu(e,t){let n=e.reduce((r,o)=>r+(Ei(o,{throwIfNoEntry:!1})?.size??0),0);if(t)return console.log(JSON.stringify({dryRun:!0,files:e.length,bytes:n})),0;if(console.log(e.length===0?"No legacy audit log files found.":`Would remove ${e.length} legacy audit log ${e.length===1?"file":"files"} (${Ii(n)}).`),console.log("Nested v2 audit logs are not included."),e.length>0)console.log("Run the same command without --dry-run to delete them.");return 0}function cu(e){try{return tu(e,{withFileTypes:!0}).filter((t)=>t.isFile()&&t.name.endsWith(".jsonl")).map((t)=>t.name)}catch{return[]}}function du(e){try{return nu(e),null}catch(t){return t instanceof Error?t.message:String(t)}}function Ii(e){let t=["B","KiB","MiB","GiB"],n=Math.min(Math.floor(Math.log2(Math.max(e,1))/10),t.length-1);return`${Math.round(e/1024**n*10)/10} ${t[n]}`}function uu(e,t,n){let r=e.filter((i)=>i.entry.id===t.id);if(r.length>1)return console.error(`Multiple audit log entries found for id ${O(t.id??"")}.`),1;if(t.json)return console.log(JSON.stringify(r.map((i)=>i.entry),null,2)),0;let o=r[0];if(!o)return console.log(`No retained audit log entry found for id ${O(t.id??"")}.`),0;return console.log(hu(o.entry,n)),0}function pu(e,t,n,r){if(!t.all&&e.entry.decision==="allow")return!1;if(Date.parse(e.entry.ts)<r)return!1;if(t.agent!==void 0&&e.entry.agent!==t.agent)return!1;if(t.rule!==void 0&&e.entry.ruleId!==t.rule)return!1;if(t.session!==void 0&&!fu(e,n,t.session))return!1;if(t.project!==void 0&&!mu(e.entry.cwd,t.project))return!1;return!0}function fu(e,t,n){if(e.entry.sessionId===n)return!0;return ru(e.file)===t&&Pi(e.file,".jsonl")===n}function mu(e,t){if(!e)return!1;return e===t||e.startsWith(`${t}/`)}function gu(e,t){let n=O(e.id??"-"),r=O(e.decision??"deny"),o=e.cwd?` [${O(e.cwd)}]`:"",i=e.segment||e.command,s=i===e.command?"":"↳ ",a=i.length>50?`${i.slice(0,50)}…`:i;return`${n.padEnd(16)} ${O(_i(e.ts,t))} ${r.padEnd(5)} ${O(e.agent??"-").padEnd(15)} ${O(e.ruleId??"-").padEnd(20)} ${s}${O(a)}${o}`}function hu(e,t){let n=(o)=>O(o===void 0||o===null||o===""?"-":o),r=e.shape?`${e.agent??"-"} (shape: ${e.shape})`:e.agent??"-";return[`id: ${n(e.id)}`,`ts: ${n(_i(e.ts,t))}`,`decision: ${n(e.decision)}`,`agent: ${n(r)}`,`level: ${n(e.level)}`,`tool: ${n(e.toolName)}`,`rule: ${n(e.ruleId)}`,`intent: ${n(e.intent)}`,`stage: ${n(e.failureStage)}`,`error: ${n(e.errorCode)}`,`session: ${n(e.sessionId)}`,`cwd: ${n(e.cwd)}`,`version: ${n(e.v)}`,`truncated: ${n(e.truncated===!0?"yes":void 0)}`,`reason: ${n(e.reason)}`,`command: ${n(e.command)}`,`segment: ${n(e.segment)}`].join(`
5
+ `)}function _i(e,t){let n=new Date(e);if(Number.isNaN(n.getTime()))return e;return new Intl.DateTimeFormat("sv-SE",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hourCycle:"h23",timeZone:t}).format(n)}function Ai(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}var Oi={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 $i={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 Ni={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"]};import{isAbsolute as Vi,join as Ru,relative as Au}from"node:path";var yu=8388608;function Lu(e,t){console.log(JSON.stringify(e(Hi(t))))}async function vu(e){let t;try{t=(await Sr(process.stdin)).trim()}catch{e({reason:"Failed to parse hook input JSON."});return}if(!t){e({reason:"Missing hook input JSON."});return}return Dr(t,e,"Failed to parse hook input JSON.")}async function Sr(e){let t=[],n=0;for await(let r of e){let o=typeof r==="string"?Buffer.from(r,"utf-8"):Buffer.from(r.buffer,r.byteOffset,r.byteLength);if(n+=o.byteLength,n>yu)throw bu(e),Error("hook input byte limit exceeded");t.push(o)}return Buffer.concat(t,n).toString("utf-8")}function bu(e){let t=e.destroy??e.cancel;if(!t)return;try{Promise.resolve(t.call(e)).catch(()=>{})}catch{}}function Dr(e,t,n){try{return JSON.parse(e)}catch{t({reason:n});return}}function N(e,t){let n=t.get(e);return n?{kind:"command",shell:n}:{kind:ji(e)}}function ne(e,t,n,r){let o=e===void 0?process.cwd():e,i=typeof o==="string"&&o.trim()!==""?V([o]):void 0;if(i)return{configCwd:i,executionCwd:i};return P(r,t,n,Cu(o)),null}function P(e,t,n,r){let o;try{o=Cr(t)}catch(i){if(!(i instanceof fe))throw i}e(Jt({command:o,segment:r,toolName:n}))}async function wu(e){let t=await vu(e.outputDeny);if(t===void 0)return;if(!t||typeof t!=="object"||Array.isArray(t)){P(e.outputDeny);return}if(!e.isSupported(t))return;let n=e.getAgent?.(t)??e.agent,r=e.agent===n?void 0:e.agent,o=Du(t),i=(u,m)=>{Fi(u,()=>e.getSessionId(t),{agent:n,shape:r,toolName:m,cwd:o}),e.outputDeny(u)},s=e.getToolName(t);if(typeof s!=="string"||s.trim()===""){P((u)=>i(u),Su(t));return}let a=s,l=(u)=>i(u,a),c;try{c=e.getToolInput(t,a,l)}catch(u){if(!(u instanceof fe))throw u;P(l,void 0,a);return}if(!c.ok)return;let d=e.getContext(t,c.input,a,l);if(!d)return;let p;try{p=Cr(c.input)}catch(u){if(!(u instanceof fe))throw u;P(l,void 0,a);return}let g=Qe(a,c.input,c.route,d,p??null);try{let u=Yt(g,{guard:{auditAllowed:Ui(),dependencies:e.guardDependencies},audit:{agent:n,shape:r,getSessionId:()=>e.getSessionId(t)}}),m=xr(u,{includeEvidence:!0,toolName:u.stage==="command-analysis"?void 0:a});if(m){e.outputDeny(m);return}e.outputAllow?.()}catch(u){if(!(u instanceof Gi))throw u;ku(u);let m=xr(u.evaluation,{includeEvidence:!0,toolName:u.evaluation.stage==="command-analysis"?void 0:a});if(m)e.outputDeny(m);return}}function ku(e){if(!wt(S.debug))return;console.error(`CC Safety Net debug: ${xu(e.stage)}: ${Mi(e.cause)}`)}function xu(e){if(e==="policy-protection")return"hook policy protection failed";if(e==="config-load")return"hook config loading failed";if(e==="secret-protection")return"hook secret protection failed";return"hook analysis failed"}function Cu(e){return typeof e==="string"?e:void 0}function Su(e){if(!e||typeof e!=="object"||Array.isArray(e))return;if(Object.hasOwn(e,"tool_input"))return e.tool_input;let t=e.toolCall;if(t&&typeof t==="object"&&!Array.isArray(t))return t.args;return}function Du(e){if(!e||typeof e!=="object"||Array.isArray(e))return null;let t=e.cwd;if(typeof t==="string")return t;let n=e.toolCall;if(!n||typeof n!=="object"||Array.isArray(n))return null;let r=n.args;if(!r||typeof r!=="object"||Array.isArray(r))return null;let o=r.Cwd;return typeof o==="string"?o:null}async function F(e){let t=(o)=>Lu(e.createDenyOutput,o),n=e.createAllowOutput;await wu({...e,outputDeny:t,outputAllow:n?()=>console.log(JSON.stringify(n())):void 0})}function Dt(e){return Ru(e,".gemini","config","hooks.json")}var Eu=new Map([["run_command","auto"]]),Pu=new Set(["absolutepath","directorypath","file_path","filepath","path","searchdirectory","searchpath","target_file","targetfile"]);function zi(e){return N(e,Eu)}async function Ki(){await F({agent:"antigravity-cli",createDenyOutput:(e)=>({decision:"deny",reason:e}),isSupported:()=>!0,getToolName:(e)=>e.toolCall?.name,getToolInput:(e,t)=>({ok:!0,input:$u(e.toolCall?.args,t),route:zi(t)}),getContext:Tu,getSessionId:(e)=>e.conversationId})}function Tu(e,t,n,r){let i=Ou(e).flatMap((c)=>{let d=V([c]);return d?[d]:[]});if(!i[0])return Te(r,t,n),null;if(n!=="run_command"){let c;try{c=Iu(t,n,i)}catch(d){if(d instanceof fe)return Te(r,void 0,n),null;if(!(d instanceof Ee))throw d;return Te(r,t,n),null}if(!c)return Te(r,t,n),null;return{configCwd:c,executionCwd:c}}let s=e.toolCall?.args;if(!s||!Object.hasOwn(s,"Cwd"))return{configCwd:i[0],executionCwd:i[0]};let a=s.Cwd;if(typeof a!=="string"||a.trim()==="")return Te(r,t,n),null;let l=me(a,i);if(l){let c=Wi(l,i);if(!c)return Te(r,t,n,a),null;return{configCwd:c,executionCwd:l}}return Te(r,t,n,a),null}function Iu(e,t,n){let r=zi(t),o=[...Bi(e,Pu),...r.kind==="patch"?qi(e):[]].filter(Vi),i=Zt(),s=new Set(o.flatMap((a)=>{let l=Wi(St(a,Ct,i),n);return l?[l]:[]}));if(s.size>1)return null;return[...s][0]??n[0]??null}function Wi(e,t){return t.filter((n)=>_u(e,n)).reduce((n,r)=>r.length>n.length?r:n,"")||null}function _u(e,t){let n=Au(t,e);return n===""||!n.startsWith("..")&&!Vi(n)}function Te(e,t,n,r){let o=t&&typeof t==="object"?t.command:void 0;e(Jt({command:typeof o==="string"?o:void 0,segment:r,toolName:n}))}function Ou(e){if(e.workspacePaths===void 0)return[process.cwd()];let t=Array.isArray(e.workspacePaths)?e.workspacePaths.filter((n)=>typeof n==="string"&&n.trim()!==""):[];return V(t)?t:[]}function $u(e,t){if(!e)return;if(t!=="run_command")return e;return{...e,command:typeof e.CommandLine==="string"&&e.CommandLine!==""?e.CommandLine:void 0}}var Rt=[{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,install:{order:4,flag:"--codex",artifactKind:"plugin",probeCommand:["codex","--version"]}},{id:"copilot-cli",displayName:"GitHub Copilot CLI",doctorOrder:7,runtime:{order:5,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:4,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:6,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:7,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:8,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:3,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"]}}],Xt=Rt.slice().sort((e,t)=>e.doctorOrder-t.doctorOrder).map((e)=>e.id),Ji=Rt.filter((e)=>("runtime"in e)).slice().sort((e,t)=>e.runtime.order-t.runtime.order).map((e)=>({id:e.id,displayName:"displayName"in e.runtime?e.runtime.displayName:e.displayName,flags:e.runtime.flags,legacyFlags:"legacyFlags"in e.runtime?e.runtime.legacyFlags:[],description:e.runtime.description,legacyTopLevelFlags:e.runtime.legacyTopLevelFlags})),z=Rt.slice().sort((e,t)=>e.install.order-t.install.order).map((e)=>({id:e.id,...e.install})).map(({order:e,...t})=>t),Oh=Object.fromEntries(Rt.map((e)=>[e.id,e.displayName]));function R(e){return Rt.find((t)=>t.id===e)?.displayName??e}import{homedir as Nu}from"node:os";import{isAbsolute as Yi,join as Rr}from"node:path";function Xi(e){if(e!==void 0&&e!==null&&typeof e!=="string")return"unknown";if(typeof e==="string"&&!Yi(e))return"unknown";try{let t=Zt(),n=typeof e==="string"&&e?St(e,Ct,t):void 0,r=process.env.HOME||Nu(),o=[["codex",process.env.CODEX_HOME||Rr(r,".codex")],["copilot-cli",process.env.COPILOT_HOME||Rr(r,".copilot")],["claude-code",process.env.CLAUDE_CONFIG_DIR||Rr(r,".claude")]],i=n?o.flatMap(([s,a])=>{if(!Yi(a))return[];return Zi(n,St(a,Ct,t))?[s]:[]}):[];if(i.length===1)return i[0]??"unknown";if(i.length>1)return"unknown"}catch(t){if(t instanceof Ee)return"unknown";return"unknown"}if(process.env.CLAUDECODE==="1"||Boolean(process.env.CLAUDE_CODE_ENTRYPOINT))return"claude-code";return"unknown"}var Ar="PreToolUse",Qi="BeforeTool",es="pre_tool_call",Er="PreToolUse";var Fu=new Map([["Bash","posix"],["PowerShell","powershell"]]);function Hu(e){return N(e,Fu)}async function ts(){await F({agent:"claude-code",getAgent:(e)=>Xi(e.transcript_path),createDenyOutput:(e)=>({hookSpecificOutput:{hookEventName:Ar,permissionDecision:"deny",permissionDecisionReason:e}}),isSupported:(e)=>e.hook_event_name===Ar,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:Hu(t)}),getContext:(e,t,n,r)=>ne(e.cwd,t,n,r),getSessionId:(e)=>e.session_id})}var Mu=new Map([["bash","auto"],["Bash","auto"],["powershell","powershell"],["PowerShell","powershell"]]);function ju(e){return N(e,Mu)}async function ns(){await F({agent:"copilot-cli",createDenyOutput:(e)=>({permissionDecision:"deny",permissionDecisionReason:e}),isSupported:()=>!0,getToolName:(e)=>e.toolName,getToolInput:(e,t,n)=>{if(typeof e.toolArgs!=="string")return n({reason:"Failed to parse toolArgs JSON."}),{ok:!1};let r=Dr(e.toolArgs,n,"Failed to parse toolArgs JSON.");if(r===void 0)return{ok:!1};return{ok:!0,input:r,route:ju(t)}},getContext:(e,t,n,r)=>ne(e.cwd,t,n,r),getSessionId:(e)=>typeof e.sessionId==="string"&&e.sessionId.trim()?e.sessionId:void 0})}var Uu=new Map([["Shell","auto"]]);function Gu(e){return N(e,Uu)}async function rs(){await F({agent:"cursor",createDenyOutput:(e)=>({permission:"deny",user_message:e,agent_message:e}),createAllowOutput:()=>({permission:"allow"}),isSupported:()=>!0,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:Gu(t)}),getContext:Bu,getSessionId:(e)=>e.conversation_id})}function Bu(e,t,n,r){let o=qu(e);if(!o[0])return P(r,t,n),null;let i=me(zu(e.cwd),o);if(!i)return P(r,t,n,typeof e.cwd==="string"?e.cwd:void 0),null;if(t===null||typeof t!=="object"||Array.isArray(t))return{configCwd:i,executionCwd:i};if(!Object.hasOwn(t,"working_directory"))return{configCwd:i,executionCwd:i};let s=t.working_directory;if(typeof s!=="string"||s.trim()==="")return P(r,t,n),null;let a=me(s,o);if(!a)return P(r,t,n,s),null;return{configCwd:i,executionCwd:a}}function qu(e){return Vu(e).flatMap((t)=>{let n=V([t]);return n?[n]:[]})}function Vu(e){if(e.workspace_roots===void 0)return typeof e.cwd==="string"&&e.cwd.trim()!==""?[e.cwd]:[];if(!Array.isArray(e.workspace_roots))return[];return e.workspace_roots.filter((t)=>typeof t==="string"&&t.trim()!=="")}function zu(e){return typeof e==="string"&&e.trim()!==""?e:"."}var Ku=new Map([["run_shell_command","auto"]]);function Wu(e){return N(e,Ku)}async function os(){await F({agent:"gemini-cli",createDenyOutput:(e)=>({decision:"deny",reason:e,systemMessage:e}),isSupported:(e)=>e.hook_event_name===Qi,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:Wu(t)}),getContext:(e,t,n,r)=>ne(e.cwd,t,n,r),getSessionId:(e)=>e.session_id})}var Ju=new Map([["run_terminal_command","auto"]]);function Yu(e){return N(e,Ju)}async function is(){await F({agent:"grok-build",createDenyOutput:(e)=>({decision:"deny",reason:e}),createAllowOutput:()=>({decision:"allow"}),isSupported:()=>!0,getToolName:(e)=>e.toolName,getToolInput:(e,t,n)=>{if(e.toolInputTruncated===!0)return P(n,e.toolInput,t),{ok:!1};return{ok:!0,input:e.toolInput,route:Yu(t)}},getContext:Zu,getSessionId:(e)=>e.sessionId})}function Zu(e,t,n,r){let o=V(Xu(e));if(!o)return P(r,t,n),null;let i=me(Qu(e.cwd),[o]);if(!i)return P(r,t,n,typeof e.cwd==="string"?e.cwd:void 0),null;return{configCwd:i,executionCwd:i}}function Xu(e){let t=e.workspaceRoot===void 0?e.cwd:e.workspaceRoot;return typeof t==="string"&&t.trim()!==""?[t]:[]}function Qu(e){return typeof e==="string"&&e.trim()!==""?e:"."}import{resolve as ep}from"node:path";var tp=new Map([["terminal","posix"]]);async function ss(){await F({agent:"hermes-agent",createDenyOutput:(e)=>({action:"block",message:e}),isSupported:(e)=>e.hook_event_name===es,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:N(t,tp)}),getContext:np,getSessionId:(e)=>e.session_id})}function np(e,t,n,r){let o=ne(e.cwd,t,n,r);if(!o)return null;if(!t||typeof t!=="object"||Array.isArray(t))return o;if(!Object.hasOwn(t,"workdir"))return o;let i=t.workdir;if(typeof i!=="string"||i.trim()==="")return P(r,t,n),null;let s=V([ep(o.configCwd,i)]);if(!s)return P(r,t,n,i),null;return{...o,executionCwd:s}}var as=new Map([["Bash","posix"]]);function rp(e){return N(e,as)}async function ls(){await F({agent:"kimi-code",createDenyOutput:(e)=>({hookSpecificOutput:{hookEventName:Er,permissionDecision:"deny",permissionDecisionReason:e}}),isSupported:(e)=>e.hook_event_name===Er,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:rp(t)}),getContext:(e,t,n,r)=>{let o=ne(e.cwd,t,n,r);if(!o)return null;let i=e.tool_input;if(!as.has(n)||!i||!Object.hasOwn(i,"cwd"))return o;let s=i.cwd;if(typeof s!=="string"||s.trim()==="")return P(r,t,n),null;let a=me(s,[o.configCwd]);if(!a)return P(r,t,n,s),null;return{configCwd:o.configCwd,executionCwd:a}},getSessionId:(e)=>e.session_id})}var op={"antigravity-cli":Ki,"claude-code":ts,"copilot-cli":ns,cursor:rs,"gemini-cli":os,"grok-build":is,"hermes-agent":ss,"kimi-code":ls},nt=Ji.map((e)=>({...e,run:op[e.id]}));function cs(e){let t=_({label:"hook",booleans:Object.fromEntries(nt.map((r)=>[r.id,[...r.flags,...r.legacyFlags]]))},e);if(t.errors.length>0)return;let n=nt.filter((r)=>t.flags[r.id]);return n.length===1?n[0]:void 0}function ds(e){return nt.find((t)=>t.legacyTopLevelFlags.some((n)=>n===e))}var ip=nt.map((e)=>({flags:e.flags.join(", "),description:e.description})),sp=nt.flatMap((e)=>e.flags.map((t)=>`cc-safety-net hook ${t}`)),us={name:"hook",description:"Run as an agent CLI hook (reads JSON from stdin)",usage:"hook INTEGRATION_FLAG",options:[...ip,{flags:"-h, --help",description:"Show this help"}],examples:sp};var ps={name:"install",description:"Install CC Safety Net into a coding agent CLI",usage:"install [TARGET_FLAG]",options:[...z.map((e)=>({flags:e.flag,description:`Install ${R(e.id)} ${e.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net install",...z.map((e)=>`cc-safety-net install ${e.flag}`)]},fs={name:"uninstall",description:"Uninstall CC Safety Net from a coding agent CLI",usage:"uninstall [TARGET_FLAG]",options:[...z.map((e)=>({flags:e.flag,description:`Uninstall ${R(e.id)} ${e.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net uninstall",...z.map((e)=>`cc-safety-net uninstall ${e.flag}`)]},ms={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 gs={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 rt={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>",description:"Add a rulebook source and sync"},{usage:"remove <source>",description:"Remove a rulebook source and sync"},{usage:"update [source]",description:"Refresh rulebook lock/cache state"},{usage:"sync",description:"Sync configured rulebooks"},{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:"--check",description:"Check without changing lock/cache state"},{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"},{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","cc-safety-net rule add project-rules","cc-safety-net rule sync","cc-safety-net rule migrate --cleanup","cc-safety-net rule verify"]};var hs={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 ys={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 Qt=[hs,Oi,gs,$i,rt,ps,ms,fs,us,Ni,ys];function ap(e){return e.aliases??[]}function en(e){let t=e.toLowerCase();return Qt.find((n)=>n.name.toLowerCase()===t||ap(n).some((r)=>r.toLowerCase()===t))}import{basename as lp}from"node:path";function tn(e=7,t=pe()){let n=Date.now()-e*24*60*60*1000,r=[],o=new Set,i=0,s,a,l,c;if(t)Ae(t);let d={count:0},p=t?Le(t,d):[];for(let u of p)for(let m of Ce(u,d)){if(m.decision==="allow")continue;let f=new Date(m.ts).getTime();if(f>=n){if(i++,o.add(m.sessionId??lp(u,".jsonl")),a===void 0||f<=a)s=m.ts,a=f;if(c===void 0||f>c)l=m.ts,c=f;cp(r,m,f)}}let g=r.map((u)=>({timestamp:u.ts,command:u.command,reason:u.reason,relativeTime:Wn(new Date(u.ts))}));return{totalBlocked:i,sessionCount:o.size,recentEntries:g,oldestEntry:s,newestEntry:l,unreadable:d.count}}function cp(e,t,n){let r=e.findIndex((o)=>n>new Date(o.ts).getTime());if(r===-1){if(e.length<3)e.push(t);return}if(e.splice(r,0,t),e.length>3)e.pop()}import{dirname as dp}from"node:path";function Ls(e,t,n,r,o){let i;try{if(w(r)===null)return{path:e,exists:!1,valid:!1,ruleCount:0};i=ce(r),i.errors.push(...de(e,t,{userConfigDir:n},o))}catch(s){if(!(s instanceof H))throw s;i={errors:[s.message],ruleNames:new Set}}return{path:e,exists:!0,valid:i.errors.length===0,ruleCount:i.ruleNames.size,...i.errors.length>0?{errors:i.errors}:{}}}function up(e,t){return{source:t,name:e.name,command:e.command,subcommand:e.subcommand,blockArgs:[...e.block_args],reason:e.reason}}function vs(e,t){let n=t?.userConfigPath??ee(),r=t?.projectConfigPath??Q(e),o=dp(n),i=ve({cwd:e,userConfigPath:n,projectConfigPath:r,userConfigDir:o}),s=te({cwd:e,userConfigPath:n,projectConfigPath:r,userConfigDir:o}),a=new Map(i.rulebooks.flatMap((l)=>l.rules.map((c)=>[c,l.source])));return{userConfig:Ls(n,Ze({userConfigPath:n}),o,s.userConfigTarget,s.userScope),projectConfig:Ls(r,Xe(r),o,s.projectConfigTarget,s.projectScope),effectiveRules:i.rules.map((l)=>up(l,a.get(l.name)??"project")),shadowedRules:[]}}var pp=[{flag:S.level,description:"Safety level preset: standard, strict, or paranoid",defaultBehavior:"standard"},{flag:S.strict,description:"Legacy; equivalent to safety.overrides.fail_closed",defaultBehavior:"permissive"},{flag:S.paranoid,description:"Legacy; equivalent to safety.overrides.paranoid_rm and paranoid_interpreters",defaultBehavior:"off"},{flag:S.paranoidRm,description:"Legacy; equivalent to safety.overrides.paranoid_rm",defaultBehavior:"off"},{flag:S.paranoidInterpreters,description:"Legacy; equivalent to safety.overrides.paranoid_interpreters",defaultBehavior:"off"},{flag:S.worktree,description:"Allow local git discards in linked worktrees",defaultBehavior:"off"},{flag:S.debug,description:"Print diagnostic messages to stderr",defaultBehavior:"off"},{flag:S.auditScope,description:"Command decisions recorded: all, or blocked (privacy-minimizing, denials only)",defaultBehavior:"all"}];function bs(){return[...pp.map((e)=>({name:e.flag.name,value:br(e.flag),isSet:wr(e.flag),legacyName:e.flag.legacyName,legacyValue:e.flag.legacyName?process.env[e.flag.legacyName]:void 0,legacyIsSet:e.flag.legacyName?process.env[e.flag.legacyName]!==void 0:void 0,description:e.description,defaultBehavior:e.defaultBehavior})),{name:"CC_SAFETY_NET_HOME",value:process.env.CC_SAFETY_NET_HOME,isSet:process.env.CC_SAFETY_NET_HOME!==void 0,description:"Override user-scope config/cache directory",defaultBehavior:"~/.cc-safety-net"}]}var ws={error:0,warning:1,info:2},fp=["policy","config","audit"];function mp(e){return e.map((t)=>{if(t==="ownership")return"is not owned by the current user";if(t==="permissions")return"has unsafe permissions";if(t==="symlink")return"is a symbolic link";return"is not a directory"}).join(" and ")}var gp=[{derive:(e)=>e.hooks.length>0&&e.hooks.every((t)=>!t.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:(e)=>e.hooks.filter((t)=>t.inspectionStatus==="failed").map((t)=>{let n=R(t.platform);return{checkId:"integration.inspection-failed",severity:"error",title:`${n} inspection failed`,detail:`Doctor could not verify the ${n} integration configuration.`,fixHint:`Correct the reported ${n} configuration error, then run \`cc-safety-net doctor\` again.`,integration:t.platform}})},{derive:(e)=>e.userConfig.exists&&!e.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:e.userConfig.path}]:[]},{derive:(e)=>e.projectConfig.exists&&!e.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:e.projectConfig.path}]:[]},{derive:(e)=>e.configState.state==="degraded"?[{checkId:"config.runtime-degraded",severity:"warning",title:"Runtime is enforcing a fallback configuration",detail:`The rejected candidate configuration is not active: ${e.configState.reason}`,fixHint:"Correct the named source, run `cc-safety-net rule sync` for a rule source, then rerun doctor."}]:[]},{derive:(e)=>{let t=e.environment.find((n)=>n.name==="CC_SAFETY_NET_AUDIT_SCOPE");return vr(t?.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."}]:[]}},...fp.map((e)=>({derive:(t)=>t.posture.directories.filter((n)=>n.kind===e&&n.status==="unsafe").map((n)=>({checkId:`posture.${e}-directory-unsafe`,severity:"error",title:`${e[0]?.toUpperCase()}${e.slice(1)} directory is unsafe`,detail:`The ${e} directory ${mp(n.issues)}.`,fixHint:"Ensure this is a real directory owned by the current user with no group or other write access, then rerun doctor.",...n.path?{path:n.path}:{}}))})),{derive:(e)=>{let t=[...e.effectiveSafety.weakenedRuleOverrides].sort();return t.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: ${t.join(", ")}.`,fixHint:`Remove these \`off\` overrides or set them to \`on\`: ${t.join(", ")}.`}]:[]}}];function ks(e){return gp.flatMap((t,n)=>t.derive(e).map((r,o)=>({finding:r,catalogOrder:n,occurrence:o}))).sort((t,n)=>ws[t.finding.severity]-ws[n.finding.severity]||t.catalogOrder-n.catalogOrder||t.occurrence-n.occurrence).map((t)=>t.finding)}function re(){return Boolean(process.stdout.isTTY&&!process.env.NO_COLOR)}var hp=(e)=>re()?`\x1B[32m${e}\x1B[0m`:e,yp=(e)=>re()?`\x1B[33m${e}\x1B[0m`:e,Lp=(e)=>re()?`\x1B[34m${e}\x1B[0m`:e,vp=(e)=>re()?`\x1B[35m${e}\x1B[0m`:e,bp=(e)=>re()?`\x1B[36m${e}\x1B[0m`:e,wp=(e)=>re()?`\x1B[31m${e}\x1B[0m`:e,kp=(e)=>re()?`\x1B[2m${e}\x1B[0m`:e,xp=(e)=>re()?`\x1B[1m${e}\x1B[0m`:e,h={green:hp,yellow:yp,blue:Lp,magenta:vp,cyan:bp,red:wp,dim:kp,bold:xp},Cp="\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 Dp(e){let t=e;return()=>(t=(t*1664525+1013904223)%4294967296,t/4294967296)}function Rp(e){let t=[...Sp],n=Dp(e);for(let r=t.length-1;r>0;r--){let o=Math.floor(n()*(r+1)),i=t[r];t[r]=t[o],t[o]=i}return t}function Ap(e,t=0){if(!re())return"";let n=Rp(t);return`\x1B[38;5;${n[e%n.length]}m`}function xs(e,t,n=0){if(!re())return`"${e}"`;return`${Ap(t,n)}"${e}"${Cp}`}var Ep=new RegExp("\x1B\\[[0-9;]*m","g"),Pr=(e)=>e.replace(Ep,"").length;function Ie(e){let t=(e.headers??e.rows[0]??[]).map((s,a)=>{let l=Math.max(...e.rows.map((c)=>Pr(c[a]??"")));return Math.max(Pr(s),l)}),n=(s,a)=>s+" ".repeat(Math.max(0,a-Pr(s))),r=(s,a)=>a[0]+t.map((l)=>s.repeat(l+2)).join(a[1])+a[2],o=(s)=>`│ ${s.map((a,l)=>n(a,t[l]??0)).join(" │ ")} │`,i=e.headers?[` ${o(e.headers)}`,` ${r("─",["├","┼","┤"])}`]:[];return[` ${r("─",["┌","┬","┐"])}`,...i,...e.rows.map((s)=>` ${o(s)}`),` ${r("─",["└","┴","┘"])}`].join(`
6
+ `)}function Cs(e){let t=[];t.push("Hook Integration"),t.push(Pp(e));let n=[],r=[];for(let o of e){let i=R(o.platform);if(o.errors&&o.errors.length>0)for(let s of o.errors)if(o.configured)n.push({platform:i,message:s});else r.push({platform:i,message:s})}for(let o of n)t.push(` Warning (${o.platform}): ${o.message}`);for(let o of r)t.push(h.red(` Error (${o.platform}): ${o.message}`));return t.join(`
7
+ `)}function Pp(e){let t=["Platform","Discovery","Configuration","Inspection"],n=e.map((r)=>{let o=R(r.platform);if(r.inspectionStatus==="not-inspected"){let l=h.dim("Not inspected");return[o,l,l,l]}let i=r.detected?h.green("Detected"):r.inspectionStatus==="failed"?h.red("Unknown"):h.dim("Not detected"),s=r.configured?h.green("Configured"):r.detected?h.yellow("Not configured"):r.inspectionStatus==="failed"?h.red("Unknown"):h.dim("Not applicable"),a=r.inspectionStatus==="verified"?h.green("Verified"):r.inspectionStatus==="failed"?h.red("Failed"):h.dim("Not applicable");return[o,i,s,a]});return Ie({headers:t,rows:n})}function Ss(e){let n=["Guard Engine Verification",` Synthetic self-test: ${e.failed>0?h.red(`${e.passed}/${e.total} FAIL`):h.green(`${e.passed}/${e.total} passed`)}`],r=e.results.filter((o)=>!o.passed);if(r.length>0){n.push(""),n.push(h.red(" Failures:"));for(let o of r)n.push(h.red(` • ${o.description}`)),n.push(h.red(` expected ${o.expected}, got ${o.actual}`))}return n.join(`
8
+ `)}function Tp(e){if(e.length===0)return" (no custom rules)";let t=["Source","Name","Command","Block Args"],n=e.map((r)=>[r.source,r.name,r.subcommand?`${r.command} ${r.subcommand}`:r.command,r.blockArgs.join(", ")]);return Ie({headers:t,rows:n})}function Ds(e){let t=[];if(t.push("Configuration"),t.push(Ip(e.userConfig,e.projectConfig)),t.push(""),e.effectiveRules.length>0)t.push(` Effective rules (${e.effectiveRules.length} total):`),t.push(Tp(e.effectiveRules));else t.push(" Effective rules: (none - using built-in rules only)");for(let n of e.shadowedRules)t.push(""),t.push(` Note: Project rule "${n.name}" shadows user rule with same name`);return t.join(`
9
+ `)}function Ip(e,t){let n=["Scope","Status"],r=(i)=>{if(!i.exists)return h.dim("N/A");if(!i.valid)return h.red(`Invalid (${i.errors?.[0]??"unknown error"})`);return h.green("Configured")},o=[["User",r(e)],["Project",r(t)]];return Ie({headers:n,rows:o})}function Rs(e){let t=[];return t.push("Environment"),t.push(_p(e)),t.join(`
10
+ `)}function As(e){let t=["Effective Safety",` Selected preset: ${e.effectiveSafety.selectedPreset}`,` Effective: ${e.effectiveSafety.level}`],n=[["fail_closed","fail_closed"],["paranoid_rm","paranoid_rm"],["paranoid_interpreters","paranoid_interpreters"]];for(let[r,o]of n){let i=e.effectiveSafety.capabilities[r],s=i.enabled?h.green("ON"):h.dim("OFF"),a=i.sources.length>0?` (${i.sources.join(", ")})`:"";t.push(` ${o}: ${s} via ${i.source}${a}`)}t.push(` Stored rule customizations: ${e.effectiveSafety.ruleCounts.stored}`),t.push(` Effective rule customizations: ${e.effectiveSafety.ruleCounts.effective}`);for(let[r,o]of Object.entries(e.effectiveSafety.ruleOverrides))t.push(` ${r}: ${o}`);return t.join(`
11
+ `)}function Es(e){let t=["Findings"];if(e.length===0)return t.push(" No findings from inspected doctor facts."),t.join(`
12
+ `);for(let n of e){let r=`[${n.severity.toUpperCase()}] ${n.checkId}: ${O(n.title)}`,o=n.severity==="error"?h.red:n.severity==="warning"?h.yellow:h.blue;if(t.push(` ${o(r)}`),t.push(` ${O(n.detail)}`),n.path)t.push(` Path: ${O(n.path)}`);if(n.fixHint)t.push(` Fix: ${O(n.fixHint)}`)}return t.join(`
13
+ `)}function _p(e){let t=["Variable","Status","Legacy"],n=e.map((r)=>{let o=r.isSet?h.green("✓"):h.dim("✗"),i=r.legacyName&&r.legacyIsSet?`${r.legacyName} ${h.green("✓")}`:r.legacyName??"";return[r.name,o,i]});return Ie({headers:t,rows:n})}function Ps(e){let t=[];if(e.totalBlocked===0)t.push("Recent Activity"),t.push(" No blocked commands in the last 7 days"),t.push(" Tip: This is normal for new installations");else t.push(`Recent Activity · last 7 days (${e.totalBlocked} blocked / ${e.sessionCount} sessions)`),t.push(Op(e.recentEntries));if(e.unreadable>0)t.push(` Warning: ${e.unreadable} audit log ${e.unreadable===1?"source":"sources"} could not be read; this summary is incomplete`);return t.join(`
14
+ `)}function Op(e){let t=["Time","Command"],n=e.map((r)=>{let o=O(r.command.replace(/\r\n|\r|\n/g," ↵ ").replace(/\t/g," ")),i=o.length>40?`${o.slice(0,37)}...`:o;return[r.relativeTime,i]});return Ie({headers:t,rows:n})}function Ts(e){let t=[];if(t.push("Update Check"),e.latestVersion===null&&!e.error)return t.push(nn([["Status",h.dim("Skipped")],["Installed",e.currentVersion]])),t.join(`
15
+ `);if(e.error)return t.push(nn([["Status",`${h.yellow("⚠")} Error`],["Installed",e.currentVersion],["Error",h.dim(e.error)]])),t.join(`
16
+ `);if(e.updateAvailable)return t.push(nn([["Status",`${h.yellow("⚠")} Update Available`],["Current",e.currentVersion],["Latest",h.green(e.latestVersion??"")]])),t.push(""),t.push(" Run: bunx cc-safety-net@latest doctor"),t.push(" Or: npx cc-safety-net@latest doctor"),t.join(`
17
+ `);return t.push(nn([["Status",`${h.green("✓")} Up to date`],["Version",e.currentVersion]])),t.join(`
18
+ `)}function nn(e){return Ie({rows:e})}function Is(e){let t=[];return t.push("System Info"),t.push($p(e)),t.join(`
19
+ `)}function $p(e){let t=["Component","Version"],n=(i)=>{if(i===null)return h.dim("not found");return i},o=[{label:"cc-safety-net",value:e.version},...Xt.map((i)=>({label:R(i),value:e.versions[i]??null})),{label:"Node.js",value:e.nodeVersion},{label:"npm",value:e.npmVersion},{label:"Bun",value:e.bunVersion},{label:"Platform",value:e.platform}].map((i)=>[i.label,n(i.value)]);return Ie({headers:t,rows:o})}function _s(e){if(e.findings.length===0)return h.green(`
20
20
  No findings from inspected doctor facts.`);let t={error:e.findings.filter((i)=>i.severity==="error").length,warning:e.findings.filter((i)=>i.severity==="warning").length,info:e.findings.filter((i)=>i.severity==="info").length},n=["error","warning","info"].filter((i)=>t[i]>0).map((i)=>`${t[i]} ${i}`),r=e.findings.length===1?"finding":"findings",o=`
21
- ${e.findings.length} ${r}: ${n.join(", ")}.`;if(t.error>0)return h.red(o);if(t.warning>0)return h.yellow(o);return h.blue(o)}import{lstatSync as fp}from"node:fs";import{dirname as Cr}from"node:path";function Sr(e,t){try{let n=fp(t);if(n.isSymbolicLink())return{kind:e,path:t,status:"unsafe",issues:["symlink"]};if(!n.isDirectory())return{kind:e,path:t,status:"unsafe",issues:["not-directory"]};if(process.platform==="win32"||typeof process.getuid!=="function")return{kind:e,path:t,status:"unknown",issues:[]};let r=[...n.uid!==process.getuid()?["ownership"]:[],...(n.mode&18)!==0?["permissions"]:[]];return{kind:e,path:t,status:r.length>0?"unsafe":"safe",issues:r}}catch(n){if(typeof n==="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return{kind:e,path:t,status:"not-applicable",issues:[]};return{kind:e,path:t,status:"unknown",issues:[]}}}function Ds(e){let t=ue();return{directories:[Sr("policy",Cr(Cr(e))),Sr("config",Cr(e)),...t?[Sr("audit",t)]:[{kind:"audit",status:"unknown",issues:[]}]]}}import{spawn as mp}from"node:child_process";import{existsSync as Rs}from"node:fs";import{delimiter as gp,extname as hp,join as yp}from"node:path";import{stripVTControlCharacters as As}from"node:util";var Ps="2.1.1",Lp=5000,vp="_CC_SAFETY_NET_TEST_SPAWN_PLATFORM";function P(){return Ps}function Dr(e,t){let n=e[t];if(n)return n;let r=Object.keys(e).find((o)=>o.toLowerCase()===t.toLowerCase()&&!!e[o]);return r?e[r]:n}function bp(e){return(Dr(e,"PATHEXT")||".COM;.EXE;.BAT;.CMD").split(";").filter((t)=>t.length>0)}function wp(e,t){let n=hp(e)?[e]:[...bp(t).map((r)=>`${e}${r}`),e];if(e.includes("/")||e.includes("\\"))return n.find((r)=>Rs(r))??e;return(Dr(t,"PATH")??"").split(gp).flatMap((r)=>n.map((o)=>yp(r,o))).find((r)=>Rs(r))??e}function Es(e){if(!/[\s"&|<>^]/.test(e))return e;return`"${e.replace(/"/g,'""')}"`}function Ie(e,t){let[n,...r]=e,o=t[vp]==="win32"?"win32":process.platform;if(!n||o!=="win32")return{cmd:n??"",args:r};let i=wp(n,t);if(!/\.(?:bat|cmd)$/i.test(i))return{cmd:i,args:r};return{cmd:Dr(t,"COMSPEC")??"cmd.exe",args:["/d","/c",["call",Es(i),...r.map(Es)].join(" ")]}}var nt=async(e,t=Lp)=>{let n=await xp(e,{timeoutMs:t});if(n.code!==0)return null;return As(n.stdout).trim()||As(n.stderr).trim()||null};function xp(e,t){let[n,...r]=e;if(!n)return Promise.resolve({code:null,stdout:"",stderr:""});return new Promise((o)=>{try{let i=Ie([n,...r],process.env),s=mp(i.cmd,i.args,{stdio:["ignore","pipe","pipe"]}),a=!1,l="",c="";s.stdout.on("data",(g)=>{l+=g.toString()}),s.stderr.on("data",(g)=>{c+=g.toString()});let d=(g)=>{if(a)return;a=!0,clearTimeout(p),o(g)},p=setTimeout(()=>{s.kill(),d({code:null,stdout:l,stderr:c})},t.timeoutMs);s.on("close",(g)=>{d({code:g,stdout:l,stderr:c})}),s.on("error",()=>{d({code:null,stdout:l,stderr:c})})}catch{o({code:null,stdout:"",stderr:""})}})}function en(e){if(!e)return null;let t=/Claude Code\s+(\d+\.\d+\.\d+)/i.exec(e);if(t)return t[1]??null;let n=/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/i.exec(e);if(n)return n[1]??null;return e.split(`
22
- `)[0]?.trim()||null}async function Rt(e=nt){let[t,n,r,o,i,s]=await Promise.all([Promise.all(V.map(async(a)=>[a.id,en(await e([...a.probeCommand]))])),e(["codex","plugin","list"],30000),e(["amp","plugins","list"],30000),e(["node","--version"]),e(["npm","--version"]),e(["bun","--version"])]);return{version:Ps,versions:Object.fromEntries(t),codexPluginListOutput:n,ampPluginListOutput:r,nodeVersion:en(o),npmVersion:en(i),bunVersion:en(s),platform:`${process.platform} ${process.arch}`}}function Rr(e,t){if(t==="dev")return!1;let n=e.split(".").map(Number),r=t.split(".").map(Number),[o=0,i=0,s=0]=n,[a=0,l=0,c=0]=r;if(o!==a)return o>a;if(i!==l)return i>l;return s>c}async function ve(){let e=P(),t=new AbortController,n=setTimeout(()=>t.abort(),3000);try{let r=await fetch("https://registry.npmjs.org/cc-safety-net/latest",{signal:t.signal});if(!r.ok)return{currentVersion:e,latestVersion:null,updateAvailable:!1,error:`npm registry returned ${r.status}`};let o=await r.json(),i=Rr(o.version,e);return{currentVersion:e,latestVersion:o.version,updateAvailable:i}}catch(r){return{currentVersion:e,latestVersion:null,updateAvailable:!1,error:r instanceof Error?r.message:"Network error"}}finally{clearTimeout(n)}}import*as Hs from"node:readline";var Os=(e)=>`\x1B[${e}B`,kp=(e)=>`\x1B[${e}A`;var Ts=["░","▒","▓","╱","╲","┃","━","┏","┓","┗","┛","╋"];function Cp(e){return new Promise((t)=>setTimeout(t,e))}function Sp(e,t,n){if(!n)return t(e);if(n.aborted)return Promise.resolve();return new Promise((r,o)=>{let i=()=>n.removeEventListener("abort",s),s=()=>{i(),r()};n.addEventListener("abort",s,{once:!0}),t(e).then(()=>{i(),r()},(a)=>{i(),o(a)})})}function At(e,t){return e&&e>0?e:t}function tn(e){return Math.max(0,Math.min(1,e))}function rt(e){return Math.max(0,Math.min(255,Math.round(e)))}function Ar(e){return e<=0.0031308?12.92*e:1.055*e**0.4166666666666667-0.055}function Dp(e,t,n){let r=n*Math.PI/180,o=t*Math.cos(r),i=t*Math.sin(r),s=(e+0.3963377774*o+0.2158037573*i)**3,a=(e-0.1055613458*o-0.0638541728*i)**3,l=(e-0.0894841775*o-1.291485548*i)**3;return{blue:rt(Ar(tn(-0.0041960863*s-0.7034186147*a+1.707614701*l))*255),green:rt(Ar(tn(-1.2684380046*s+2.6097574011*a-0.3413193965*l))*255),red:rt(Ar(tn(4.0767416621*s-3.3077115913*a+0.2309699292*l))*255)}}function Er(e,t){let n=(t*e*180/Math.PI%360+360)%360;return Dp(0.72,0.15,n)}function $s(e,t=0.1){let n=Er(t,e);return`\x1B[38;2;${n.red};${n.green};${n.blue}m`}function Rp(e,t){return{blue:rt(e.blue+(255-e.blue)*t),green:rt(e.green+(255-e.green)*t),red:rt(e.red+(255-e.red)*t)}}function Ns(e,t,n){let r=Math.imul(e+2654435769,2246822507)^Math.imul(t+3266489909,668265263)^Math.imul(n+374761393,2654435761),o=r^r>>>15,i=Math.imul(o,739982445),s=i^i>>>12,a=Math.imul(s,695872825);return((a^a>>>15)>>>0)/4294967296}function Ap(e,t,n){let r=Math.floor(Ns(e,t,n)*Ts.length);return Ts[r]??"░"}function Is(e){let t=tn(e);return t*t*t*(t*(t*6-15)+10)}function Ep(e){if(e.length===0)return"";let t=[],n=!1,r="";for(let o of e){let i=`${o.red};${o.green};${o.blue}`;if(o.bold!==n)t.push(o.bold?"\x1B[1m":"\x1B[22m"),n=o.bold;if(i!==r)t.push(`\x1B[38;2;${i}m`),r=i;t.push(o.character)}return`${t.join("")}\x1B[22m\x1B[39m`}function Pp(e,t,n,r,o){return e.map((i,s)=>({...Er(n,r+t+s/o),bold:!1,character:i}))}function Tp(e,t,n,r,o,i,s,a){let l=Math.max(1,r*0.75),c=Math.min(1,n/l),d=o*Is(c),p=Math.max(0,(n-l)/Math.max(1,r-l)),g=(1-Is(n/r))*a*2,u=0.35*Math.max(0,1-p*2),m=c>=1,f=Math.min(e.length,Math.ceil(d+2+1));return e.slice(0,f).map((L,v)=>{let k=Er(i,s+t+v/a+g),y=v+Ns(t,v,7919)*2-1;if(y>d+2)return{...k,bold:!1,character:" "};let C=d-y,H=0.8*Math.exp(-(C*C)/12.5),he=Math.min(0.9,H+u),Mn=!m&&y>d-4;return{...Rp(k,he),bold:he>0.3,character:Mn?Ap(t,v,n):L}})}function _s(e){return`\x1B[?2026h${e.map((t,n)=>`\x1B8${n>0?Os(n):""}${Ep(t)}`).join("")}\x1B[?2026l`}async function Pr(e,t={}){if(!e)return;let n=t.output??process.stdout,r=t.sleep??Cp,o=At(t.frequency,0.1),i=t.seed??0,s=At(t.speed,40),a=At(t.spread,3),l=At(t.frameRate,60),c=Math.max(1,Math.floor(At(t.duration,12))),d=e.split(`
21
+ ${e.findings.length} ${r}: ${n.join(", ")}.`;if(t.error>0)return h.red(o);if(t.warning>0)return h.yellow(o);return h.blue(o)}import{lstatSync as Np}from"node:fs";import{dirname as Tr}from"node:path";function Ir(e,t){try{let n=Np(t);if(n.isSymbolicLink())return{kind:e,path:t,status:"unsafe",issues:["symlink"]};if(!n.isDirectory())return{kind:e,path:t,status:"unsafe",issues:["not-directory"]};if(process.platform==="win32"||typeof process.getuid!=="function")return{kind:e,path:t,status:"unknown",issues:[]};let r=[...n.uid!==process.getuid()?["ownership"]:[],...(n.mode&18)!==0?["permissions"]:[]];return{kind:e,path:t,status:r.length>0?"unsafe":"safe",issues:r}}catch(n){if(typeof n==="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return{kind:e,path:t,status:"not-applicable",issues:[]};return{kind:e,path:t,status:"unknown",issues:[]}}}function Os(e){let t=pe();return{directories:[Ir("policy",Tr(Tr(e))),Ir("config",Tr(e)),...t?[Ir("audit",t)]:[{kind:"audit",status:"unknown",issues:[]}]]}}import{spawn as Fp}from"node:child_process";import{existsSync as $s}from"node:fs";import{delimiter as Hp,extname as Mp,join as jp}from"node:path";import{stripVTControlCharacters as Ns}from"node:util";var Hs="2.2.0",Up=5000,Gp="_CC_SAFETY_NET_TEST_SPAWN_PLATFORM";function T(){return Hs}function _r(e,t){let n=e[t];if(n)return n;let r=Object.keys(e).find((o)=>o.toLowerCase()===t.toLowerCase()&&!!e[o]);return r?e[r]:n}function Bp(e){return(_r(e,"PATHEXT")||".COM;.EXE;.BAT;.CMD").split(";").filter((t)=>t.length>0)}function qp(e,t){let n=Mp(e)?[e]:[...Bp(t).map((r)=>`${e}${r}`),e];if(e.includes("/")||e.includes("\\"))return n.find((r)=>$s(r))??e;return(_r(t,"PATH")??"").split(Hp).flatMap((r)=>n.map((o)=>jp(r,o))).find((r)=>$s(r))??e}function Fs(e){if(!/[\s"&|<>^]/.test(e))return e;return`"${e.replace(/"/g,'""')}"`}function _e(e,t){let[n,...r]=e,o=t[Gp]==="win32"?"win32":process.platform;if(!n||o!=="win32")return{cmd:n??"",args:r};let i=qp(n,t);if(!/\.(?:bat|cmd)$/i.test(i))return{cmd:i,args:r};return{cmd:_r(t,"COMSPEC")??"cmd.exe",args:["/d","/c",["call",Fs(i),...r.map(Fs)].join(" ")]}}var ot=async(e,t=Up)=>{let n=await Vp(e,{timeoutMs:t});if(n.code!==0)return null;return Ns(n.stdout).trim()||Ns(n.stderr).trim()||null};function Vp(e,t){let[n,...r]=e;if(!n)return Promise.resolve({code:null,stdout:"",stderr:""});return new Promise((o)=>{try{let i=_e([n,...r],process.env),s=Fp(i.cmd,i.args,{stdio:["ignore","pipe","pipe"]}),a=!1,l="",c="";s.stdout.on("data",(g)=>{l+=g.toString()}),s.stderr.on("data",(g)=>{c+=g.toString()});let d=(g)=>{if(a)return;a=!0,clearTimeout(p),o(g)},p=setTimeout(()=>{s.kill(),d({code:null,stdout:l,stderr:c})},t.timeoutMs);s.on("close",(g)=>{d({code:g,stdout:l,stderr:c})}),s.on("error",()=>{d({code:null,stdout:l,stderr:c})})}catch{o({code:null,stdout:"",stderr:""})}})}function rn(e){if(!e)return null;let t=/Claude Code\s+(\d+\.\d+\.\d+)/i.exec(e);if(t)return t[1]??null;let n=/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/i.exec(e);if(n)return n[1]??null;return e.split(`
22
+ `)[0]?.trim()||null}async function At(e=ot){let[t,n,r,o,i,s]=await Promise.all([Promise.all(z.map(async(a)=>[a.id,rn(await e([...a.probeCommand]))])),e(["codex","plugin","list"],30000),e(["amp","plugins","list"],30000),e(["node","--version"]),e(["npm","--version"]),e(["bun","--version"])]);return{version:Hs,versions:Object.fromEntries(t),codexPluginListOutput:n,ampPluginListOutput:r,nodeVersion:rn(o),npmVersion:rn(i),bunVersion:rn(s),platform:`${process.platform} ${process.arch}`}}function Or(e,t){if(t==="dev")return!1;let n=e.split(".").map(Number),r=t.split(".").map(Number),[o=0,i=0,s=0]=n,[a=0,l=0,c=0]=r;if(o!==a)return o>a;if(i!==l)return i>l;return s>c}async function be(){let e=T(),t=new AbortController,n=setTimeout(()=>t.abort(),3000);try{let r=await fetch("https://registry.npmjs.org/cc-safety-net/latest",{signal:t.signal});if(!r.ok)return{currentVersion:e,latestVersion:null,updateAvailable:!1,error:`npm registry returned ${r.status}`};let o=await r.json(),i=Or(o.version,e);return{currentVersion:e,latestVersion:o.version,updateAvailable:i}}catch(r){return{currentVersion:e,latestVersion:null,updateAvailable:!1,error:r instanceof Error?r.message:"Network error"}}finally{clearTimeout(n)}}import*as zs from"node:readline";var Gs=(e)=>`\x1B[${e}B`,zp=(e)=>`\x1B[${e}A`;var Ms=["░","▒","▓","╱","╲","┃","━","┏","┓","┗","┛","╋"];function Kp(e){return new Promise((t)=>setTimeout(t,e))}function Wp(e,t,n){if(!n)return t(e);if(n.aborted)return Promise.resolve();return new Promise((r,o)=>{let i=()=>n.removeEventListener("abort",s),s=()=>{i(),r()};n.addEventListener("abort",s,{once:!0}),t(e).then(()=>{i(),r()},(a)=>{i(),o(a)})})}function Et(e,t){return e&&e>0?e:t}function on(e){return Math.max(0,Math.min(1,e))}function it(e){return Math.max(0,Math.min(255,Math.round(e)))}function $r(e){return e<=0.0031308?12.92*e:1.055*e**0.4166666666666667-0.055}function Jp(e,t,n){let r=n*Math.PI/180,o=t*Math.cos(r),i=t*Math.sin(r),s=(e+0.3963377774*o+0.2158037573*i)**3,a=(e-0.1055613458*o-0.0638541728*i)**3,l=(e-0.0894841775*o-1.291485548*i)**3;return{blue:it($r(on(-0.0041960863*s-0.7034186147*a+1.707614701*l))*255),green:it($r(on(-1.2684380046*s+2.6097574011*a-0.3413193965*l))*255),red:it($r(on(4.0767416621*s-3.3077115913*a+0.2309699292*l))*255)}}function Nr(e,t){let n=(t*e*180/Math.PI%360+360)%360;return Jp(0.72,0.15,n)}function Bs(e,t=0.1){let n=Nr(t,e);return`\x1B[38;2;${n.red};${n.green};${n.blue}m`}function Yp(e,t){return{blue:it(e.blue+(255-e.blue)*t),green:it(e.green+(255-e.green)*t),red:it(e.red+(255-e.red)*t)}}function qs(e,t,n){let r=Math.imul(e+2654435769,2246822507)^Math.imul(t+3266489909,668265263)^Math.imul(n+374761393,2654435761),o=r^r>>>15,i=Math.imul(o,739982445),s=i^i>>>12,a=Math.imul(s,695872825);return((a^a>>>15)>>>0)/4294967296}function Zp(e,t,n){let r=Math.floor(qs(e,t,n)*Ms.length);return Ms[r]??"░"}function js(e){let t=on(e);return t*t*t*(t*(t*6-15)+10)}function Xp(e){if(e.length===0)return"";let t=[],n=!1,r="";for(let o of e){let i=`${o.red};${o.green};${o.blue}`;if(o.bold!==n)t.push(o.bold?"\x1B[1m":"\x1B[22m"),n=o.bold;if(i!==r)t.push(`\x1B[38;2;${i}m`),r=i;t.push(o.character)}return`${t.join("")}\x1B[22m\x1B[39m`}function Qp(e,t,n,r,o){return e.map((i,s)=>({...Nr(n,r+t+s/o),bold:!1,character:i}))}function e2(e,t,n,r,o,i,s,a){let l=Math.max(1,r*0.75),c=Math.min(1,n/l),d=o*js(c),p=Math.max(0,(n-l)/Math.max(1,r-l)),g=(1-js(n/r))*a*2,u=0.35*Math.max(0,1-p*2),m=c>=1,f=Math.min(e.length,Math.ceil(d+2+1));return e.slice(0,f).map((L,v)=>{let x=Nr(i,s+t+v/a+g),y=v+qs(t,v,7919)*2-1;if(y>d+2)return{...x,bold:!1,character:" "};let C=d-y,j=0.8*Math.exp(-(C*C)/12.5),ye=Math.min(0.9,j+u),zn=!m&&y>d-4;return{...Yp(x,ye),bold:ye>0.3,character:zn?Zp(t,v,n):L}})}function Us(e){return`\x1B[?2026h${e.map((t,n)=>`\x1B8${n>0?Gs(n):""}${Xp(t)}`).join("")}\x1B[?2026l`}async function Fr(e,t={}){if(!e)return;let n=t.output??process.stdout,r=t.sleep??Kp,o=Et(t.frequency,0.1),i=t.seed??0,s=Et(t.speed,40),a=Et(t.spread,3),l=Et(t.frameRate,60),c=Math.max(1,Math.floor(Et(t.duration,12))),d=e.split(`
23
23
  `).map((f)=>Array.from(f)),p=Math.max(...d.map((f)=>f.length)),g=1000*c*d.filter((f)=>f.length>0).length/s,u=p>0?Math.max(1,Math.ceil(g/(1000/l))):0,m=u>0?g/u:0;n.write(`\x1B[?25l${d.length>1?`${`
24
- `.repeat(d.length-1)}${kp(d.length-1)}`:""}\x1B7`);try{for(let f=1;f<=u;f+=1){if(t.signal?.aborted)break;n.write(_s(d.map((L,v)=>Tp(L,v,f,u,p,o,i,a)))),await Sp(m,r,t.signal)}}finally{if(n.write(_s(d.map((f,L)=>Pp(f,L,o,i,a)))),n.write("\x1B8"),d.length>1)n.write(Os(d.length-1));n.write(`
25
- \x1B[0m\x1B[?25h`)}}var Fs=["┏━┛┏━┛ ┏━┛┏━┃┏━┛┏━┛━┏┛┃ ┃ ┏━ ┏━┛━┏┛","┃ ┃ ━━┃┏━┃┏━┛┏━┛ ┃ ━┏┛ ┃ ┃┏━┛ ┃ ","━━┛━━┛ ━━┛┛ ┛┛ ━━┛ ┛ ┛ ┛ ┛━━┛ ┛ "].join(`
26
- `);function Ip(e){return Boolean(e.isTTY)}async function Et(e={}){let t=e.output??process.stdout;if(!Ip(t))return;let n=e.input??process.stdin,r={duration:e.duration,frequency:e.frequency,output:t,seed:e.seed??Math.random()*8192,sleep:e.sleep,speed:e.speed,spread:e.spread};if(!n.isTTY||typeof n.setRawMode!=="function"){await Pr(Fs,r);return}let o=new AbortController,i=n.readableFlowing===!0,s=n.isRaw===!0,a=!1,l=(c,d)=>{if(d.ctrl&&d.name==="c")a=!0;if(a||d.name==="return"||d.name==="enter")o.abort()};Hs.emitKeypressEvents(n),n.on("keypress",l),n.setRawMode(!0),n.resume();try{await Pr(Fs,{...r,signal:o.signal})}finally{if(n.off("keypress",l),n.setRawMode(s),!i)n.pause()}if(!a)return;if(e.onInterrupt){e.onInterrupt();return}process.kill(process.pid,"SIGINT")}var Ms="\r\x1B[2K",_p="\x1B[?25l",Op="\x1B[39m",$p="\x1B[?25h",Np=100,Fp=0.55,Hp=80,js=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function Mp(e){return new Promise((t)=>setTimeout(t,e))}async function nn(e,t={}){let n=t.output??process.stdout;if(!n.isTTY)return e;let r=t.sleep??Mp,o=!1,i=e.then((a)=>(o=!0,a),(a)=>{throw o=!0,a});if(await Promise.race([i.then(()=>!0),r(Np).then(()=>!1)]))return i;n.write(_p);try{for(let a=0;!o;a+=1)n.write(`${Ms}${$s(a*Fp)}${js[a%js.length]}${Op} ${t.loadingMessage??"Loading…"}`),await Promise.race([i,r(Hp)]);return await i}finally{n.write(`${Ms}${$p}`)}}async function Pt(e,t,n,r={}){let o=t();if(e)await n();if(e&&o.ready)await nn(o.ready,r);return o.finish()}import{homedir as lf}from"node:os";import{stripVTControlCharacters as jp}from"node:util";var rn="amp plugins list",Up=/^\s*[✓✗]\s+cc-safety-net(?:\.ts)?\s+\(User Plugins\)\s+(\S+)\s*$/;function Us(e){if(!e.ampPluginListOutput)return{platform:"amp",status:"n/a"};let t=jp(e.ampPluginListOutput).split(`
27
- `).map((n)=>Up.exec(n)?.[1]).find((n)=>n!==void 0);if(!t)return{platform:"amp",status:"n/a"};if(t!=="active")return{platform:"amp",status:"disabled",method:rn,configPath:rn,errors:[`Amp personal plugin cc-safety-net is ${t}; run "plugins: reload" in Amp or reinstall with install --amp`]};return{platform:"amp",status:"configured",method:rn,configPath:rn}}import{existsSync as Gp,readFileSync as Bp}from"node:fs";var qp=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*(?:--agy-cli|-ac)(\s|["']|$)/;function Vp(e){if(!e||typeof e!=="object"||Array.isArray(e))return[];return Object.values(e).flatMap((t)=>{if(!t||typeof t!=="object"||Array.isArray(t))return[];let n=t,r=n.PreToolUse;if(!Array.isArray(r))return[];return r.flatMap((o)=>{if(!o||typeof o!=="object"||Array.isArray(o))return[];let i=o.hooks;if(!Array.isArray(i))return[];return i.flatMap((s)=>{if(!s||typeof s!=="object"||Array.isArray(s))return[];let a=s.command;if(typeof a!=="string"||!qp.test(a))return[];return[{command:a,enabled:n.enabled!==!1}]})})})}function Gs(e){let t=St(e.homeDir);if(!Gp(t))return{platform:"antigravity-cli",status:"n/a",configPath:t};let n;try{n=Vp(JSON.parse(Bp(t,"utf-8")))}catch(r){return{platform:"antigravity-cli",status:"n/a",configPath:t,errors:[`Failed to parse Antigravity hooks config ${t}: ${r instanceof Error?r.message:String(r)}`]}}if(n.some((r)=>r.enabled))return{platform:"antigravity-cli",status:"configured",method:"hook config",configPath:t};if(n.length>0)return{platform:"antigravity-cli",status:"disabled",method:"hook config",configPath:t};return{platform:"antigravity-cli",status:"n/a",configPath:t}}import{join as Bs}from"node:path";import{existsSync as zp,lstatSync as Kp,readFileSync as Wp}from"node:fs";function re(e,t=(n)=>n){if(!zp(e))return{kind:"missing"};try{return{kind:"ok",value:JSON.parse(t(Wp(e,"utf-8")))}}catch{return{kind:"unreadable"}}}function E(e){try{return Kp(e)}catch{return}}function on(e,t){let n=E(t);if(!n)return{platform:e,status:"n/a",configPath:t};if(!n.isSymbolicLink()&&n.isDirectory())return;return{platform:e,status:"n/a",configPath:t,errors:[`${t} is a symlink or not a directory; move or remove it before installing`]}}function b(e,t){return typeof e==="object"&&e!==null?e[t]:void 0}var Tr="cc-safety-net@cc-marketplace";function qs(e){return Bs(e,".claude","plugins","installed_plugins.json")}function Vs(e,t){let n=b(b(e,"plugins"),t);return Array.isArray(n)&&n.length>0}function sn(e,t){let n=re(qs(e));return n.kind==="ok"&&Vs(n.value,t)}function Ir(e){let t=qs(e),n=re(t);if(n.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(n.kind==="missing")return{platform:"claude-code",status:"n/a"};if(!Vs(n.value,Tr))return{platform:"claude-code",status:"n/a"};let r=Bs(e,".claude","settings.json"),o=re(r);if(o.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(!(o.kind==="ok"&&b(b(o.value,"enabledPlugins"),Tr)===!0))return{platform:"claude-code",status:"disabled",method:"plugin config",configPath:r,errors:[`${Tr} is installed but not enabled in Claude Code`]};return{platform:"claude-code",status:"configured",method:"plugin config",configPath:t}}function zs(e){return Ir(e.homeDir)}function Ks(e){if(!e.codexPluginListOutput)return{platform:"codex",status:"n/a"};let t=e.codexPluginListOutput.split(`
28
- `).find((n)=>n.includes("https://github.com/kenryu42/cc-safety-net.git"));if(!t)return{platform:"codex",status:"n/a"};if(!t.includes("installed,"))return{platform:"codex",status:"n/a"};if(!t.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"}}import{existsSync as dn,readdirSync as Jp,readFileSync as Yp}from"node:fs";import{join as F}from"node:path";var oe="cc-safety-net@cc-marketplace",an=["cc-marketplace","cc-safety-net"],Ws=["_direct","copilot-safety-net"],Js=["cc-marketplace","safety-net"],Ys="safety-net@cc-marketplace";function ln(e,t){let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^a-z0-9-])${n}([^a-z0-9-]|$)`,"m").test(e??"")}function Zs(e){return ln(e,"cc-safety-net@cc-marketplace")}function Xs(e){return ln(e,"cc-marketplace")}function Qs(e){return ln(e,"copilot-safety-net")}function ea(e){return ln(e,"safety-net@cc-marketplace")}function q(e){let t="",n=0,r=!1,o=!1,i=-1;while(n<e.length){let s=e[n],a=e[n+1];if(o){t+=s,o=!1,n++;continue}if(s==='"'&&!r){r=!0,i=-1,t+=s,n++;continue}if(s==='"'&&r){r=!1,t+=s,n++;continue}if(s==="\\"&&r){o=!0,t+=s,n++;continue}if(r){t+=s,n++;continue}if(s==="/"&&a==="/"){while(n<e.length&&e[n]!==`
29
- `)n++;continue}if(s==="/"&&a==="*"){n+=2;while(n<e.length-1){if(e[n]==="*"&&e[n+1]==="/"){n+=2;break}n++}continue}if(s===","){i=t.length,t+=s,n++;continue}if(s==="}"||s==="]"){if(i!==-1){let l=t.slice(i+1);if(/^\s*$/.test(l))t=t.slice(0,i)+l}i=-1,t+=s,n++;continue}if(!/\s/.test(s))i=-1;t+=s,n++}return t}function _r(e){if(!e?.includes("cc-safety-net"))return!1;return/(^|\s)hook\s+(?:[^\s]+\s+)*(--copilot-cli|-cp)(\s|$)/.test(e)}function na(e,t){if(!e)return null;let n=e.match(/(\d+)\.(\d+)\.(\d+)/);if(!n)return null;let r=[Number(n[1]),Number(n[2]),Number(n[3])];for(let o=0;o<t.length;o++){let i=r[o]??0,s=t[o]??0;if(i!==s)return i>s}return!0}function Zp(e){return na(e,[0,0,422])}function Xp(e){return na(e,[1,0,8])}function Tt(e){return process.env.COPILOT_HOME||F(e,".copilot")}function Or(e){return(e.hooks?.preToolUse??[]).some((n)=>{if(n.type!=="command")return!1;return _r(n.command)||_r(n.bash)||_r(n.powershell)})}function cn(e){return e===void 0||typeof e==="string"}function Qp(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e;if(t.disableAllHooks!==void 0&&typeof t.disableAllHooks!=="boolean")return!1;if(t.hooks===void 0)return!0;if(!t.hooks||typeof t.hooks!=="object"||Array.isArray(t.hooks))return!1;let n=t.hooks.preToolUse;if(n===void 0)return!0;return Array.isArray(n)&&n.every((r)=>r!==null&&typeof r==="object"&&!Array.isArray(r)&&cn(r.type)&&cn(r.command)&&cn(r.bash)&&cn(r.powershell))}function $r(e,t){try{let n=JSON.parse(q(Yp(e,"utf-8")));if(!Qp(n)){t?.push(`Invalid hook config ${e}: hooks.preToolUse must be an array of hook objects`);return}return n}catch(n){t?.push(`Failed to parse ${e}: ${n instanceof Error?n.message:String(n)}`);return}}function ra(e,t){try{return Jp(e).filter((n)=>n.endsWith(".json")).sort((n,r)=>n.localeCompare(r))}catch(n){return t?.push(`Failed to read ${e}: ${n instanceof Error?n.message:String(n)}`),[]}}function e2(e,t){if(!dn(e))return[];let n=[];for(let r of ra(e,t)){let o=F(e,r),i=$r(o,t);if(i&&Or(i))n.push(o)}return n}function ot(e,t){if(!dn(e))return;let n=$r(e,t);if(!n)return;return{path:e,config:n}}function ta(e,t,n,r){if(t){e.push(`GitHub Copilot CLI ${t} does not support ${n}; requires ${r}+`);return}e.push(`GitHub Copilot CLI version unavailable; skipping ${n} because it requires ${r}+`)}function t2(e){for(let t of e){if(t?.config.disableAllHooks===!0)return t.path;if(t?.config.disableAllHooks===!1)return}return}function n2(e,t,n,r){let o=Tt(e),i=F(t,".github","hooks"),s=F(o,"hooks"),a=F(t,".github","copilot"),l=F(t,".claude"),c=Xp(n),d=c===!0?r:void 0,p=[ot(F(a,"settings.local.json"),d),ot(F(a,"settings.json"),d),ot(F(l,"settings.local.json"),d),ot(F(l,"settings.json"),d)],g=[ot(F(o,"settings.json"),d),ot(F(o,"config.json"),d)];if(c!==!1){let C=t2([...p,...g]);if(C){if(c===null)r.push(`GitHub Copilot CLI version unavailable; treating disableAllHooks in ${C} as active`);return{activeConfigPaths:[],disabledBy:C}}}let u=e2(i,r),m=Zp(n),f=m===!0?r:void 0,L=dn(s)?ra(s,f):[],v=[];for(let C of L){let H=F(s,C),he=$r(H,f);if(he&&Or(he))v.push(H)}if(m!==!0&&v.length>0)ta(r,n,`user hook files in ${s}`,"0.0.422"),v.length=0;let k=[];for(let C of[...p,...g]){if(!C)continue;if(!Or(C.config))continue;if(c===!0){k.push(C);continue}ta(r,n,"inline hook definitions in Copilot config files","1.0.8");break}let y=(C)=>C.filter((H)=>!!H&&k.includes(H)).map((H)=>H.path);return{activeConfigPaths:[...y(p),...u,...y(g),...v]}}function oa(e){let t=[],n=n2(e.homeDir,e.cwd,e.copilotCliVersion,t);if(n.disabledBy)return{platform:"copilot-cli",status:"disabled",method:"hook config",configPath:n.disabledBy,configPaths:[n.disabledBy],errors:t.length>0?t:void 0};let r=Tt(e.homeDir),o=F(r,"installed-plugins",...an),i=dn(o),s=F(r,"settings.json"),a=re(s,q);if(i&&a.kind==="unreadable")return{platform:"copilot-cli",status:"not-inspected"};if(i&&a.kind==="ok"&&b(b(a.value,"enabledPlugins"),oe)===!1)return{platform:"copilot-cli",status:"disabled",method:"plugin config",configPath:s,errors:[`${oe} is installed but not enabled in Copilot CLI`]};if(i||n.activeConfigPaths.length>0){let l=i,c=n.activeConfigPaths[0];return{platform:"copilot-cli",status:"configured",method:l?"plugin config":"hook config",configPath:c??(l?o:void 0),configPaths:n.activeConfigPaths.length>0?n.activeConfigPaths:void 0,errors:t.length>0?t:void 0}}return{platform:"copilot-cli",status:"n/a",errors:t.length>0?t:void 0}}import{existsSync as p2,readFileSync as f2}from"node:fs";import{existsSync as ia,mkdirSync as i2,readFileSync as s2}from"node:fs";import{dirname as a2,join as l2}from"node:path";import{renameSync as r2,writeFileSync as o2}from"node:fs";function _(e,t){let n=`${e}.${process.pid}.tmp`;o2(n,t),r2(n,e)}var It="npx -y cc-safety-net hook --cursor",sa=30;function pn(e){return l2(e,".cursor","hooks.json")}function _e(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Nr(){return{command:It,timeout:sa,failClosed:!0}}function un(e){return _e(e)&&e.command===It}function c2(e){return Object.keys(e).length===3&&e.command===It&&e.timeout===sa&&e.failClosed===!0}function d2(e){try{return JSON.parse(s2(e,"utf-8"))}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Cursor hooks config ${e}: ${t.message}`);throw t}}function aa(e){let t=d2(e);if(!_e(t))throw Error(`Cursor hooks config ${e} must be a JSON object`);if(t.version!==1)throw Error(`Cursor hooks config ${e} must set "version": 1`);if(t.hooks!==void 0&&!_e(t.hooks))throw Error(`Cursor hooks config ${e} "hooks" must be an object`);let n=_e(t.hooks)?t.hooks.preToolUse:void 0;if(n!==void 0&&!Array.isArray(n))throw Error(`Cursor hooks config ${e} "hooks.preToolUse" must be an array`);return t}function la(e){let t=_e(e.hooks)?e.hooks.preToolUse:void 0;return Array.isArray(t)?t:[]}function u2(e){if(!e.some(un))return[...e,Nr()];return e.reduce((t,n)=>{if(!un(n))return t.result.push(n),t;if(!t.inserted)t.result.push(Nr()),t.inserted=!0;return t},{result:[],inserted:!1}).result}function ca(e,t,n){let r=_e(t.hooks)?t.hooks:{},o={...t,hooks:{...r,preToolUse:n}};_(e,`${JSON.stringify(o,null,2)}
30
- `)}function da(e){let t=pn(e);if(!ia(t))return i2(a2(t),{recursive:!0}),_(t,`${JSON.stringify({version:1,hooks:{preToolUse:[Nr()]}},null,2)}
31
- `),{path:t,alreadyInstalled:!1};let n=aa(t),r=la(n),o=r.filter(un);if(_e(n.hooks)&&Array.isArray(n.hooks.preToolUse)&&o.length===1&&o[0]!==void 0&&c2(o[0]))return{path:t,alreadyInstalled:!0};return ca(t,n,u2(r)),{path:t,alreadyInstalled:!1}}function ua(e){let t=pn(e);if(!ia(t))return{path:t,alreadyInstalled:!1};let n=aa(t),r=la(n),o=r.filter((i)=>!un(i));if(o.length===r.length)return{path:t,alreadyInstalled:!1};return ca(t,n,o),{path:t,alreadyInstalled:!0}}function m2(e){if(!e||typeof e!=="object"||Array.isArray(e))return[];let t=e.hooks;if(!t||typeof t!=="object"||Array.isArray(t))return[];let n=t.preToolUse;if(!Array.isArray(n))return[];return n.filter((r)=>!!r&&typeof r==="object"&&!Array.isArray(r)&&r.command===It)}function g2(e){let t=[];if(e.length>1)t.push("Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates");let n=e[0];if(n&&n.failClosed!==!0)t.push('Managed hook is missing "failClosed": true; reinstall to repair');if(n&&n.timeout!==30)t.push('Managed hook "timeout" is not 30; reinstall to repair');return t}function pa(e){let t=pn(e.homeDir);if(!p2(t))return{platform:"cursor",status:"n/a",configPath:t};let n;try{n=JSON.parse(f2(t,"utf-8"))}catch(i){return{platform:"cursor",status:"n/a",configPath:t,errors:[`Failed to parse Cursor hooks config ${t}: ${i instanceof Error?i.message:String(i)}`]}}let r=m2(n);if(r.length===0)return{platform:"cursor",status:"n/a",configPath:t};let o=g2(r);return{platform:"cursor",status:"configured",method:"hook config",configPath:t,errors:o.length>0?o:void 0}}import{existsSync as h2}from"node:fs";import{join as Fr}from"node:path";var Hr="gemini-safety-net";function Mr(e){let t=Fr(e,".gemini","extensions"),n=Fr(t,Hr);if(!h2(n))return{platform:"gemini-cli",status:"n/a"};let r=Fr(t,"extension-enablement.json"),o=re(r);if(o.kind==="unreadable")return{platform:"gemini-cli",status:"not-inspected"};let i=o.kind==="ok"?b(b(o.value,Hr),"overrides"):void 0;if(Array.isArray(i)&&i.some((a)=>typeof a==="string"&&a.startsWith("!")))return{platform:"gemini-cli",status:"disabled",method:"extension config",configPath:r,errors:[`${Hr} is disabled in Gemini CLI`]};return{platform:"gemini-cli",status:"configured",method:"extension config",configPath:n}}function fa(e){return Mr(e.homeDir)}import{readFileSync as xa}from"node:fs";import{join as ka}from"node:path";var z="cc-safety-net",ma="# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent";function ga(e){return`# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent
24
+ `.repeat(d.length-1)}${zp(d.length-1)}`:""}\x1B7`);try{for(let f=1;f<=u;f+=1){if(t.signal?.aborted)break;n.write(Us(d.map((L,v)=>e2(L,v,f,u,p,o,i,a)))),await Wp(m,r,t.signal)}}finally{if(n.write(Us(d.map((f,L)=>Qp(f,L,o,i,a)))),n.write("\x1B8"),d.length>1)n.write(Gs(d.length-1));n.write(`
25
+ \x1B[0m\x1B[?25h`)}}var Vs=["┏━┛┏━┛ ┏━┛┏━┃┏━┛┏━┛━┏┛┃ ┃ ┏━ ┏━┛━┏┛","┃ ┃ ━━┃┏━┃┏━┛┏━┛ ┃ ━┏┛ ┃ ┃┏━┛ ┃ ","━━┛━━┛ ━━┛┛ ┛┛ ━━┛ ┛ ┛ ┛ ┛━━┛ ┛ "].join(`
26
+ `);function t2(e){return Boolean(e.isTTY)}async function Pt(e={}){let t=e.output??process.stdout;if(!t2(t))return;let n=e.input??process.stdin,r={duration:e.duration,frequency:e.frequency,output:t,seed:e.seed??Math.random()*8192,sleep:e.sleep,speed:e.speed,spread:e.spread};if(!n.isTTY||typeof n.setRawMode!=="function"){await Fr(Vs,r);return}let o=new AbortController,i=n.readableFlowing===!0,s=n.isRaw===!0,a=!1,l=(c,d)=>{if(d.ctrl&&d.name==="c")a=!0;if(a||d.name==="return"||d.name==="enter")o.abort()};zs.emitKeypressEvents(n),n.on("keypress",l),n.setRawMode(!0),n.resume();try{await Fr(Vs,{...r,signal:o.signal})}finally{if(n.off("keypress",l),n.setRawMode(s),!i)n.pause()}if(!a)return;if(e.onInterrupt){e.onInterrupt();return}process.kill(process.pid,"SIGINT")}var Ks="\r\x1B[2K",n2="\x1B[?25l",r2="\x1B[39m",o2="\x1B[?25h",i2=100,s2=0.55,a2=80,Ws=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function l2(e){return new Promise((t)=>setTimeout(t,e))}async function sn(e,t={}){let n=t.output??process.stdout;if(!n.isTTY)return e;let r=t.sleep??l2,o=!1,i=e.then((a)=>(o=!0,a),(a)=>{throw o=!0,a});if(await Promise.race([i.then(()=>!0),r(i2).then(()=>!1)]))return i;n.write(n2);try{for(let a=0;!o;a+=1)n.write(`${Ks}${Bs(a*s2)}${Ws[a%Ws.length]}${r2} ${t.loadingMessage??"Loading…"}`),await Promise.race([i,r(a2)]);return await i}finally{n.write(`${Ks}${o2}`)}}async function Tt(e,t,n,r={}){let o=t();if(e)await n();if(e&&o.ready)await sn(o.ready,r);return o.finish()}import{homedir as Hf}from"node:os";import{stripVTControlCharacters as c2}from"node:util";var an="amp plugins list",d2=/^\s*[✓✗]\s+cc-safety-net(?:\.ts)?\s+\(User Plugins\)\s+(\S+)\s*$/;function Js(e){if(!e.ampPluginListOutput)return{platform:"amp",status:"n/a"};let t=c2(e.ampPluginListOutput).split(`
27
+ `).map((n)=>d2.exec(n)?.[1]).find((n)=>n!==void 0);if(!t)return{platform:"amp",status:"n/a"};if(t!=="active")return{platform:"amp",status:"disabled",method:an,configPath:an,errors:[`Amp personal plugin cc-safety-net is ${t}; run "plugins: reload" in Amp or reinstall with install --amp`]};return{platform:"amp",status:"configured",method:an,configPath:an}}import{existsSync as u2,readFileSync as p2}from"node:fs";var f2=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*(?:--agy-cli|-ac)(\s|["']|$)/;function m2(e){if(!e||typeof e!=="object"||Array.isArray(e))return[];return Object.values(e).flatMap((t)=>{if(!t||typeof t!=="object"||Array.isArray(t))return[];let n=t,r=n.PreToolUse;if(!Array.isArray(r))return[];return r.flatMap((o)=>{if(!o||typeof o!=="object"||Array.isArray(o))return[];let i=o.hooks;if(!Array.isArray(i))return[];return i.flatMap((s)=>{if(!s||typeof s!=="object"||Array.isArray(s))return[];let a=s.command;if(typeof a!=="string"||!f2.test(a))return[];return[{command:a,enabled:n.enabled!==!1}]})})})}function Ys(e){let t=Dt(e.homeDir);if(!u2(t))return{platform:"antigravity-cli",status:"n/a",configPath:t};let n;try{n=m2(JSON.parse(p2(t,"utf-8")))}catch(r){return{platform:"antigravity-cli",status:"n/a",configPath:t,errors:[`Failed to parse Antigravity hooks config ${t}: ${r instanceof Error?r.message:String(r)}`]}}if(n.some((r)=>r.enabled))return{platform:"antigravity-cli",status:"configured",method:"hook config",configPath:t};if(n.length>0)return{platform:"antigravity-cli",status:"disabled",method:"hook config",configPath:t};return{platform:"antigravity-cli",status:"n/a",configPath:t}}import{join as Zs}from"node:path";import{existsSync as g2,lstatSync as h2,readFileSync as y2}from"node:fs";function oe(e,t=(n)=>n){if(!g2(e))return{kind:"missing"};try{return{kind:"ok",value:JSON.parse(t(y2(e,"utf-8")))}}catch{return{kind:"unreadable"}}}function E(e){try{return h2(e)}catch{return}}function ln(e,t){let n=E(t);if(!n)return{platform:e,status:"n/a",configPath:t};if(!n.isSymbolicLink()&&n.isDirectory())return;return{platform:e,status:"n/a",configPath:t,errors:[`${t} is a symlink or not a directory; move or remove it before installing`]}}function b(e,t){return typeof e==="object"&&e!==null?e[t]:void 0}var Hr="cc-safety-net@cc-marketplace";function Xs(e){return Zs(e,".claude","plugins","installed_plugins.json")}function Qs(e,t){let n=b(b(e,"plugins"),t);return Array.isArray(n)&&n.length>0}function cn(e,t){let n=oe(Xs(e));return n.kind==="ok"&&Qs(n.value,t)}function Mr(e){let t=Xs(e),n=oe(t);if(n.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(n.kind==="missing")return{platform:"claude-code",status:"n/a"};if(!Qs(n.value,Hr))return{platform:"claude-code",status:"n/a"};let r=Zs(e,".claude","settings.json"),o=oe(r);if(o.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(!(o.kind==="ok"&&b(b(o.value,"enabledPlugins"),Hr)===!0))return{platform:"claude-code",status:"disabled",method:"plugin config",configPath:r,errors:[`${Hr} is installed but not enabled in Claude Code`]};return{platform:"claude-code",status:"configured",method:"plugin config",configPath:t}}function ea(e){return Mr(e.homeDir)}function ta(e){if(!e.codexPluginListOutput)return{platform:"codex",status:"n/a"};let t=e.codexPluginListOutput.split(`
28
+ `).find((n)=>n.includes("https://github.com/kenryu42/cc-safety-net.git"));if(!t)return{platform:"codex",status:"n/a"};if(!t.includes("installed,"))return{platform:"codex",status:"n/a"};if(!t.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"}}import{existsSync as fn,readdirSync as L2,readFileSync as v2}from"node:fs";import{join as M}from"node:path";var ie="cc-safety-net@cc-marketplace",dn=["cc-marketplace","cc-safety-net"],na=["_direct","copilot-safety-net"],ra=["cc-marketplace","safety-net"],oa="safety-net@cc-marketplace";function un(e,t){let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^a-z0-9-])${n}([^a-z0-9-]|$)`,"m").test(e??"")}function ia(e){return un(e,"cc-safety-net@cc-marketplace")}function sa(e){return un(e,"cc-marketplace")}function aa(e){return un(e,"copilot-safety-net")}function la(e){return un(e,"safety-net@cc-marketplace")}function q(e){let t="",n=0,r=!1,o=!1,i=-1;while(n<e.length){let s=e[n],a=e[n+1];if(o){t+=s,o=!1,n++;continue}if(s==='"'&&!r){r=!0,i=-1,t+=s,n++;continue}if(s==='"'&&r){r=!1,t+=s,n++;continue}if(s==="\\"&&r){o=!0,t+=s,n++;continue}if(r){t+=s,n++;continue}if(s==="/"&&a==="/"){while(n<e.length&&e[n]!==`
29
+ `)n++;continue}if(s==="/"&&a==="*"){n+=2;while(n<e.length-1){if(e[n]==="*"&&e[n+1]==="/"){n+=2;break}n++}continue}if(s===","){i=t.length,t+=s,n++;continue}if(s==="}"||s==="]"){if(i!==-1){let l=t.slice(i+1);if(/^\s*$/.test(l))t=t.slice(0,i)+l}i=-1,t+=s,n++;continue}if(!/\s/.test(s))i=-1;t+=s,n++}return t}function jr(e){if(!e?.includes("cc-safety-net"))return!1;return/(^|\s)hook\s+(?:[^\s]+\s+)*(--copilot-cli|-cp)(\s|$)/.test(e)}function da(e,t){if(!e)return null;let n=e.match(/(\d+)\.(\d+)\.(\d+)/);if(!n)return null;let r=[Number(n[1]),Number(n[2]),Number(n[3])];for(let o=0;o<t.length;o++){let i=r[o]??0,s=t[o]??0;if(i!==s)return i>s}return!0}function b2(e){return da(e,[0,0,422])}function w2(e){return da(e,[1,0,8])}function It(e){return process.env.COPILOT_HOME||M(e,".copilot")}function Ur(e){return(e.hooks?.preToolUse??[]).some((n)=>{if(n.type!=="command")return!1;return jr(n.command)||jr(n.bash)||jr(n.powershell)})}function pn(e){return e===void 0||typeof e==="string"}function k2(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e;if(t.disableAllHooks!==void 0&&typeof t.disableAllHooks!=="boolean")return!1;if(t.hooks===void 0)return!0;if(!t.hooks||typeof t.hooks!=="object"||Array.isArray(t.hooks))return!1;let n=t.hooks.preToolUse;if(n===void 0)return!0;return Array.isArray(n)&&n.every((r)=>r!==null&&typeof r==="object"&&!Array.isArray(r)&&pn(r.type)&&pn(r.command)&&pn(r.bash)&&pn(r.powershell))}function Gr(e,t){try{let n=JSON.parse(q(v2(e,"utf-8")));if(!k2(n)){t?.push(`Invalid hook config ${e}: hooks.preToolUse must be an array of hook objects`);return}return n}catch(n){t?.push(`Failed to parse ${e}: ${n instanceof Error?n.message:String(n)}`);return}}function ua(e,t){try{return L2(e).filter((n)=>n.endsWith(".json")).sort((n,r)=>n.localeCompare(r))}catch(n){return t?.push(`Failed to read ${e}: ${n instanceof Error?n.message:String(n)}`),[]}}function x2(e,t){if(!fn(e))return[];let n=[];for(let r of ua(e,t)){let o=M(e,r),i=Gr(o,t);if(i&&Ur(i))n.push(o)}return n}function st(e,t){if(!fn(e))return;let n=Gr(e,t);if(!n)return;return{path:e,config:n}}function ca(e,t,n,r){if(t){e.push(`GitHub Copilot CLI ${t} does not support ${n}; requires ${r}+`);return}e.push(`GitHub Copilot CLI version unavailable; skipping ${n} because it requires ${r}+`)}function C2(e){for(let t of e){if(t?.config.disableAllHooks===!0)return t.path;if(t?.config.disableAllHooks===!1)return}return}function S2(e,t,n,r){let o=It(e),i=M(t,".github","hooks"),s=M(o,"hooks"),a=M(t,".github","copilot"),l=M(t,".claude"),c=w2(n),d=c===!0?r:void 0,p=[st(M(a,"settings.local.json"),d),st(M(a,"settings.json"),d),st(M(l,"settings.local.json"),d),st(M(l,"settings.json"),d)],g=[st(M(o,"settings.json"),d),st(M(o,"config.json"),d)];if(c!==!1){let C=C2([...p,...g]);if(C){if(c===null)r.push(`GitHub Copilot CLI version unavailable; treating disableAllHooks in ${C} as active`);return{activeConfigPaths:[],disabledBy:C}}}let u=x2(i,r),m=b2(n),f=m===!0?r:void 0,L=fn(s)?ua(s,f):[],v=[];for(let C of L){let j=M(s,C),ye=Gr(j,f);if(ye&&Ur(ye))v.push(j)}if(m!==!0&&v.length>0)ca(r,n,`user hook files in ${s}`,"0.0.422"),v.length=0;let x=[];for(let C of[...p,...g]){if(!C)continue;if(!Ur(C.config))continue;if(c===!0){x.push(C);continue}ca(r,n,"inline hook definitions in Copilot config files","1.0.8");break}let y=(C)=>C.filter((j)=>!!j&&x.includes(j)).map((j)=>j.path);return{activeConfigPaths:[...y(p),...u,...y(g),...v]}}function pa(e){let t=[],n=S2(e.homeDir,e.cwd,e.copilotCliVersion,t);if(n.disabledBy)return{platform:"copilot-cli",status:"disabled",method:"hook config",configPath:n.disabledBy,configPaths:[n.disabledBy],errors:t.length>0?t:void 0};let r=It(e.homeDir),o=M(r,"installed-plugins",...dn),i=fn(o),s=M(r,"settings.json"),a=oe(s,q);if(i&&a.kind==="unreadable")return{platform:"copilot-cli",status:"not-inspected"};if(i&&a.kind==="ok"&&b(b(a.value,"enabledPlugins"),ie)===!1)return{platform:"copilot-cli",status:"disabled",method:"plugin config",configPath:s,errors:[`${ie} is installed but not enabled in Copilot CLI`]};if(i||n.activeConfigPaths.length>0){let l=i,c=n.activeConfigPaths[0];return{platform:"copilot-cli",status:"configured",method:l?"plugin config":"hook config",configPath:c??(l?o:void 0),configPaths:n.activeConfigPaths.length>0?n.activeConfigPaths:void 0,errors:t.length>0?t:void 0}}return{platform:"copilot-cli",status:"n/a",errors:t.length>0?t:void 0}}import{existsSync as $2,readFileSync as N2}from"node:fs";import{existsSync as fa,mkdirSync as A2,readFileSync as E2}from"node:fs";import{dirname as P2,join as T2}from"node:path";import{renameSync as D2,writeFileSync as R2}from"node:fs";function I(e,t){let n=`${e}.${process.pid}.tmp`;R2(n,t),D2(n,e)}var _t="npx -y cc-safety-net hook --cursor",ma=30;function gn(e){return T2(e,".cursor","hooks.json")}function Oe(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Br(){return{command:_t,timeout:ma,failClosed:!0}}function mn(e){return Oe(e)&&e.command===_t}function I2(e){return Object.keys(e).length===3&&e.command===_t&&e.timeout===ma&&e.failClosed===!0}function _2(e){try{return JSON.parse(E2(e,"utf-8"))}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Cursor hooks config ${e}: ${t.message}`);throw t}}function ga(e){let t=_2(e);if(!Oe(t))throw Error(`Cursor hooks config ${e} must be a JSON object`);if(t.version!==1)throw Error(`Cursor hooks config ${e} must set "version": 1`);if(t.hooks!==void 0&&!Oe(t.hooks))throw Error(`Cursor hooks config ${e} "hooks" must be an object`);let n=Oe(t.hooks)?t.hooks.preToolUse:void 0;if(n!==void 0&&!Array.isArray(n))throw Error(`Cursor hooks config ${e} "hooks.preToolUse" must be an array`);return t}function ha(e){let t=Oe(e.hooks)?e.hooks.preToolUse:void 0;return Array.isArray(t)?t:[]}function O2(e){if(!e.some(mn))return[...e,Br()];return e.reduce((t,n)=>{if(!mn(n))return t.result.push(n),t;if(!t.inserted)t.result.push(Br()),t.inserted=!0;return t},{result:[],inserted:!1}).result}function ya(e,t,n){let r=Oe(t.hooks)?t.hooks:{},o={...t,hooks:{...r,preToolUse:n}};I(e,`${JSON.stringify(o,null,2)}
30
+ `)}function La(e){let t=gn(e);if(!fa(t))return A2(P2(t),{recursive:!0}),I(t,`${JSON.stringify({version:1,hooks:{preToolUse:[Br()]}},null,2)}
31
+ `),{path:t,alreadyInstalled:!1};let n=ga(t),r=ha(n),o=r.filter(mn);if(Oe(n.hooks)&&Array.isArray(n.hooks.preToolUse)&&o.length===1&&o[0]!==void 0&&I2(o[0]))return{path:t,alreadyInstalled:!0};return ya(t,n,O2(r)),{path:t,alreadyInstalled:!1}}function va(e){let t=gn(e);if(!fa(t))return{path:t,alreadyInstalled:!1};let n=ga(t),r=ha(n),o=r.filter((i)=>!mn(i));if(o.length===r.length)return{path:t,alreadyInstalled:!1};return ya(t,n,o),{path:t,alreadyInstalled:!0}}function F2(e){if(!e||typeof e!=="object"||Array.isArray(e))return[];let t=e.hooks;if(!t||typeof t!=="object"||Array.isArray(t))return[];let n=t.preToolUse;if(!Array.isArray(n))return[];return n.filter((r)=>!!r&&typeof r==="object"&&!Array.isArray(r)&&r.command===_t)}function H2(e){let t=[];if(e.length>1)t.push("Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates");let n=e[0];if(n&&n.failClosed!==!0)t.push('Managed hook is missing "failClosed": true; reinstall to repair');if(n&&n.timeout!==30)t.push('Managed hook "timeout" is not 30; reinstall to repair');return t}function ba(e){let t=gn(e.homeDir);if(!$2(t))return{platform:"cursor",status:"n/a",configPath:t};let n;try{n=JSON.parse(N2(t,"utf-8"))}catch(i){return{platform:"cursor",status:"n/a",configPath:t,errors:[`Failed to parse Cursor hooks config ${t}: ${i instanceof Error?i.message:String(i)}`]}}let r=F2(n);if(r.length===0)return{platform:"cursor",status:"n/a",configPath:t};let o=H2(r);return{platform:"cursor",status:"configured",method:"hook config",configPath:t,errors:o.length>0?o:void 0}}import{existsSync as M2}from"node:fs";import{join as qr}from"node:path";var Vr="gemini-safety-net";function zr(e){let t=qr(e,".gemini","extensions"),n=qr(t,Vr);if(!M2(n))return{platform:"gemini-cli",status:"n/a"};let r=qr(t,"extension-enablement.json"),o=oe(r);if(o.kind==="unreadable")return{platform:"gemini-cli",status:"not-inspected"};let i=o.kind==="ok"?b(b(o.value,Vr),"overrides"):void 0;if(Array.isArray(i)&&i.some((a)=>typeof a==="string"&&a.startsWith("!")))return{platform:"gemini-cli",status:"disabled",method:"extension config",configPath:r,errors:[`${Vr} is disabled in Gemini CLI`]};return{platform:"gemini-cli",status:"configured",method:"extension config",configPath:n}}function wa(e){return zr(e.homeDir)}import{existsSync as B2,readFileSync as q2}from"node:fs";import{existsSync as xa,mkdirSync as j2,readFileSync as Ca,rmSync as U2}from"node:fs";import{dirname as G2,join as ka}from"node:path";var Ot="npx -y cc-safety-net hook --grok-build",Ln=30;function vn(e){return ka(process.env.GROK_HOME??ka(e,".grok"),"hooks","cc-safety-net.json")}function $e(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function hn(){return{hooks:[{type:"command",command:Ot,timeout:Ln}]}}function Sa(e){return $e(e)&&e.command===Ot}function Da(e){return e.flatMap((t)=>{if(!$e(t)||!Array.isArray(t.hooks))return[t];let n=t.hooks.filter((r)=>!Sa(r));if(n.length===t.hooks.length)return[t];return n.length===0?[]:[{...t,hooks:n}]})}function Ra(e){try{let t=JSON.parse(e);return $e(t)?t:null}catch{return null}}function Aa(e){let t=$e(e.hooks)?e.hooks.PreToolUse:void 0;return Array.isArray(t)?t:[]}function yn(e,t,n){let r=$e(t.hooks)?t.hooks:{};I(e,`${JSON.stringify({...t,hooks:{...r,PreToolUse:n}},null,2)}
32
+ `)}function Ea(e){let t=vn(e);if(!xa(t))return j2(G2(t),{recursive:!0}),yn(t,{},[hn()]),{path:t,alreadyInstalled:!1};let n=Ra(Ca(t,"utf-8"));if(!n)return yn(t,{},[hn()]),{path:t,alreadyInstalled:!1};let r=Aa(n),o=r.filter((i)=>$e(i)&&Array.isArray(i.hooks)&&i.hooks.some(Sa));if(o.length===1&&JSON.stringify(o[0])===JSON.stringify(hn()))return{path:t,alreadyInstalled:!0};return yn(t,n,[...Da(r),hn()]),{path:t,alreadyInstalled:!1}}function Pa(e){let t=vn(e);if(!xa(t))return{path:t,alreadyInstalled:!1};let n=Ra(Ca(t,"utf-8"));if(!n)return{path:t,alreadyInstalled:!1};let r=Aa(n),o=Da(r);if(JSON.stringify(o)===JSON.stringify(r))return{path:t,alreadyInstalled:!1};let i=$e(n.hooks)?n.hooks:{};if(o.length===0&&Object.keys(n).length===1&&Object.keys(i).length===1)return U2(t),{path:t,alreadyInstalled:!0};return yn(t,n,o),{path:t,alreadyInstalled:!0}}function $t(e){return!!e&&typeof e==="object"&&!Array.isArray(e)}function V2(e){if(!$t(e)||!$t(e.hooks))return[];let t=e.hooks.PreToolUse;if(!Array.isArray(t))return[];return t.filter((n)=>$t(n)&&Array.isArray(n.hooks)&&n.hooks.some((r)=>$t(r)&&r.command===Ot))}function z2(e){let n=(Array.isArray(e.hooks)?e.hooks.filter($t):[]).find((r)=>r.command===Ot);return[...e.matcher===void 0||e.matcher===""||e.matcher==="*"?[]:['Managed hook has a "matcher" that narrows coverage; reinstall to repair'],...n?.type==="command"?[]:['Managed hook "type" is not "command"; reinstall to repair'],...n?.timeout===Ln?[]:[`Managed hook "timeout" is not ${Ln}; reinstall to repair`]]}function Ta(e){let t=vn(e.homeDir);if(!B2(t))return{platform:"grok-build",status:"n/a",configPath:t};let n;try{n=JSON.parse(q2(t,"utf-8"))}catch(i){return{platform:"grok-build",status:"n/a",configPath:t,errors:[`Failed to parse Grok Build hooks config ${t}: ${i instanceof Error?i.message:String(i)}`]}}let r=V2(n)[0];if(!r)return{platform:"grok-build",status:"n/a",configPath:t};let o=z2(r);return{platform:"grok-build",status:"configured",method:"hook config",configPath:t,errors:o.length>0?o:void 0}}import{readFileSync as ja}from"node:fs";import{join as Ua}from"node:path";var K="cc-safety-net",Ia="# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent";function _a(e){return`# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent
32
33
  # version: ${e}
33
- `}function y2(e){return`${ga(e)}name: cc-safety-net
34
+ `}function K2(e){return`${_a(e)}name: cc-safety-net
34
35
  version: "${e}"
35
36
  description: "Block destructive commands and secret-file access before Hermes runs a tool."
36
37
  author: "cc-safety-net"
37
38
  provides_hooks:
38
39
  - pre_tool_call
39
- `}function L2(e){return`${ga(e)}"""CC Safety Net guard for Hermes Agent.
40
+ `}function W2(e){return`${_a(e)}"""CC Safety Net guard for Hermes Agent.
40
41
 
41
42
  Registers pre_tool_call and forwards the tool call to the packaged CC Safety Net
42
43
  adapter (cc-safety-net hook --hermes-agent) over JSON stdin. The adapter prints nothing
@@ -174,86 +175,86 @@ def _pre_tool_call(tool_name="", args=None, session_id="", task_id="", **_):
174
175
 
175
176
  def register(ctx):
176
177
  ctx.register_hook("pre_tool_call", _pre_tool_call)
177
- `}function _t(e){return[{name:"__init__.py",content:L2(e)},{name:"plugin.yaml",content:y2(e)}]}import{mkdirSync as v2,readdirSync as b2,readFileSync as w2,rmSync as jr}from"node:fs";import{join as Oe}from"node:path";var x2="__pycache__";function Ur(e){let t=process.env.HERMES_HOME?.trim();return t?t:Oe(e,".hermes")}function Gr(e){return Oe(Ur(e),"plugins",z)}function Br(e){return e.startsWith(ma)}function qr(e,t){let n=Gr(e),r=E(n);if(r&&(r.isSymbolicLink()||!r.isDirectory()))throw Error(`Refusing to ${t} ${n}: not a regular directory. Move or remove it and rerun ${t==="install"?"install":"uninstall"} --hermes-agent.`);return n}function ha(e,t){let n=E(e);if(!n)return;if(n.isSymbolicLink()||!n.isFile())throw Error(`Refusing to ${t} ${e}: not a regular file. Move or remove it.`);let r=w2(e,"utf-8");if(!Br(r))throw Error(`Refusing to ${t} unmanaged file at ${e}. Move or remove it.`);return r}function ya(e){let t=qr(e,"install"),n=_t(P());if(n.map((o)=>ha(Oe(t,o.name),"overwrite")).every((o,i)=>o===n[i]?.content))return{path:t,alreadyInstalled:!0};return v2(t,{recursive:!0}),n.forEach((o)=>{_(Oe(t,o.name),o.content)}),{path:t,alreadyInstalled:!1}}function Vr(e){let t=qr(e,"remove");if(!E(t))return[];return _t(P()).filter((n)=>ha(Oe(t,n.name),"remove")!==void 0)}function La(e){let t=qr(e,"remove");if(!E(t))return{path:t,alreadyInstalled:!1};let n=Vr(e);if(n.forEach((r)=>{jr(Oe(t,r.name))}),jr(Oe(t,x2),{recursive:!0,force:!0}),b2(t).length===0)jr(t,{recursive:!0});return{path:t,alreadyInstalled:n.length>0}}var fn="hermes-agent",va=/^([^\s#][^:]*):/,k2=/^\s+([A-Za-z_][\w-]*):/,ba=/^\s+-\s*(.*)$/;function C2(e){return e.trim().replace(/^(["'])(.*)\1$/,"$2")}function S2(e){let t=e.split(/\r?\n/),n=t.findIndex((i)=>va.exec(i)?.[1]?.trim()==="plugins");if(n===-1)return[];let r=t.slice(n+1),o=r.findIndex((i)=>va.test(i));return o===-1?r:r.slice(0,o)}function wa(e,t){let n=S2(e),r=n.findIndex((s)=>k2.exec(s)?.[1]===t);if(r===-1)return[];let o=n.slice(r+1),i=o.findIndex((s)=>!ba.test(s));return(i===-1?o:o.slice(0,i)).map((s)=>C2(ba.exec(s)?.[1]??""))}function D2(e){try{return xa(ka(Ur(e),"config.yaml"),"utf-8")}catch{return}}function zr(e){let t=D2(e)??"";return wa(t,"enabled").includes(z)&&!wa(t,"disabled").includes(z)}function Ca(e){return/^# version:\s*(.+)$/m.exec(e)?.[1]?.trim()}function R2(e,t){let n=E(e);if(!n)return{error:`${t.name} is missing from ${e}; run install --hermes-agent`};if(n.isSymbolicLink()||!n.isFile())return{error:`${e} is a symlink or not a regular file; move or remove it`};try{let r=xa(e,"utf-8");if(!Br(r))return{error:`Unmanaged ${t.name} occupies ${e}; move or remove it`};if(Ca(r)===P()&&r!==t.content)return{error:`Modified ${t.name} occupies ${e}; run install --hermes-agent to restore it`};return{content:r}}catch(r){return{error:`Failed to read ${e}: ${r instanceof Error?r.message:String(r)}`}}}function Sa(e){let t=Gr(e.homeDir),n=on(fn,t);if(n)return n;let r=_t(P()).map((a)=>R2(ka(t,a.name),a)),o=r.flatMap((a)=>("error"in a)?[a.error]:[]);if(o.length>0)return{platform:fn,status:"n/a",configPath:t,errors:o};let i=r.some((a)=>("content"in a)&&Ca(a.content)!==P()),s=i?["Installed Hermes Agent plugin is outdated; run install --hermes-agent to update"]:[];if(!zr(e.homeDir))return{platform:fn,status:"disabled",method:"plugin directory",configPath:t,errors:[`${z} is not enabled in Hermes; run \`hermes plugins enable ${z}\``,...s]};return{platform:fn,status:"configured",method:"plugin directory",configPath:t,errors:i?s:void 0}}import{existsSync as A2,readFileSync as E2}from"node:fs";import{join as Da}from"node:path";var P2=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*--kimi-code(\s|["']|$)/;function T2(e){return Da(process.env.KIMI_CODE_HOME||Da(e,".kimi-code"),"config.toml")}function Ot(e){let t=T2(e.homeDir);if(!A2(t))return{platform:"kimi-code",status:"n/a",configPath:t};try{if(!P2.test(E2(t,"utf-8")))return{platform:"kimi-code",status:"n/a",configPath:t}}catch(n){return{platform:"kimi-code",status:"n/a",configPath:t,errors:[`Failed to read ${t}: ${n instanceof Error?n.message:String(n)}`]}}return{platform:"kimi-code",status:"configured",method:"hook config",configPath:t}}import{readFileSync as Na}from"node:fs";import{join as Nt}from"node:path";var A="cc-safety-net",K="index.js",it="openclaw.plugin.json",st="package.json";var mn="// cc-safety-net managed OpenClaw plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --openclaw";import{existsSync as O2,lstatSync as $2,readdirSync as N2,readFileSync as F2}from"node:fs";import{dirname as Ea,join as be}from"node:path";import{fileURLToPath as H2}from"node:url";import{spawn as I2}from"node:child_process";function _2(e){return e.join(" ")}function Kr(e,t,n){return[`Failed to run ${_2(e)}${t===null?"":` (exit ${t})`}.`,n.trim()].filter(Boolean).join(`
178
- `)}function Wr(e){let t={stdout:"",stderr:""};return e.stdout.setEncoding("utf-8"),e.stderr.setEncoding("utf-8"),e.stdout.on("data",(n)=>{t.stdout+=n}),e.stderr.on("data",(n)=>{t.stderr+=n}),t}function ie(e,t){return new Promise((n,r)=>{let o=Ie([...e],process.env),i=I2(o.cmd,o.args,{stdio:["ignore","pipe","pipe"]}),s=Wr(i),a=()=>[s.stdout,s.stderr].filter(Boolean).join(`
179
- `),l=t?.timeoutMs??120000,c=setTimeout(()=>{i.kill(),r(Error(Kr(e,null,`Timed out after ${l}ms.
180
- ${a()}`.trim())))},l);i.on("error",(d)=>{clearTimeout(c),r(Error(Kr(e,null,`${d.message}
181
- ${a()}`.trim())))}),i.on("close",(d)=>{if(clearTimeout(c),d!==0){r(Error(Kr(e,d,a())));return}n(t?.stdoutOnly?s.stdout:a())})})}async function Jr(e){for(let t of e)await ie(t)}async function Ra(e){for(let t of e)try{await ie(t)}catch(n){console.warn(n instanceof Error?n.message:String(n))}}var Aa=be("openclaw",A),M2=[K,it,st];function Yr(e,t){if(e==="~")return t;if(e.startsWith("~/")||e.startsWith("~\\"))return be(t,e.slice(2));return e}function Pa(e){let t=process.env.OPENCLAW_STATE_DIR?.trim();if(t)return Yr(t,e);let n=process.env.OPENCLAW_CONFIG_PATH?.trim();return n?Ea(Yr(n,e)):be(e,".openclaw")}function Ta(e){let t=process.env.OPENCLAW_CONFIG_PATH?.trim();return t?Yr(t,e):be(Pa(e),"openclaw.json")}function Zr(e){return be(Pa(e),"extensions",A)}function j2(e){let t=N2(e);if(t.length===0)return!0;if(t.some((o)=>!M2.includes(o)))return!1;let n=be(e,K),r=E(n);return r!==void 0&&!r.isSymbolicLink()&&r.isFile()&&F2(n,"utf-8").startsWith(mn)}function Xr(e){let t=Zr(e),n=E(t);if(!n)return;if(!n.isSymbolicLink()&&n.isDirectory()&&j2(t))return;throw Error(`Refusing to modify ${t}: it does not hold a cc-safety-net managed OpenClaw plugin. Move or remove it, then run the command again.`)}function Ia(){let e=Ea(H2(import.meta.url));return[be(e,"..",Aa),be(e,"..","..","..","dist",Aa)]}function Qr(e=Ia()){return e.find((t)=>O2(t)&&$2(t).isDirectory())}function U2(e=Ia()){let t=Qr(e);if(!t)throw Error("Packaged OpenClaw plugin directory not found. Reinstall cc-safety-net and try again.");return t}function _a(e=U2()){return[["openclaw","plugins","install",e,"--force"],["openclaw","plugins","enable",A]]}function G2(e){let t=(()=>{try{return JSON.parse(e)}catch{return}})(),n=b(b(t,"plugin"),"status");return typeof n==="string"?n:void 0}async function Oa(){let e=G2(await ie(["openclaw","plugins","inspect",A,"--runtime","--json"],{stdoutOnly:!0}));if(e==="loaded")return;throw Error(`${e===void 0?`The ${A} plugin's load state could not be verified: OpenClaw's runtime inspect report was unreadable.`:`OpenClaw reports the ${A} plugin with status "${e}".`} Run \`openclaw plugins inspect ${A} --runtime\` for details.`)}var gn="openclaw",$t=`run \`openclaw plugins enable ${A}\``;function at(e,t){let n=Nt(e,t),r=E(n);if(!r)return{error:`${t} is missing from ${n}; run install --openclaw`};if(r.isSymbolicLink()||!r.isFile())return{error:`${n} is a symlink or not a regular file; move or remove it`};try{return{content:Na(n,"utf-8")}}catch(o){return{error:`Failed to read ${n}: ${o instanceof Error?o.message:String(o)}`}}}function Fa(e){try{return JSON.parse(q(e))}catch{return}}function B2(e){let t=at(e,it);if("error"in t)return t.error;if(b(Fa(t.content),"id")===A)return;return`${Nt(e,it)} is not a valid ${A} manifest; run install --openclaw`}function q2(e){let t=at(e,st);if("error"in t)return t.error;let n=b(b(Fa(t.content),"openclaw"),"extensions");if(Array.isArray(n)&&n.includes(`./${K}`))return;return`${Nt(e,st)} does not point OpenClaw at ${K}; run install --openclaw`}function $a(e){return Array.isArray(e)?e.filter((t)=>typeof t==="string"):[]}function V2(e){let t=Ta(e);if(!E(t))return`${A} is not enabled; ${$t}`;let n=(()=>{try{return JSON.parse(q(Na(t,"utf-8")))}catch{return}})();if(n===void 0)return`Failed to read ${t}; fix it, then ${$t}`;let r=b(n,"plugins");if(b(r,"enabled")===!1)return`plugins.enabled is false in ${t}; no OpenClaw plugin loads`;let o=b(b(b(r,"entries"),A),"enabled");if($a(b(r,"deny")).includes(A)||o===!1)return`${A} is disabled in ${t}; ${$t}`;let i=$a(b(r,"allow"));if(i.length>0&&!i.includes(A))return`plugins.allow in ${t} does not list ${A}; add it, then ${$t}`;if(i.includes(A)||o===!0)return;return`${A} is not enabled; ${$t}`}function Ha(e){return/^\/\/ version:\s*(.+)$/m.exec(e)?.[1]?.trim()}function z2(e,t,n){if(n===void 0)return[];let r=at(n,K);if("error"in r||Ha(r.content)!==t)return[];return[K,it,st].flatMap((o)=>{let i=at(e,o),s=at(n,o);if("error"in i||"error"in s||i.content===s.content)return[];return[`Modified ${o} occupies ${Nt(e,o)}; run install --openclaw to restore it`]})}function Ma(e){let t=Zr(e.homeDir),n=on(gn,t);if(n)return n;let r=at(t,K),i=["error"in r?r.error:r.content.startsWith(mn)?void 0:`Unmanaged ${K} occupies ${Nt(t,K)}; move or remove it`,B2(t),q2(t)].filter((d)=>d!==void 0),s="content"in r?Ha(r.content):void 0,a=i.length>0?i:z2(t,s,Qr());if(a.length>0)return{platform:gn,status:"n/a",configPath:t,errors:a};let l=s===P()?[]:["Installed OpenClaw plugin is outdated; run install --openclaw to update"],c=V2(e.homeDir);if(c)return{platform:gn,status:"disabled",method:"plugin directory",configPath:t,errors:[c,...l]};return{platform:gn,status:"configured",method:"plugin directory",configPath:t,errors:l.length>0?l:void 0}}import{existsSync as rf,readFileSync as of}from"node:fs";import{join as sf}from"node:path";import{existsSync as eo,readFileSync as qa,rmSync as W2}from"node:fs";import{join as me}from"node:path";import{pathToFileURL as J2}from"node:url";function ja(e){return e!==void 0&&/\s/.test(e)}function K2(e,t,n){let r=t+1,o=!1;while(r<e.length){let i=e[r];if(o){o=!1,r++;continue}if(i==="\\"){o=!0,r++;continue}if(i==='"')return r+1;r++}throw Error(n)}function hn(e,t,n){let r=e[t],o=r==="["?"]":"}",i=0,s=t;while(s<e.length){let a=n.skipComment?.(e,s)??s;if(a!==s){s=a;continue}if(e[s]==='"'){s=K2(e,s,n.stringError);continue}if(e[s]===r)i++;if(e[s]===o){if(i--,i===0)return s}s++}throw Error(n.bracketError)}function Ua(e,t){let n=e.lastIndexOf(`
182
- `,t)+1;return/^[ \t]*/.exec(e.slice(n))?.[0]??""}function yn(e,t){let{start:n,end:r,end:o}=t;while(ja(e[o]))o++;if(e[o]===","){if(r=o+1,e[r]===`
183
- `)r++;return`${e.slice(0,n)}${e.slice(r)}`}o=t.start-1;while(ja(e[o]))o--;if(e[o]===","){n=o;let i=e.lastIndexOf(`
184
- `,n-1);if(i!==-1&&/^\s*$/.test(e.slice(i+1,n)))n=i}return`${e.slice(0,n)}${e.slice(r)}`}var Ln="cc-safety-net",Va=`${Ln}@latest`,za=["opencode.json","opencode.jsonc"],Ga="CCSafetyNetPlugin";function vn(e){return me(process.env.XDG_CONFIG_HOME||me(e,".config"),"opencode")}function Y2(e){return me(vn(e),za[0])}function Z2(e){return za.map((t)=>me(vn(e),t))}function Ka(e){return me(process.env.XDG_CACHE_HOME||me(e,".cache"),"opencode","packages",Va)}function to(e){W2(Ka(e),{recursive:!0,force:!0})}async function Wa(e){let t=me(Ka(e),"node_modules",Ln),n=me(t,"package.json");if(!eo(n))throw Error(`The OpenCode plugin cache at ${t} is missing its package, so OpenCode would load nothing and fail open. Run \`opencode plugin -g -f ${Va}\` for details.`);let r=b(JSON.parse(qa(n,"utf-8")),"main");if(typeof r!=="string")throw Error(`The cached OpenCode plugin at ${t} declares no "main" entry.`);let o=me(t,r);if(typeof(await import(J2(o).href))[Ga]==="function")return;throw Error(`The cached OpenCode plugin at ${o} does not export a callable ${Ga}, so OpenCode would load nothing and fail open.`)}function bn(e,t){if(e[t]==="/"&&e[t+1]==="/"){let n=e.indexOf(`
185
- `,t+2);return n===-1?e.length:n+1}if(e[t]==="/"&&e[t+1]==="*"){let n=e.indexOf("*/",t+2);return n===-1?e.length:n+2}return t}function Ba(e,t){let n=t;while(n<e.length){if(/\s/.test(e[n]??"")){n++;continue}let r=bn(e,n);if(r===n)return n;n=r}return n}function Ja(e,t){let n=t+1,r=!1;while(n<e.length){if(r){r=!1,n++;continue}if(e[n]==="\\"){r=!0,n++;continue}if(e[n]==='"')return n+1;n++}throw Error("Unterminated string in OpenCode config")}function Ya(e,t,n){return JSON.parse(e.slice(t,n))}function X2(e,t){return hn(e,t,{skipComment:bn,stringError:"Unterminated string in OpenCode config",bracketError:"Unmatched plugin array in OpenCode config"})}function Q2(e){let t=0,n=0;while(n<e.length){let r=bn(e,n);if(r!==n){n=r;continue}if(e[n]==='"'){let o=Ja(e,n);if(t===1&&Ya(e,n,o)==="plugin"){let i=Ba(e,o),s=Ba(e,i+1);if(e[i]===":"&&e[s]==="[")return{start:s,end:X2(e,s)}}n=o;continue}if(e[n]==="{"||e[n]==="[")t++;if(e[n]==="}"||e[n]==="]")t--;n++}return}function ef(e,t){let n=[],r=t.start+1;while(r<t.end){let o=bn(e,r);if(o!==r){r=o;continue}if(e[r]==='"'){let i=Ja(e,r),s=Ya(e,r,i);if(typeof s==="string"&&s.includes(Ln))n.push({start:r,end:i});r=i;continue}r++}return n}function Za(e,t){try{return JSON.parse(q(e))}catch(n){if(n instanceof SyntaxError)throw Error(`Failed to parse OpenCode config ${t}: ${n.message}`);throw n}}function tf(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e.plugin;if(!Array.isArray(t))return!1;return t.some((n)=>typeof n==="string"&&n.includes(Ln))}function nf(e,t){let n=Q2(e);if(!n)throw Error(`Failed to locate OpenCode plugin array in ${t}`);let r=[...ef(e,n)].reverse().reduce(yn,e);return Za(r,t),r}function Xa(e){to(e);let t=Z2(e),n=t.find((o)=>eo(o)),r=[];for(let o of t){if(!eo(o))continue;try{let i=qa(o,"utf-8");if(!tf(Za(i,o)))continue;return _(o,nf(i,o)),{path:o,alreadyInstalled:!0}}catch(i){r.push(i instanceof Error?i.message:String(i))}}if(r.length>0)throw Error(r.join(`
186
- `));return{path:n??Y2(e),alreadyInstalled:!1}}function Qa(e){let t=[],n=vn(e.homeDir),r=["opencode.json","opencode.jsonc"];for(let o of r){let i=sf(n,o);if(rf(i))try{let s=of(i,"utf-8"),a=q(s);if((JSON.parse(a).plugin??[]).some((p)=>p.includes("cc-safety-net")))return{platform:"opencode",status:"configured",method:"plugin array",configPath:i,errors:t.length>0?t:void 0}}catch(s){t.push(`Failed to parse ${o}: ${s instanceof Error?s.message:String(s)}`)}}return{platform:"opencode",status:"n/a",errors:t.length>0?t:void 0}}import{join as af}from"node:path";function no(e){return af(e,".pi","agent","settings.json")}function ro(e){if(typeof e!=="string")return!1;return e==="npm:cc-safety-net"||e.startsWith("npm:cc-safety-net@")}function el(e){let t=no(e.homeDir),n=re(t);if(n.kind==="unreadable")return{platform:"pi",status:"not-inspected"};if(n.kind==="missing")return{platform:"pi",status:"n/a"};let r=b(n.value,"packages");if(!Array.isArray(r))return{platform:"pi",status:"n/a"};let o=r.find((a)=>ro(typeof a==="string"?a:b(a,"source")));if(o===void 0)return{platform:"pi",status:"n/a"};let i=b(o,"extensions");if(Array.isArray(i)&&i.some((a)=>typeof a==="string"&&a.startsWith("-")))return{platform:"pi",status:"disabled",method:"package config",configPath:t,errors:["npm:cc-safety-net is installed but its extension is disabled in Pi settings"]};return{platform:"pi",status:"configured",method:"package config",configPath:t}}var cf={amp:Us,"antigravity-cli":Gs,"claude-code":zs,codex:Ks,"copilot-cli":oa,cursor:pa,"gemini-cli":fa,"hermes-agent":Sa,"kimi-code":Ot,openclaw:Ma,opencode:Qa,pi:el};function lt(e,t){let n={...t,cwd:e,homeDir:t?.homeDir??lf()};return Jt.map((r)=>df(cf[r](n)))}function df(e){if(e.status==="not-inspected")return{platform:e.platform,detected:!1,configured:!1,inspectionStatus:"not-inspected"};return{platform:e.platform,detected:e.status!=="n/a",configured:e.status==="configured",inspectionStatus:e.status!=="n/a"?"verified":e.errors&&e.errors.length>0?"failed":"not-applicable",method:e.method,configPath:e.configPath,configPaths:e.configPaths,errors:e.errors}}import{tmpdir as uf}from"node:os";import{join as pf}from"node:path";var ff=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}]),mf=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([])})})}),gf={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 e=pf(uf(),"cc-safety-net-self-test"),t=ff.map((n)=>{let r=Kt(Ze("self-test",{command:n.command},{kind:"command",shell:"auto"},{configCwd:e,executionCwd:e},n.command),{guard:{dependencies:{loadPolicySnapshot:()=>mf,getModes:()=>gf,findPolicyMutation:()=>null}},audit:{agent:"self-test",getSessionId:()=>{return}}}),o=n.expectBlocked?"blocked":"allowed",i=r.decision.kind==="deny"?"blocked":"allowed";return{command:n.command,description:n.description,expected:o,actual:i,passed:o===i,reason:r.decision.kind==="deny"?r.decision.reason:void 0,ruleId:r.decision.kind==="deny"?r.decision.ruleId:void 0}});return{passed:t.filter((n)=>n.passed).length,failed:t.filter((n)=>!n.passed).length,total:t.length,results:t}}function oo(e){let t=T({label:"doctor",booleans:{json:["--json"],skipUpdateCheck:["--skip-update-check"]}},e);if(ae(t.errors))return null;return{json:t.flags.json,skipUpdateCheck:t.flags.skipUpdateCheck}}async function nl(e={}){let t=await Pt(!e.json,()=>{let n=hf(e);return{ready:n,finish:()=>n}},()=>Et(),{loadingMessage:"Checking system status…"});if(e.json)console.log(JSON.stringify(t,null,2));else yf(t);return t.engineSelfTest.failed>0||t.findings.some((n)=>n.severity==="error")?1:0}async function hf(e){let t=e.cwd??process.cwd(),n=await Rt(),r=lt(t,{ampPluginListOutput:n.ampPluginListOutput,codexPluginListOutput:n.codexPluginListOutput,copilotCliVersion:n.versions["copilot-cli"]}),o=us(t),i=ps(),s=B({cwd:t}),a=s.policy,l=de(a),c=Ae(a,l.capabilities),d=Xt(7),p=e.skipUpdateCheck?{currentVersion:P(),latestVersion:null,updateAvailable:!1}:await ve(),g={hooks:r,engineSelfTest:tl(),userConfig:o.userConfig,projectConfig:o.projectConfig,configState:xt(s),effectiveRules:o.effectiveRules,shadowedRules:o.shadowedRules,environment:i,effectiveSafety:{selectedPreset:a.safety.level??"standard",level:l.effectiveLevel,capabilities:l.capabilities,ruleOverrides:a.destructiveCommandRuleOverrides,weakenedRuleOverrides:Object.entries(c).filter(([,u])=>u.source==="rule_override"&&u.override==="off"&&u.inheritedEnabled&&u.changesInherited).map(([u])=>u),ruleCounts:{stored:Object.keys(a.destructiveCommandRuleOverrides).length,effective:Object.values(c).filter((u)=>u.changesInherited).length}},posture:Ds(o.userConfig.path),activity:d,update:p,system:n};return{...g,findings:ms(g)}}function yf(e){console.log(),console.log(hs(e.hooks)),console.log(),console.log(ys(e.engineSelfTest)),console.log(),console.log(Ls(e)),console.log(),console.log(vs(e.environment)),console.log(),console.log(bs(e)),console.log(),console.log(ws(e.findings)),console.log(),console.log(xs(e.activity)),console.log(),console.log(Cs(e.system)),console.log(),console.log(ks(e.update)),console.log(Ss(e))}import{existsSync as Lf}from"node:fs";var vf=/^[A-Za-z0-9_@%+=:,./-]+$/,rl="Usage: cc-safety-net explain [--json] [--cwd <path>] <command>";function io(e){let t=T({label:"explain",booleans:{json:["--json"]},values:{cwd:["--cwd"]},positionals:"tail"},e);if(ae(t.errors))return console.error(rl),console.error("Pass -- before a command that starts with dashes."),null;if(t.values.cwd!==void 0&&!Lf(t.values.cwd))return console.error(`Error: --cwd path does not exist: ${t.values.cwd}`),null;let n=t.positionals.length===1?t.positionals[0]:t.positionals.map((r)=>vf.test(r)?r:`'${r.replaceAll("'","'\\''")}'`).join(" ");if(!n)return console.error("Error: No command provided"),console.error(rl),null;return{json:t.flags.json,cwd:t.values.cwd,command:n}}function ol(e){if(e)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 il(e,t){let r=t-18;return[`${e.dtl}${e.dh.repeat(t)}${e.dtr}`,`${e.dv} Command Analysis${" ".repeat(r)}${e.dv}`,`${e.dbl}${e.dh.repeat(t)}${e.dbr}`]}function so(e){return JSON.stringify(e)}function sl(e,t=0){return`[${e.map((r,o)=>gs(r,o,t)).join(",")}]`}function wn(e,t,n=70){let r=e.split(" "),o=[],i="";for(let s of r)if(i&&i.length+s.length+1>n)o.push(i),i=s;else i=i?`${i} ${s}`:s;if(i)o.push(i);return o.map((s,a)=>a===0?s:`${t}${s}`)}function al(e,t,n){let r=[];switch(e.type){case"parse":return null;case"env-strip":return r.push(""),r.push(`STEP ${t} ${n.h} Strip environment variables`),r.push(` Removed: ${e.envVars.map((o)=>`${o}=<redacted>`).join(", ")}`),r.push(` Tokens: ${so(e.output)}`),{lines:r,incrementStep:!0};case"leading-tokens-stripped":return r.push(""),r.push(`STEP ${t} ${n.h} Strip wrappers`),r.push(` Removed: ${e.removed.join(", ")}`),r.push(` Tokens: ${so(e.output)}`),{lines:r,incrementStep:!0};case"shell-wrapper":return r.push(""),r.push(`STEP ${t} ${n.h} Detect shell wrapper`),r.push(` Wrapper: ${e.wrapper} -c`),r.push(` Inner: ${e.innerCommand}`),{lines:r,incrementStep:!0};case"interpreter":{if(r.push(""),r.push(`STEP ${t} ${n.h} Detect interpreter`),r.push(` Interpreter: ${e.interpreter}`),r.push(` Code: ${e.codeArg}`),e.paranoidBlocked)r.push(" Result: ✗ BLOCKED (paranoid mode)");return{lines:r,incrementStep:!0}}case"busybox":return r.push(""),r.push(`STEP ${t} ${n.h} Busybox wrapper`),r.push(` Subcommand: ${e.subcommand}`),{lines:r,incrementStep:!0};case"transparent-wrapper":return r.push(""),r.push(`STEP ${t} ${n.h} Transparent wrapper`),r.push(` Wrapper: ${e.wrapper}`),r.push(` Tokens: ${so(e.output)}`),{lines:r,incrementStep:!0};case"recurse":return{lines:[],incrementStep:!1};case"rule-check":{if(r.push(""),r.push(`STEP ${t} ${n.h} Match rules`),r.push(` Rule: ${e.rule}()`),e.matched)r.push(" Result: MATCHED");else r.push(" Result: No match");return{lines:r,incrementStep:!0}}case"worktree-relaxation":return r.push(""),r.push(`STEP ${t} ${n.h} Worktree relaxation`),r.push(` Mode: ${S.worktree.name}`),r.push(` Git cwd: ${e.gitCwd}`),r.push(" Result: Allowed local discard in linked worktree"),{lines:r,incrementStep:!0};case"tmpdir-check":return null;case"fallback-scan":{if(e.embeddedCommandFound)return r.push(""),r.push(`STEP ${t} ${n.h} Fallback scan`),r.push(` Found: ${e.embeddedCommandFound}`),{lines:r,incrementStep:!0};return null}case"custom-rules-check":{if(e.rulesChecked){if(r.push(""),r.push(`STEP ${t} ${n.h} Custom rules`),e.matched)r.push(" Result: MATCHED");else r.push(" Result: No match");return{lines:r,incrementStep:!0}}return null}case"cwd-change":return null;case"dangerous-text":{if(e.matched)return r.push(""),r.push(`STEP ${t} ${n.h} Dangerous text check`),r.push(` Token: ${e.token}`),r.push(" Result: MATCHED"),{lines:r,incrementStep:!0};return null}case"strict-unparseable":return r.push(""),r.push(`STEP ${t} ${n.h} Strict mode check`),r.push(` Command: ${e.rawCommand}`),r.push(" Result: ✗ UNPARSEABLE"),{lines:r,incrementStep:!0};case"segment-skipped":return null;case"error":return r.push(""),r.push(`ERROR: ${e.message}`),{lines:r,incrementStep:!1};default:return e}}function ao(e,t){let n=ol(t?.asciiOnly??!1),r=58,o=[],i=1;o.push(...il(n,58)),o.push("");let s=e.trace.steps.find((u)=>u.type==="error");if(s&&s.type==="error"){o.push("ERROR"),o.push(` ${s.message}`),o.push(""),o.push("RESULT"),o.push(` Status: ${e.result==="blocked"?h.red("BLOCKED"):h.green("ALLOWED")}`),o.push(""),o.push("CONFIG");let u=e.configSource??"none";return o.push(` Path: ${u}`),o.join(`
187
- `)}let a=e.trace.steps.find((u)=>u.type==="parse");if(a&&a.type==="parse"){o.push("INPUT"),o.push(` ${a.input}`),o.push(""),o.push(`STEP ${i} ${n.h} Split shell commands`),i++;for(let u=0;u<a.segments.length;u++){let m=a.segments[u];if(m){let f=Math.random();o.push(` Segment ${u+1}: ${sl(m,f)}`)}}}let l=e.trace.segments,c=l.length>1;for(let u of l){if(c){o.push("");let v="";if(a&&a.type==="parse"){let jn=a.segments[u.index];if(jn)v=jn.join(" ")}let k=54,y=v,C=` Segment ${u.index+1}: `,H=" ";if(v){if(C.length+v.length+H.length>k){let Yc=k-C.length-H.length;y=`${v.substring(0,Yc-1)}…`}}let he=v?`${C}${y}${H}`:` Segment ${u.index+1} `,Mn=v?`${C}${h.cyan(y)}${H}`:he,Io=58-he.length,_o=Math.floor(Io/2),Jc=Io-_o;o.push(`${n.sh.repeat(_o)}${Mn}${n.sh.repeat(Jc)}`)}if(u.steps.find((v)=>v.type==="segment-skipped")){o.push(""),o.push(" (skipped — prior segment blocked)");continue}let f=!1,L=!1;for(let v of u.steps){let k=al(v,i,n);if(k){if(L=!0,v.type==="recurse"){o.push("");let y=" RECURSING ",C=58-y.length-4;o.push(` ${n.tl}${n.h}${y}${n.h.repeat(C)}`),o.push(` ${n.v}`),f=!0;continue}for(let y of k.lines)if(f)o.push(` ${n.v} ${y}`);else o.push(y);if(k.incrementStep)i++}}if(f)o.push(` ${n.v}`),o.push(` ${n.bl}${n.h.repeat(56)}`),f=!1;if(!L)o.push(""),o.push(` ${h.green("✓")} Allowed (no matching rules)`)}if(o.push(""),o.push("RESULT"),e.result==="blocked"){if(o.push(` Status: ${h.red("BLOCKED")}`),e.customRule){if(o.push(` Rule: ${e.customRule.id}`),e.customRule.rulebook)o.push(` Rulebook: ${e.customRule.rulebook.name} ${e.customRule.rulebook.version}`);if(e.customRule.source)o.push(` Source: ${e.customRule.source}`);if(e.customRule.override)o.push(` Override: reason ${e.customRule.override.reason}`)}if(e.reason){let u=wn(e.reason," ");o.push(` Reason: ${u[0]}`);for(let m=1;m<u.length;m++)o.push(u[m]??"")}}else o.push(` Status: ${h.green("ALLOWED")}`);o.push(""),o.push("CONFIG");let d=e.configSource??"none",p=e.configValid?"":" (invalid)";o.push(` Path: ${d}${p}`),o.push(` Safety preset: ${e.selectedPreset??"standard"}`),o.push(` Effective capabilities: ${e.effectiveLevel}`);let g=Object.entries(e.destructiveCommandRuleOverrides??{});if(o.push(` Rule customizations: ${g.length}`),e.ruleActivation)o.push(` Rule activation: ${e.ruleActivation.id} — ${e.ruleActivation.enabled?"on":"off"} via ${e.ruleActivation.source}`);return o.join(`
188
- `)}function lo(e){return JSON.stringify(e,null,2)}function ll(e){return new Promise((t)=>{process.stdout.write(`${e}
189
- `,()=>t())})}async function cl(e){let t=io(e);if(!t)return 1;try{let n=Xe(t.command,{cwd:t.cwd}),r=!!process.env.NO_COLOR||!process.stdout.isTTY;return await ll(t.json?lo(n):ao(n,{asciiOnly:r})),0}catch(n){if(!(n instanceof dr)&&!(n instanceof Re)&&!(n instanceof pe))throw n;if(t.json)return await ll(JSON.stringify({error:n.message})),1;return console.error(n.message),1}}var dl="2.1.1",W=" ",$e="cc-safety-net";function ul(e){return e.argument?`${e.flags} ${e.argument}`:e.flags}function bf(e){return Math.max(...e.map((t)=>ul(t).length))}function wf(e){return Math.max(...e.map((t)=>t.usage.length))}function xf(e){return Math.max(...e.map((t)=>`${$e} ${t.usage}`.length))}function kf(e,t){let n=`${$e} ${e.usage}`;return`${W}${n.padEnd(t+2)}${e.description}`}function ge(e,t){return`${W}${e.padEnd(Math.max(40,e.length+2))}${t}`}function xn(e,t=console.log){let n=[];if(n.push(`${$e} ${e.name}`),n.push(""),n.push(`${W}${e.description}`),n.push(""),n.push("USAGE:"),n.push(`${W}${$e} ${e.usage}`),n.push(""),e.subcommands&&e.subcommands.length>0){n.push("SUBCOMMANDS:");let r=wf(e.subcommands);for(let o of e.subcommands)n.push(`${W}${o.usage.padEnd(r+2)}${o.description}`);n.push("")}if(e.options.length>0){n.push("OPTIONS:");let r=bf(e.options);for(let o of e.options){let i=ul(o),s=o.default?`${o.description} (default: ${o.default})`:o.description;n.push(`${W}${i.padEnd(r+2)}${s}`)}n.push("")}if(e.examples&&e.examples.length>0){n.push("EXAMPLES:");for(let r of e.examples)n.push(`${W}${r}`)}t(n.join(`
190
- `))}function co(){let e=xf(Yt),t=[];t.push(`${$e} v${dl}`),t.push(""),t.push("Blocks destructive commands and secret access."),t.push(""),t.push("COMMANDS:");for(let n of Yt)t.push(kf(n,e));t.push(""),t.push("GLOBAL OPTIONS:"),t.push(`${W}-h, --help Show help (use with command for command-specific help)`),t.push(`${W}-V, --version Show version`),t.push(""),t.push("HELP:"),t.push(`${W}${$e} help <command> Show help for a specific command`),t.push(`${W}${$e} <command> --help Show help for a specific command`),t.push(""),t.push("ENVIRONMENT VARIABLES:"),t.push(ge(`${S.level.name}=standard|strict|paranoid`,"Set session safety level")),t.push(ge(`${S.worktree.name}=1`,"Allow local git discards in linked worktrees")),t.push(ge(`${S.debug.name}=1`,"Print diagnostic messages to stderr")),t.push(ge(`${S.auditScope.name}=all|blocked`,"Record all command decisions, or denials only")),t.push(ge("CC_SAFETY_NET_HOME","Override rule config home directory")),t.push(""),t.push("LEGACY ENVIRONMENT VARIABLES (STILL SUPPORTED):"),t.push(ge(`${S.strict.name}=1`,"Force safety.overrides.fail_closed on")),t.push(ge(`${S.paranoid.name}=1`,"Force paranoid_rm and paranoid_interpreters on")),t.push(ge(`${S.paranoidRm.name}=1`,"Force safety.overrides.paranoid_rm on")),t.push(ge(`${S.paranoidInterpreters.name}=1`,"Force safety.overrides.paranoid_interpreters on")),t.push(""),t.push("Documentation: https://ccsafetynet.com/docs"),console.log(t.join(`
191
- `))}function pl(){console.log(dl)}function Ft(e,t=console.log){let n=Zt(e);if(!n)return!1;if(n.name.toLowerCase()!==e.toLowerCase())return!1;return xn(n,t),!0}import{existsSync as xo,readFileSync as oc}from"node:fs";import{homedir as bm,tmpdir as wm}from"node:os";import{join as bo}from"node:path";import*as we from"node:readline";function Cf(e){return e==="install"?"Install":"Uninstall"}function Sf(e){return e==="install"?"Installing":"Uninstalling"}function Df(e){return e==="install"?"into":"from"}function gl(e){return e?.available===!0}function Rf(e,t){let n=new Set(t);return e.filter((r)=>n.has(r.target)).map((r)=>r.target)}function fl(e,t,n){if(e.length===0||e.every((r)=>!r.available))return t;return Array.from({length:e.length},(r,o)=>o+1).map((r)=>(t+r*n+e.length)%e.length).find((r)=>gl(e[r]))}function Af(e,t,n){if(n.ctrl&&n.name==="c")return"interrupt";if(n.name==="escape"||t==="q")return"abort";if(e==="install"&&(t==="u"||t==="U"))return"update";if(n.name==="up"||t==="k")return"up";if(n.name==="down"||t==="j")return"down";if(n.name==="space"||t===" ")return"toggle";if(n.name==="return"||n.name==="enter")return"confirm";return null}function Ef(e){return{cursor:e.findIndex((t)=>t.available),selected:[]}}function Pf(e,t,n){if(n==="confirm"||n==="update"||n==="abort"||n==="interrupt")return{state:e,done:n};if(n==="up")return{state:{...e,cursor:fl(t,e.cursor,-1)}};if(n==="down")return{state:{...e,cursor:fl(t,e.cursor,1)}};let r=t[e.cursor];if(!gl(r))return{state:e};let o=e.selected.includes(r.target)?e.selected.filter((i)=>i!==r.target):Rf(t,[...e.selected,r.target]);return{state:{...e,selected:o}}}var hl="◉",yl="◯",Ll=">",vl=" ";function Tf(e,t,n,r={}){let o=r.color!==!1,i=o?h.dim:(l)=>l,s=o?h.green:(l)=>l,a=o?h.bold:(l)=>l;return["",`${Cf(e)} CC Safety Net ${Df(e)}:`,"",...t.map((l,c)=>{let d=n.selected.includes(l.target),p=c===n.cursor,g=d?hl:yl,u=p?Ll:vl,m=l.available?"":` (${l.unavailableReason??"not installed"})`,f=`${g} ${l.label}${m}`,L=!l.available?i(f):d?s(f):p?a(f):f;return`${u} ${L}`}),"",e==="install"?"Space: select Enter: confirm u: update installed Up/Down: move q/Esc: cancel":t.some((l)=>l.available)?"Space: select Enter: confirm Up/Down: move q/Esc: cancel":`No selectable integrations found for ${e}. q/Esc: close`].join(`
192
- `)}var ml=["global-hook","plugin"];function If(e,t,n={}){let r=n.color!==!1?h.bold:(i)=>i;return["","Install the Kimi Code integration as:","",...[`Global hook — ${t?"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((i,s)=>{let a=s===e,l=`${a?hl:yl} ${i}`;return`${a?Ll:vl} ${a?r(l):l}`}),"","Enter: confirm Up/Down: move q/Esc: cancel"].join(`
193
- `)}function bl(e){let{input:t,output:n}=e;we.emitKeypressEvents(t);let r=t.isRaw===!0;t.setRawMode(!0),t.resume();let o=0,i=()=>{if(o===0)return;we.moveCursor(n,0,-o),we.cursorTo(n,0),we.clearScreenDown(n)},s=()=>{i();let a=e.render();n.write(`${a}
178
+ `}function Nt(e){return[{name:"__init__.py",content:W2(e)},{name:"plugin.yaml",content:K2(e)}]}import{mkdirSync as J2,readdirSync as Y2,readFileSync as Z2,rmSync as Kr}from"node:fs";import{join as Ne}from"node:path";var X2="__pycache__";function Wr(e){let t=process.env.HERMES_HOME?.trim();return t?t:Ne(e,".hermes")}function Jr(e){return Ne(Wr(e),"plugins",K)}function Yr(e){return e.startsWith(Ia)}function Zr(e,t){let n=Jr(e),r=E(n);if(r&&(r.isSymbolicLink()||!r.isDirectory()))throw Error(`Refusing to ${t} ${n}: not a regular directory. Move or remove it and rerun ${t==="install"?"install":"uninstall"} --hermes-agent.`);return n}function Oa(e,t){let n=E(e);if(!n)return;if(n.isSymbolicLink()||!n.isFile())throw Error(`Refusing to ${t} ${e}: not a regular file. Move or remove it.`);let r=Z2(e,"utf-8");if(!Yr(r))throw Error(`Refusing to ${t} unmanaged file at ${e}. Move or remove it.`);return r}function $a(e){let t=Zr(e,"install"),n=Nt(T());if(n.map((o)=>Oa(Ne(t,o.name),"overwrite")).every((o,i)=>o===n[i]?.content))return{path:t,alreadyInstalled:!0};return J2(t,{recursive:!0}),n.forEach((o)=>{I(Ne(t,o.name),o.content)}),{path:t,alreadyInstalled:!1}}function Xr(e){let t=Zr(e,"remove");if(!E(t))return[];return Nt(T()).filter((n)=>Oa(Ne(t,n.name),"remove")!==void 0)}function Na(e){let t=Zr(e,"remove");if(!E(t))return{path:t,alreadyInstalled:!1};let n=Xr(e);if(n.forEach((r)=>{Kr(Ne(t,r.name))}),Kr(Ne(t,X2),{recursive:!0,force:!0}),Y2(t).length===0)Kr(t,{recursive:!0});return{path:t,alreadyInstalled:n.length>0}}var bn="hermes-agent",Fa=/^([^\s#][^:]*):/,Q2=/^\s+([A-Za-z_][\w-]*):/,Ha=/^\s+-\s*(.*)$/;function ef(e){return e.trim().replace(/^(["'])(.*)\1$/,"$2")}function tf(e){let t=e.split(/\r?\n/),n=t.findIndex((i)=>Fa.exec(i)?.[1]?.trim()==="plugins");if(n===-1)return[];let r=t.slice(n+1),o=r.findIndex((i)=>Fa.test(i));return o===-1?r:r.slice(0,o)}function Ma(e,t){let n=tf(e),r=n.findIndex((s)=>Q2.exec(s)?.[1]===t);if(r===-1)return[];let o=n.slice(r+1),i=o.findIndex((s)=>!Ha.test(s));return(i===-1?o:o.slice(0,i)).map((s)=>ef(Ha.exec(s)?.[1]??""))}function nf(e){try{return ja(Ua(Wr(e),"config.yaml"),"utf-8")}catch{return}}function Qr(e){let t=nf(e)??"";return Ma(t,"enabled").includes(K)&&!Ma(t,"disabled").includes(K)}function Ga(e){return/^# version:\s*(.+)$/m.exec(e)?.[1]?.trim()}function rf(e,t){let n=E(e);if(!n)return{error:`${t.name} is missing from ${e}; run install --hermes-agent`};if(n.isSymbolicLink()||!n.isFile())return{error:`${e} is a symlink or not a regular file; move or remove it`};try{let r=ja(e,"utf-8");if(!Yr(r))return{error:`Unmanaged ${t.name} occupies ${e}; move or remove it`};if(Ga(r)===T()&&r!==t.content)return{error:`Modified ${t.name} occupies ${e}; run install --hermes-agent to restore it`};return{content:r}}catch(r){return{error:`Failed to read ${e}: ${r instanceof Error?r.message:String(r)}`}}}function Ba(e){let t=Jr(e.homeDir),n=ln(bn,t);if(n)return n;let r=Nt(T()).map((a)=>rf(Ua(t,a.name),a)),o=r.flatMap((a)=>("error"in a)?[a.error]:[]);if(o.length>0)return{platform:bn,status:"n/a",configPath:t,errors:o};let i=r.some((a)=>("content"in a)&&Ga(a.content)!==T()),s=i?["Installed Hermes Agent plugin is outdated; run install --hermes-agent to update"]:[];if(!Qr(e.homeDir))return{platform:bn,status:"disabled",method:"plugin directory",configPath:t,errors:[`${K} is not enabled in Hermes; run \`hermes plugins enable ${K}\``,...s]};return{platform:bn,status:"configured",method:"plugin directory",configPath:t,errors:i?s:void 0}}import{existsSync as of,readFileSync as sf}from"node:fs";import{join as qa}from"node:path";var af=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*--kimi-code(\s|["']|$)/;function lf(e){return qa(process.env.KIMI_CODE_HOME||qa(e,".kimi-code"),"config.toml")}function Ft(e){let t=lf(e.homeDir);if(!of(t))return{platform:"kimi-code",status:"n/a",configPath:t};try{if(!af.test(sf(t,"utf-8")))return{platform:"kimi-code",status:"n/a",configPath:t}}catch(n){return{platform:"kimi-code",status:"n/a",configPath:t,errors:[`Failed to read ${t}: ${n instanceof Error?n.message:String(n)}`]}}return{platform:"kimi-code",status:"configured",method:"hook config",configPath:t}}import{readFileSync as el}from"node:fs";import{join as Mt}from"node:path";var A="cc-safety-net",W="index.js",at="openclaw.plugin.json",lt="package.json";var wn="// cc-safety-net managed OpenClaw plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --openclaw";import{existsSync as uf,lstatSync as pf,readdirSync as ff,readFileSync as mf}from"node:fs";import{dirname as Ka,join as we}from"node:path";import{fileURLToPath as gf}from"node:url";import{spawn as cf}from"node:child_process";function df(e){return e.join(" ")}function eo(e,t,n){return[`Failed to run ${df(e)}${t===null?"":` (exit ${t})`}.`,n.trim()].filter(Boolean).join(`
179
+ `)}function to(e){let t={stdout:"",stderr:""};return e.stdout.setEncoding("utf-8"),e.stderr.setEncoding("utf-8"),e.stdout.on("data",(n)=>{t.stdout+=n}),e.stderr.on("data",(n)=>{t.stderr+=n}),t}function se(e,t){return new Promise((n,r)=>{let o=_e([...e],process.env),i=cf(o.cmd,o.args,{stdio:["ignore","pipe","pipe"]}),s=to(i),a=()=>[s.stdout,s.stderr].filter(Boolean).join(`
180
+ `),l=t?.timeoutMs??120000,c=setTimeout(()=>{i.kill(),r(Error(eo(e,null,`Timed out after ${l}ms.
181
+ ${a()}`.trim())))},l);i.on("error",(d)=>{clearTimeout(c),r(Error(eo(e,null,`${d.message}
182
+ ${a()}`.trim())))}),i.on("close",(d)=>{if(clearTimeout(c),d!==0){r(Error(eo(e,d,a())));return}n(t?.stdoutOnly?s.stdout:a())})})}async function no(e){for(let t of e)await se(t)}async function Va(e){for(let t of e)try{await se(t)}catch(n){console.warn(n instanceof Error?n.message:String(n))}}var za=we("openclaw",A),hf=[W,at,lt];function ro(e,t){if(e==="~")return t;if(e.startsWith("~/")||e.startsWith("~\\"))return we(t,e.slice(2));return e}function Wa(e){let t=process.env.OPENCLAW_STATE_DIR?.trim();if(t)return ro(t,e);let n=process.env.OPENCLAW_CONFIG_PATH?.trim();return n?Ka(ro(n,e)):we(e,".openclaw")}function Ja(e){let t=process.env.OPENCLAW_CONFIG_PATH?.trim();return t?ro(t,e):we(Wa(e),"openclaw.json")}function oo(e){return we(Wa(e),"extensions",A)}function yf(e){let t=ff(e);if(t.length===0)return!0;if(t.some((o)=>!hf.includes(o)))return!1;let n=we(e,W),r=E(n);return r!==void 0&&!r.isSymbolicLink()&&r.isFile()&&mf(n,"utf-8").startsWith(wn)}function io(e){let t=oo(e),n=E(t);if(!n)return;if(!n.isSymbolicLink()&&n.isDirectory()&&yf(t))return;throw Error(`Refusing to modify ${t}: it does not hold a cc-safety-net managed OpenClaw plugin. Move or remove it, then run the command again.`)}function Ya(){let e=Ka(gf(import.meta.url));return[we(e,"..",za),we(e,"..","..","..","dist",za)]}function so(e=Ya()){return e.find((t)=>uf(t)&&pf(t).isDirectory())}function Lf(e=Ya()){let t=so(e);if(!t)throw Error("Packaged OpenClaw plugin directory not found. Reinstall cc-safety-net and try again.");return t}function Za(e=Lf()){return[["openclaw","plugins","install",e,"--force"],["openclaw","plugins","enable",A]]}function vf(e){let t=(()=>{try{return JSON.parse(e)}catch{return}})(),n=b(b(t,"plugin"),"status");return typeof n==="string"?n:void 0}async function Xa(){let e=vf(await se(["openclaw","plugins","inspect",A,"--runtime","--json"],{stdoutOnly:!0}));if(e==="loaded")return;throw Error(`${e===void 0?`The ${A} plugin's load state could not be verified: OpenClaw's runtime inspect report was unreadable.`:`OpenClaw reports the ${A} plugin with status "${e}".`} Run \`openclaw plugins inspect ${A} --runtime\` for details.`)}var kn="openclaw",Ht=`run \`openclaw plugins enable ${A}\``;function ct(e,t){let n=Mt(e,t),r=E(n);if(!r)return{error:`${t} is missing from ${n}; run install --openclaw`};if(r.isSymbolicLink()||!r.isFile())return{error:`${n} is a symlink or not a regular file; move or remove it`};try{return{content:el(n,"utf-8")}}catch(o){return{error:`Failed to read ${n}: ${o instanceof Error?o.message:String(o)}`}}}function tl(e){try{return JSON.parse(q(e))}catch{return}}function bf(e){let t=ct(e,at);if("error"in t)return t.error;if(b(tl(t.content),"id")===A)return;return`${Mt(e,at)} is not a valid ${A} manifest; run install --openclaw`}function wf(e){let t=ct(e,lt);if("error"in t)return t.error;let n=b(b(tl(t.content),"openclaw"),"extensions");if(Array.isArray(n)&&n.includes(`./${W}`))return;return`${Mt(e,lt)} does not point OpenClaw at ${W}; run install --openclaw`}function Qa(e){return Array.isArray(e)?e.filter((t)=>typeof t==="string"):[]}function kf(e){let t=Ja(e);if(!E(t))return`${A} is not enabled; ${Ht}`;let n=(()=>{try{return JSON.parse(q(el(t,"utf-8")))}catch{return}})();if(n===void 0)return`Failed to read ${t}; fix it, then ${Ht}`;let r=b(n,"plugins");if(b(r,"enabled")===!1)return`plugins.enabled is false in ${t}; no OpenClaw plugin loads`;let o=b(b(b(r,"entries"),A),"enabled");if(Qa(b(r,"deny")).includes(A)||o===!1)return`${A} is disabled in ${t}; ${Ht}`;let i=Qa(b(r,"allow"));if(i.length>0&&!i.includes(A))return`plugins.allow in ${t} does not list ${A}; add it, then ${Ht}`;if(i.includes(A)||o===!0)return;return`${A} is not enabled; ${Ht}`}function nl(e){return/^\/\/ version:\s*(.+)$/m.exec(e)?.[1]?.trim()}function xf(e,t,n){if(n===void 0)return[];let r=ct(n,W);if("error"in r||nl(r.content)!==t)return[];return[W,at,lt].flatMap((o)=>{let i=ct(e,o),s=ct(n,o);if("error"in i||"error"in s||i.content===s.content)return[];return[`Modified ${o} occupies ${Mt(e,o)}; run install --openclaw to restore it`]})}function rl(e){let t=oo(e.homeDir),n=ln(kn,t);if(n)return n;let r=ct(t,W),i=["error"in r?r.error:r.content.startsWith(wn)?void 0:`Unmanaged ${W} occupies ${Mt(t,W)}; move or remove it`,bf(t),wf(t)].filter((d)=>d!==void 0),s="content"in r?nl(r.content):void 0,a=i.length>0?i:xf(t,s,so());if(a.length>0)return{platform:kn,status:"n/a",configPath:t,errors:a};let l=s===T()?[]:["Installed OpenClaw plugin is outdated; run install --openclaw to update"],c=kf(e.homeDir);if(c)return{platform:kn,status:"disabled",method:"plugin directory",configPath:t,errors:[c,...l]};return{platform:kn,status:"configured",method:"plugin directory",configPath:t,errors:l.length>0?l:void 0}}import{existsSync as Of,readFileSync as $f}from"node:fs";import{join as Nf}from"node:path";import{existsSync as ao,readFileSync as ll,rmSync as Sf}from"node:fs";import{join as ge}from"node:path";import{pathToFileURL as Df}from"node:url";function ol(e){return e!==void 0&&/\s/.test(e)}function Cf(e,t,n){let r=t+1,o=!1;while(r<e.length){let i=e[r];if(o){o=!1,r++;continue}if(i==="\\"){o=!0,r++;continue}if(i==='"')return r+1;r++}throw Error(n)}function xn(e,t,n){let r=e[t],o=r==="["?"]":"}",i=0,s=t;while(s<e.length){let a=n.skipComment?.(e,s)??s;if(a!==s){s=a;continue}if(e[s]==='"'){s=Cf(e,s,n.stringError);continue}if(e[s]===r)i++;if(e[s]===o){if(i--,i===0)return s}s++}throw Error(n.bracketError)}function il(e,t){let n=e.lastIndexOf(`
183
+ `,t)+1;return/^[ \t]*/.exec(e.slice(n))?.[0]??""}function Cn(e,t){let{start:n,end:r,end:o}=t;while(ol(e[o]))o++;if(e[o]===","){if(r=o+1,e[r]===`
184
+ `)r++;return`${e.slice(0,n)}${e.slice(r)}`}o=t.start-1;while(ol(e[o]))o--;if(e[o]===","){n=o;let i=e.lastIndexOf(`
185
+ `,n-1);if(i!==-1&&/^\s*$/.test(e.slice(i+1,n)))n=i}return`${e.slice(0,n)}${e.slice(r)}`}var Sn="cc-safety-net",cl=`${Sn}@latest`,dl=["opencode.json","opencode.jsonc"],sl="CCSafetyNetPlugin";function Dn(e){return ge(process.env.XDG_CONFIG_HOME||ge(e,".config"),"opencode")}function Rf(e){return ge(Dn(e),dl[0])}function Af(e){return dl.map((t)=>ge(Dn(e),t))}function ul(e){return ge(process.env.XDG_CACHE_HOME||ge(e,".cache"),"opencode","packages",cl)}function lo(e){Sf(ul(e),{recursive:!0,force:!0})}async function pl(e){let t=ge(ul(e),"node_modules",Sn),n=ge(t,"package.json");if(!ao(n))throw Error(`The OpenCode plugin cache at ${t} is missing its package, so OpenCode would load nothing and fail open. Run \`opencode plugin -g -f ${cl}\` for details.`);let r=b(JSON.parse(ll(n,"utf-8")),"main");if(typeof r!=="string")throw Error(`The cached OpenCode plugin at ${t} declares no "main" entry.`);let o=ge(t,r);if(typeof(await import(Df(o).href))[sl]==="function")return;throw Error(`The cached OpenCode plugin at ${o} does not export a callable ${sl}, so OpenCode would load nothing and fail open.`)}function Rn(e,t){if(e[t]==="/"&&e[t+1]==="/"){let n=e.indexOf(`
186
+ `,t+2);return n===-1?e.length:n+1}if(e[t]==="/"&&e[t+1]==="*"){let n=e.indexOf("*/",t+2);return n===-1?e.length:n+2}return t}function al(e,t){let n=t;while(n<e.length){if(/\s/.test(e[n]??"")){n++;continue}let r=Rn(e,n);if(r===n)return n;n=r}return n}function fl(e,t){let n=t+1,r=!1;while(n<e.length){if(r){r=!1,n++;continue}if(e[n]==="\\"){r=!0,n++;continue}if(e[n]==='"')return n+1;n++}throw Error("Unterminated string in OpenCode config")}function ml(e,t,n){return JSON.parse(e.slice(t,n))}function Ef(e,t){return xn(e,t,{skipComment:Rn,stringError:"Unterminated string in OpenCode config",bracketError:"Unmatched plugin array in OpenCode config"})}function Pf(e){let t=0,n=0;while(n<e.length){let r=Rn(e,n);if(r!==n){n=r;continue}if(e[n]==='"'){let o=fl(e,n);if(t===1&&ml(e,n,o)==="plugin"){let i=al(e,o),s=al(e,i+1);if(e[i]===":"&&e[s]==="[")return{start:s,end:Ef(e,s)}}n=o;continue}if(e[n]==="{"||e[n]==="[")t++;if(e[n]==="}"||e[n]==="]")t--;n++}return}function Tf(e,t){let n=[],r=t.start+1;while(r<t.end){let o=Rn(e,r);if(o!==r){r=o;continue}if(e[r]==='"'){let i=fl(e,r),s=ml(e,r,i);if(typeof s==="string"&&s.includes(Sn))n.push({start:r,end:i});r=i;continue}r++}return n}function gl(e,t){try{return JSON.parse(q(e))}catch(n){if(n instanceof SyntaxError)throw Error(`Failed to parse OpenCode config ${t}: ${n.message}`);throw n}}function If(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e.plugin;if(!Array.isArray(t))return!1;return t.some((n)=>typeof n==="string"&&n.includes(Sn))}function _f(e,t){let n=Pf(e);if(!n)throw Error(`Failed to locate OpenCode plugin array in ${t}`);let r=[...Tf(e,n)].reverse().reduce(Cn,e);return gl(r,t),r}function hl(e){lo(e);let t=Af(e),n=t.find((o)=>ao(o)),r=[];for(let o of t){if(!ao(o))continue;try{let i=ll(o,"utf-8");if(!If(gl(i,o)))continue;return I(o,_f(i,o)),{path:o,alreadyInstalled:!0}}catch(i){r.push(i instanceof Error?i.message:String(i))}}if(r.length>0)throw Error(r.join(`
187
+ `));return{path:n??Rf(e),alreadyInstalled:!1}}function yl(e){let t=[],n=Dn(e.homeDir),r=["opencode.json","opencode.jsonc"];for(let o of r){let i=Nf(n,o);if(Of(i))try{let s=$f(i,"utf-8"),a=q(s);if((JSON.parse(a).plugin??[]).some((p)=>p.includes("cc-safety-net")))return{platform:"opencode",status:"configured",method:"plugin array",configPath:i,errors:t.length>0?t:void 0}}catch(s){t.push(`Failed to parse ${o}: ${s instanceof Error?s.message:String(s)}`)}}return{platform:"opencode",status:"n/a",errors:t.length>0?t:void 0}}import{join as Ff}from"node:path";function co(e){return Ff(e,".pi","agent","settings.json")}function uo(e){if(typeof e!=="string")return!1;return e==="npm:cc-safety-net"||e.startsWith("npm:cc-safety-net@")}function Ll(e){let t=co(e.homeDir),n=oe(t);if(n.kind==="unreadable")return{platform:"pi",status:"not-inspected"};if(n.kind==="missing")return{platform:"pi",status:"n/a"};let r=b(n.value,"packages");if(!Array.isArray(r))return{platform:"pi",status:"n/a"};let o=r.find((a)=>uo(typeof a==="string"?a:b(a,"source")));if(o===void 0)return{platform:"pi",status:"n/a"};let i=b(o,"extensions");if(Array.isArray(i)&&i.some((a)=>typeof a==="string"&&a.startsWith("-")))return{platform:"pi",status:"disabled",method:"package config",configPath:t,errors:["npm:cc-safety-net is installed but its extension is disabled in Pi settings"]};return{platform:"pi",status:"configured",method:"package config",configPath:t}}var Mf={amp:Js,"antigravity-cli":Ys,"claude-code":ea,codex:ta,"copilot-cli":pa,cursor:ba,"gemini-cli":wa,"grok-build":Ta,"hermes-agent":Ba,"kimi-code":Ft,openclaw:rl,opencode:yl,pi:Ll};function dt(e,t){let n={...t,cwd:e,homeDir:t?.homeDir??Hf()};return Xt.map((r)=>jf(Mf[r](n)))}function jf(e){if(e.status==="not-inspected")return{platform:e.platform,detected:!1,configured:!1,inspectionStatus:"not-inspected"};return{platform:e.platform,detected:e.status!=="n/a",configured:e.status==="configured",inspectionStatus:e.status!=="n/a"?"verified":e.errors&&e.errors.length>0?"failed":"not-applicable",method:e.method,configPath:e.configPath,configPaths:e.configPaths,errors:e.errors}}import{tmpdir as Uf}from"node:os";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 vl(){let e=Gf(Uf(),"cc-safety-net-self-test"),t=Bf.map((n)=>{let r=Yt(Qe("self-test",{command:n.command},{kind:"command",shell:"auto"},{configCwd:e,executionCwd:e},n.command),{guard:{dependencies:{loadPolicySnapshot:()=>qf,getModes:()=>Vf,findPolicyMutation:()=>null}},audit:{agent:"self-test",getSessionId:()=>{return}}}),o=n.expectBlocked?"blocked":"allowed",i=r.decision.kind==="deny"?"blocked":"allowed";return{command:n.command,description:n.description,expected:o,actual:i,passed:o===i,reason:r.decision.kind==="deny"?r.decision.reason:void 0,ruleId:r.decision.kind==="deny"?r.decision.ruleId:void 0}});return{passed:t.filter((n)=>n.passed).length,failed:t.filter((n)=>!n.passed).length,total:t.length,results:t}}function po(e){let t=_({label:"doctor",booleans:{json:["--json"],skipUpdateCheck:["--skip-update-check"]}},e);if(le(t.errors))return null;return{json:t.flags.json,skipUpdateCheck:t.flags.skipUpdateCheck}}async function bl(e={}){let t=await Tt(!e.json,()=>{let n=zf(e);return{ready:n,finish:()=>n}},()=>Pt(),{loadingMessage:"Checking system status…"});if(e.json)console.log(JSON.stringify(t,null,2));else Kf(t);return t.engineSelfTest.failed>0||t.findings.some((n)=>n.severity==="error")?1:0}async function zf(e){let t=e.cwd??process.cwd(),n=await At(),r=dt(t,{ampPluginListOutput:n.ampPluginListOutput,codexPluginListOutput:n.codexPluginListOutput,copilotCliVersion:n.versions["copilot-cli"]}),o=vs(t),i=bs(),s=B({cwd:t}),a=s.policy,l=ue(a),c=Pe(a,l.capabilities),d=tn(7),p=e.skipUpdateCheck?{currentVersion:T(),latestVersion:null,updateAvailable:!1}:await be(),g={hooks:r,engineSelfTest:vl(),userConfig:o.userConfig,projectConfig:o.projectConfig,configState:xt(s),effectiveRules:o.effectiveRules,shadowedRules:o.shadowedRules,environment:i,effectiveSafety:{selectedPreset:a.safety.level??"standard",level:l.effectiveLevel,capabilities:l.capabilities,ruleOverrides:a.destructiveCommandRuleOverrides,weakenedRuleOverrides:Object.entries(c).filter(([,u])=>u.source==="rule_override"&&u.override==="off"&&u.inheritedEnabled&&u.changesInherited).map(([u])=>u),ruleCounts:{stored:Object.keys(a.destructiveCommandRuleOverrides).length,effective:Object.values(c).filter((u)=>u.changesInherited).length}},posture:Os(o.userConfig.path),activity:d,update:p,system:n};return{...g,findings:ks(g)}}function Kf(e){console.log(),console.log(Cs(e.hooks)),console.log(),console.log(Ss(e.engineSelfTest)),console.log(),console.log(Ds(e)),console.log(),console.log(Rs(e.environment)),console.log(),console.log(As(e)),console.log(),console.log(Es(e.findings)),console.log(),console.log(Ps(e.activity)),console.log(),console.log(Is(e.system)),console.log(),console.log(Ts(e.update)),console.log(_s(e))}import{existsSync as Wf}from"node:fs";var Jf=/^[A-Za-z0-9_@%+=:,./-]+$/,wl="Usage: cc-safety-net explain [--json] [--cwd <path>] <command>";function fo(e){let t=_({label:"explain",booleans:{json:["--json"]},values:{cwd:["--cwd"]},positionals:"tail"},e);if(le(t.errors))return console.error(wl),console.error("Pass -- before a command that starts with dashes."),null;if(t.values.cwd!==void 0&&!Wf(t.values.cwd))return console.error(`Error: --cwd path does not exist: ${t.values.cwd}`),null;let n=t.positionals.length===1?t.positionals[0]:t.positionals.map((r)=>Jf.test(r)?r:`'${r.replaceAll("'","'\\''")}'`).join(" ");if(!n)return console.error("Error: No command provided"),console.error(wl),null;return{json:t.flags.json,cwd:t.values.cwd,command:n}}function kl(e){if(e)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(e,t){let r=t-18;return[`${e.dtl}${e.dh.repeat(t)}${e.dtr}`,`${e.dv} Command Analysis${" ".repeat(r)}${e.dv}`,`${e.dbl}${e.dh.repeat(t)}${e.dbr}`]}function mo(e){return JSON.stringify(e)}function Cl(e,t=0){return`[${e.map((r,o)=>xs(r,o,t)).join(",")}]`}function An(e,t,n=70){let r=e.split(" "),o=[],i="";for(let s of r)if(i&&i.length+s.length+1>n)o.push(i),i=s;else i=i?`${i} ${s}`:s;if(i)o.push(i);return o.map((s,a)=>a===0?s:`${t}${s}`)}function Sl(e,t,n){let r=[];switch(e.type){case"parse":return null;case"env-strip":return r.push(""),r.push(`STEP ${t} ${n.h} Strip environment variables`),r.push(` Removed: ${e.envVars.map((o)=>`${o}=<redacted>`).join(", ")}`),r.push(` Tokens: ${mo(e.output)}`),{lines:r,incrementStep:!0};case"leading-tokens-stripped":return r.push(""),r.push(`STEP ${t} ${n.h} Strip wrappers`),r.push(` Removed: ${e.removed.join(", ")}`),r.push(` Tokens: ${mo(e.output)}`),{lines:r,incrementStep:!0};case"shell-wrapper":return r.push(""),r.push(`STEP ${t} ${n.h} Detect shell wrapper`),r.push(` Wrapper: ${e.wrapper} -c`),r.push(` Inner: ${e.innerCommand}`),{lines:r,incrementStep:!0};case"interpreter":{if(r.push(""),r.push(`STEP ${t} ${n.h} Detect interpreter`),r.push(` Interpreter: ${e.interpreter}`),r.push(` Code: ${e.codeArg}`),e.paranoidBlocked)r.push(" Result: ✗ BLOCKED (paranoid mode)");return{lines:r,incrementStep:!0}}case"busybox":return r.push(""),r.push(`STEP ${t} ${n.h} Busybox wrapper`),r.push(` Subcommand: ${e.subcommand}`),{lines:r,incrementStep:!0};case"transparent-wrapper":return r.push(""),r.push(`STEP ${t} ${n.h} Transparent wrapper`),r.push(` Wrapper: ${e.wrapper}`),r.push(` Tokens: ${mo(e.output)}`),{lines:r,incrementStep:!0};case"recurse":return{lines:[],incrementStep:!1};case"rule-check":{if(r.push(""),r.push(`STEP ${t} ${n.h} Match rules`),r.push(` Rule: ${e.rule}()`),e.matched)r.push(" Result: MATCHED");else r.push(" Result: No match");return{lines:r,incrementStep:!0}}case"worktree-relaxation":return r.push(""),r.push(`STEP ${t} ${n.h} Worktree relaxation`),r.push(` Mode: ${S.worktree.name}`),r.push(` Git cwd: ${e.gitCwd}`),r.push(" Result: Allowed local discard in linked worktree"),{lines:r,incrementStep:!0};case"tmpdir-check":return null;case"fallback-scan":{if(e.embeddedCommandFound)return r.push(""),r.push(`STEP ${t} ${n.h} Fallback scan`),r.push(` Found: ${e.embeddedCommandFound}`),{lines:r,incrementStep:!0};return null}case"custom-rules-check":{if(e.rulesChecked){if(r.push(""),r.push(`STEP ${t} ${n.h} Custom rules`),e.matched)r.push(" Result: MATCHED");else r.push(" Result: No match");return{lines:r,incrementStep:!0}}return null}case"cwd-change":return null;case"dangerous-text":{if(e.matched)return r.push(""),r.push(`STEP ${t} ${n.h} Dangerous text check`),r.push(` Token: ${e.token}`),r.push(" Result: MATCHED"),{lines:r,incrementStep:!0};return null}case"strict-unparseable":return r.push(""),r.push(`STEP ${t} ${n.h} Strict mode check`),r.push(` Command: ${e.rawCommand}`),r.push(" Result: ✗ UNPARSEABLE"),{lines:r,incrementStep:!0};case"segment-skipped":return null;case"error":return r.push(""),r.push(`ERROR: ${e.message}`),{lines:r,incrementStep:!1};default:return e}}function go(e,t){let n=kl(t?.asciiOnly??!1),r=58,o=[],i=1;o.push(...xl(n,58)),o.push("");let s=e.trace.steps.find((u)=>u.type==="error");if(s&&s.type==="error"){o.push("ERROR"),o.push(` ${s.message}`),o.push(""),o.push("RESULT"),o.push(` Status: ${e.result==="blocked"?h.red("BLOCKED"):h.green("ALLOWED")}`),o.push(""),o.push("CONFIG");let u=e.configSource??"none";return o.push(` Path: ${u}`),o.join(`
188
+ `)}let a=e.trace.steps.find((u)=>u.type==="parse");if(a&&a.type==="parse"){o.push("INPUT"),o.push(` ${a.input}`),o.push(""),o.push(`STEP ${i} ${n.h} Split shell commands`),i++;for(let u=0;u<a.segments.length;u++){let m=a.segments[u];if(m){let f=Math.random();o.push(` Segment ${u+1}: ${Cl(m,f)}`)}}}let l=e.trace.segments,c=l.length>1;for(let u of l){if(c){o.push("");let v="";if(a&&a.type==="parse"){let Kn=a.segments[u.index];if(Kn)v=Kn.join(" ")}let x=54,y=v,C=` Segment ${u.index+1}: `,j=" ";if(v){if(C.length+v.length+j.length>x){let md=x-C.length-j.length;y=`${v.substring(0,md-1)}…`}}let ye=v?`${C}${y}${j}`:` Segment ${u.index+1} `,zn=v?`${C}${h.cyan(y)}${j}`:ye,Mo=58-ye.length,jo=Math.floor(Mo/2),fd=Mo-jo;o.push(`${n.sh.repeat(jo)}${zn}${n.sh.repeat(fd)}`)}if(u.steps.find((v)=>v.type==="segment-skipped")){o.push(""),o.push(" (skipped — prior segment blocked)");continue}let f=!1,L=!1;for(let v of u.steps){let x=Sl(v,i,n);if(x){if(L=!0,v.type==="recurse"){o.push("");let y=" RECURSING ",C=58-y.length-4;o.push(` ${n.tl}${n.h}${y}${n.h.repeat(C)}`),o.push(` ${n.v}`),f=!0;continue}for(let y of x.lines)if(f)o.push(` ${n.v} ${y}`);else o.push(y);if(x.incrementStep)i++}}if(f)o.push(` ${n.v}`),o.push(` ${n.bl}${n.h.repeat(56)}`),f=!1;if(!L)o.push(""),o.push(` ${h.green("✓")} Allowed (no matching rules)`)}if(o.push(""),o.push("RESULT"),e.result==="blocked"){if(o.push(` Status: ${h.red("BLOCKED")}`),e.customRule){if(o.push(` Rule: ${e.customRule.id}`),e.customRule.rulebook)o.push(` Rulebook: ${e.customRule.rulebook.name} ${e.customRule.rulebook.version}`);if(e.customRule.source)o.push(` Source: ${e.customRule.source}`);if(e.customRule.override)o.push(` Override: reason ${e.customRule.override.reason}`)}if(e.reason){let u=An(e.reason," ");o.push(` Reason: ${u[0]}`);for(let m=1;m<u.length;m++)o.push(u[m]??"")}}else o.push(` Status: ${h.green("ALLOWED")}`);o.push(""),o.push("CONFIG");let d=e.configSource??"none",p=e.configValid?"":" (invalid)";o.push(` Path: ${d}${p}`),o.push(` Safety preset: ${e.selectedPreset??"standard"}`),o.push(` Effective capabilities: ${e.effectiveLevel}`);let g=Object.entries(e.destructiveCommandRuleOverrides??{});if(o.push(` Rule customizations: ${g.length}`),e.ruleActivation)o.push(` Rule activation: ${e.ruleActivation.id} — ${e.ruleActivation.enabled?"on":"off"} via ${e.ruleActivation.source}`);return o.join(`
189
+ `)}function ho(e){return JSON.stringify(e,null,2)}function Dl(e){return new Promise((t)=>{process.stdout.write(`${e}
190
+ `,()=>t())})}async function Rl(e){let t=fo(e);if(!t)return 1;try{let n=et(t.command,{cwd:t.cwd}),r=!!process.env.NO_COLOR||!process.stdout.isTTY;return await Dl(t.json?ho(n):go(n,{asciiOnly:r})),0}catch(n){if(!(n instanceof yr)&&!(n instanceof Ee)&&!(n instanceof fe))throw n;if(t.json)return await Dl(JSON.stringify({error:n.message})),1;return console.error(n.message),1}}var Al="2.2.0",J=" ",Fe="cc-safety-net";function El(e){return e.argument?`${e.flags} ${e.argument}`:e.flags}function Yf(e){return Math.max(...e.map((t)=>El(t).length))}function Zf(e){return Math.max(...e.map((t)=>t.usage.length))}function Xf(e){return Math.max(...e.map((t)=>`${Fe} ${t.usage}`.length))}function Qf(e,t){let n=`${Fe} ${e.usage}`;return`${J}${n.padEnd(t+2)}${e.description}`}function he(e,t){return`${J}${e.padEnd(Math.max(40,e.length+2))}${t}`}function En(e,t=console.log){let n=[];if(n.push(`${Fe} ${e.name}`),n.push(""),n.push(`${J}${e.description}`),n.push(""),n.push("USAGE:"),n.push(`${J}${Fe} ${e.usage}`),n.push(""),e.subcommands&&e.subcommands.length>0){n.push("SUBCOMMANDS:");let r=Zf(e.subcommands);for(let o of e.subcommands)n.push(`${J}${o.usage.padEnd(r+2)}${o.description}`);n.push("")}if(e.options.length>0){n.push("OPTIONS:");let r=Yf(e.options);for(let o of e.options){let i=El(o),s=o.default?`${o.description} (default: ${o.default})`:o.description;n.push(`${J}${i.padEnd(r+2)}${s}`)}n.push("")}if(e.examples&&e.examples.length>0){n.push("EXAMPLES:");for(let r of e.examples)n.push(`${J}${r}`)}t(n.join(`
191
+ `))}function yo(){let e=Xf(Qt),t=[];t.push(`${Fe} v${Al}`),t.push(""),t.push("Blocks destructive commands and secret access."),t.push(""),t.push("COMMANDS:");for(let n of Qt)t.push(Qf(n,e));t.push(""),t.push("GLOBAL OPTIONS:"),t.push(`${J}-h, --help Show help (use with command for command-specific help)`),t.push(`${J}-V, --version Show version`),t.push(""),t.push("HELP:"),t.push(`${J}${Fe} help <command> Show help for a specific command`),t.push(`${J}${Fe} <command> --help Show help for a specific command`),t.push(""),t.push("ENVIRONMENT VARIABLES:"),t.push(he(`${S.level.name}=standard|strict|paranoid`,"Set session safety level")),t.push(he(`${S.worktree.name}=1`,"Allow local git discards in linked worktrees")),t.push(he(`${S.debug.name}=1`,"Print diagnostic messages to stderr")),t.push(he(`${S.auditScope.name}=all|blocked`,"Record all command decisions, or denials only")),t.push(he("CC_SAFETY_NET_HOME","Override rule config home directory")),t.push(""),t.push("LEGACY ENVIRONMENT VARIABLES (STILL SUPPORTED):"),t.push(he(`${S.strict.name}=1`,"Force safety.overrides.fail_closed on")),t.push(he(`${S.paranoid.name}=1`,"Force paranoid_rm and paranoid_interpreters on")),t.push(he(`${S.paranoidRm.name}=1`,"Force safety.overrides.paranoid_rm on")),t.push(he(`${S.paranoidInterpreters.name}=1`,"Force safety.overrides.paranoid_interpreters on")),t.push(""),t.push("Documentation: https://ccsafetynet.com/docs"),console.log(t.join(`
192
+ `))}function Pl(){console.log(Al)}function jt(e,t=console.log){let n=en(e);if(!n)return!1;if(n.name.toLowerCase()!==e.toLowerCase())return!1;return En(n,t),!0}import{existsSync as Eo,readFileSync as kc}from"node:fs";import{homedir as Ym,tmpdir as Zm}from"node:os";import{join as Ro}from"node:path";import*as ke from"node:readline";function em(e){return e==="install"?"Install":"Uninstall"}function tm(e){return e==="install"?"Installing":"Uninstalling"}function nm(e){return e==="install"?"into":"from"}function _l(e){return e?.available===!0}function rm(e,t){let n=new Set(t);return e.filter((r)=>n.has(r.target)).map((r)=>r.target)}function Tl(e,t,n){if(e.length===0||e.every((r)=>!r.available))return t;return Array.from({length:e.length},(r,o)=>o+1).map((r)=>(t+r*n+e.length)%e.length).find((r)=>_l(e[r]))}function om(e,t,n){if(n.ctrl&&n.name==="c")return"interrupt";if(n.name==="escape"||t==="q")return"abort";if(e==="install"&&(t==="u"||t==="U"))return"update";if(n.name==="up"||t==="k")return"up";if(n.name==="down"||t==="j")return"down";if(n.name==="space"||t===" ")return"toggle";if(n.name==="return"||n.name==="enter")return"confirm";return null}function im(e){return{cursor:e.findIndex((t)=>t.available),selected:[]}}function sm(e,t,n){if(n==="confirm"||n==="update"||n==="abort"||n==="interrupt")return{state:e,done:n};if(n==="up")return{state:{...e,cursor:Tl(t,e.cursor,-1)}};if(n==="down")return{state:{...e,cursor:Tl(t,e.cursor,1)}};let r=t[e.cursor];if(!_l(r))return{state:e};let o=e.selected.includes(r.target)?e.selected.filter((i)=>i!==r.target):rm(t,[...e.selected,r.target]);return{state:{...e,selected:o}}}var Ol="◉",$l="◯",Nl=">",Fl=" ";function am(e,t,n,r={}){let o=r.color!==!1,i=o?h.dim:(l)=>l,s=o?h.green:(l)=>l,a=o?h.bold:(l)=>l;return["",`${em(e)} CC Safety Net ${nm(e)}:`,"",...t.map((l,c)=>{let d=n.selected.includes(l.target),p=c===n.cursor,g=d?Ol:$l,u=p?Nl:Fl,m=l.available?"":` (${l.unavailableReason??"not installed"})`,f=`${g} ${l.label}${m}`,L=!l.available?i(f):d?s(f):p?a(f):f;return`${u} ${L}`}),"",e==="install"?"Space: select Enter: confirm u: update installed Up/Down: move q/Esc: cancel":t.some((l)=>l.available)?"Space: select Enter: confirm Up/Down: move q/Esc: cancel":`No selectable integrations found for ${e}. q/Esc: close`].join(`
193
+ `)}var Il=["global-hook","plugin"];function lm(e,t,n={}){let r=n.color!==!1?h.bold:(i)=>i;return["","Install the Kimi Code integration as:","",...[`Global hook — ${t?"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((i,s)=>{let a=s===e,l=`${a?Ol:$l} ${i}`;return`${a?Nl:Fl} ${a?r(l):l}`}),"","Enter: confirm Up/Down: move q/Esc: cancel"].join(`
194
+ `)}function Hl(e){let{input:t,output:n}=e;ke.emitKeypressEvents(t);let r=t.isRaw===!0;t.setRawMode(!0),t.resume();let o=0,i=()=>{if(o===0)return;ke.moveCursor(n,0,-o),ke.cursorTo(n,0),ke.clearScreenDown(n)},s=()=>{i();let a=e.render();n.write(`${a}
194
195
  `),o=a.split(`
195
- `).length};return new Promise((a)=>{let l=(d)=>{t.off("keypress",c),t.setRawMode(r),t.pause(),i(),a(d)};function c(d,p){e.onKey(d,p,{finish:l,draw:s})}t.on("keypress",c),s()})}function wl(e={}){let t=0;return bl({input:e.input??process.stdin,output:e.output??process.stdout,render:()=>If(t,e.globalHookInstalled===!0),onKey:(n,r,o)=>{if(r.ctrl&&r.name==="c"){o.finish(null),(e.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(r.name==="escape"||n==="q")return o.finish(null);if(r.name==="return"||r.name==="enter")return o.finish(ml[t]);if(r.name==="up"||r.name==="down"||n==="k"||n==="j")t=(t+1)%ml.length,o.draw()}})}function uo(e=process.stdin,t=process.stdout){return Boolean(e.isTTY&&t.isTTY&&typeof e.setRawMode==="function")}function xl(e,t,n={}){let r=n.output??process.stdout,o=Ef(t);return bl({input:n.input??process.stdin,output:r,render:()=>Tf(e,t,o),onKey:(i,s,a)=>{let l=Af(e,i,s);if(!l)return;let c=Pf(o,t,l);if(o=c.state,c.done==="interrupt"){a.finish(null),(n.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(c.done==="abort")return a.finish(null);if(c.done==="update")return a.finish("update");if(c.done==="confirm"){if(o.selected.length===0){r.write("\x07"),a.draw();return}a.finish([...o.selected]),r.write(`${Sf(e)} selected integrations...
196
- `);return}a.draw()}})}import{existsSync as Cl,lstatSync as Of,mkdirSync as $f,mkdtempSync as Nf,readdirSync as Ff,readFileSync as dt,rmSync as Sn}from"node:fs";import{tmpdir as Hf}from"node:os";import{basename as Mf,dirname as jf,join as U}from"node:path";import{fileURLToPath as Uf}from"node:url";var po="// cc-safety-net managed Amp plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --amp",Ne="cc-safety-net",Fe="cc-safety-net/index.ts";import{spawn as _f}from"node:child_process";var fo=(e,t)=>{let n=Ie([...e],process.env);return new Promise((r)=>{let o=_f(n.cmd,n.args,{cwd:t,stdio:["ignore","pipe","pipe"]}),i=Wr(o),s=!1,a=setTimeout(()=>{s=!0,o.kill()},120000);o.on("error",(l)=>{clearTimeout(a),r({status:null,errorCode:l.code,stdout:i.stdout,stderr:[l.message,i.stderr].filter(Boolean).join(`
197
- `)})}),o.on("close",(l)=>{clearTimeout(a),r({status:s?null:l,errorCode:s?"ETIMEDOUT":void 0,stdout:i.stdout,stderr:i.stderr})})})};var ct="cc-safety-net.ts",kl=U("amp",Fe);function Gf(e){return U(e,".config","amp","plugins","cc-safety-net.ts")}function Bf(){let e=jf(Uf(import.meta.url));return[U(e,"..",kl),U(e,"..","..","..","dist",kl)]}function qf(e=Bf()){let t=e.find((n)=>Cl(n)&&Of(n).isFile());if(!t)throw Error("Packaged Amp plugin artifact not found. Reinstall cc-safety-net and try again.");return t}function Sl(e){try{return JSON.parse(e)}catch{return}}function Dn(e){return e.subarray(0,Buffer.byteLength(po)).toString("utf-8")===po}async function Ht(e,t,n){let r=await e(t,n);if(r.status===0)return r;throw Error([`Failed to run ${t.join(" ")}${r.status===null?"":` (exit ${r.status})`}.`,[r.stdout,r.stderr].filter(Boolean).join(`
196
+ `).length};return new Promise((a)=>{let l=(d)=>{t.off("keypress",c),t.setRawMode(r),t.pause(),i(),a(d)};function c(d,p){e.onKey(d,p,{finish:l,draw:s})}t.on("keypress",c),s()})}function Ml(e={}){let t=0;return Hl({input:e.input??process.stdin,output:e.output??process.stdout,render:()=>lm(t,e.globalHookInstalled===!0),onKey:(n,r,o)=>{if(r.ctrl&&r.name==="c"){o.finish(null),(e.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(r.name==="escape"||n==="q")return o.finish(null);if(r.name==="return"||r.name==="enter")return o.finish(Il[t]);if(r.name==="up"||r.name==="down"||n==="k"||n==="j")t=(t+1)%Il.length,o.draw()}})}function Lo(e=process.stdin,t=process.stdout){return Boolean(e.isTTY&&t.isTTY&&typeof e.setRawMode==="function")}function jl(e,t,n={}){let r=n.output??process.stdout,o=im(t);return Hl({input:n.input??process.stdin,output:r,render:()=>am(e,t,o),onKey:(i,s,a)=>{let l=om(e,i,s);if(!l)return;let c=sm(o,t,l);if(o=c.state,c.done==="interrupt"){a.finish(null),(n.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(c.done==="abort")return a.finish(null);if(c.done==="update")return a.finish("update");if(c.done==="confirm"){if(o.selected.length===0){r.write("\x07"),a.draw();return}a.finish([...o.selected]),r.write(`${tm(e)} selected integrations...
197
+ `);return}a.draw()}})}import{existsSync as Gl,lstatSync as dm,mkdirSync as um,mkdtempSync as pm,readdirSync as fm,readFileSync as pt,rmSync as In}from"node:fs";import{tmpdir as mm}from"node:os";import{basename as gm,dirname as hm,join as U}from"node:path";import{fileURLToPath as ym}from"node:url";var vo="// cc-safety-net managed Amp plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --amp",He="cc-safety-net",Me="cc-safety-net/index.ts";import{spawn as cm}from"node:child_process";var bo=(e,t)=>{let n=_e([...e],process.env);return new Promise((r)=>{let o=cm(n.cmd,n.args,{cwd:t,stdio:["ignore","pipe","pipe"]}),i=to(o),s=!1,a=setTimeout(()=>{s=!0,o.kill()},120000);o.on("error",(l)=>{clearTimeout(a),r({status:null,errorCode:l.code,stdout:i.stdout,stderr:[l.message,i.stderr].filter(Boolean).join(`
198
+ `)})}),o.on("close",(l)=>{clearTimeout(a),r({status:s?null:l,errorCode:s?"ETIMEDOUT":void 0,stdout:i.stdout,stderr:i.stderr})})})};var ut="cc-safety-net.ts",Ul=U("amp",Me);function Lm(e){return U(e,".config","amp","plugins","cc-safety-net.ts")}function vm(){let e=hm(ym(import.meta.url));return[U(e,"..",Ul),U(e,"..","..","..","dist",Ul)]}function bm(e=vm()){let t=e.find((n)=>Gl(n)&&dm(n).isFile());if(!t)throw Error("Packaged Amp plugin artifact not found. Reinstall cc-safety-net and try again.");return t}function Bl(e){try{return JSON.parse(e)}catch{return}}function _n(e){return e.subarray(0,Buffer.byteLength(vo)).toString("utf-8")===vo}async function Ut(e,t,n){let r=await e(t,n);if(r.status===0)return r;throw Error([`Failed to run ${t.join(" ")}${r.status===null?"":` (exit ${r.status})`}.`,[r.stdout,r.stderr].filter(Boolean).join(`
198
199
  `).trim()].filter(Boolean).join(`
199
- `))}async function Dl(e){let t=await e(["amp","plugins","repositories","--json"]);if(t.status===null)throw Error(`${t.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 (${t.errorCode??"terminated"}). Check that the amp CLI responds and rerun install --amp.`}
200
+ `))}async function ql(e){let t=await e(["amp","plugins","repositories","--json"]);if(t.status===null)throw Error(`${t.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 (${t.errorCode??"terminated"}). Check that the amp CLI responds and rerun install --amp.`}
200
201
  ${t.stderr}`.trim());if(t.status!==0)throw Error(`Failed to run amp plugins repositories --json (exit ${t.status}). Sign in with "amp login" and rerun install --amp.
201
202
  ${[t.stdout,t.stderr].filter(Boolean).join(`
202
- `)}`.trim());let n=Sl(t.stdout),r=(Array.isArray(n)?n:[]).filter((o)=>b(o,"scope")==="user"&&b(o,"exists")===!0&&b(o,"viewerCanWrite")===!0).map((o)=>b(o,"cloneRef")).find((o)=>typeof o==="string"&&o.length>0);if(!r)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 r}async function Rl(e,t){let n=Nf(U(Hf(),"cc-safety-net-amp-"));try{return await Ht(e,["amp","clone","user-plugins",n]),await t(n)}finally{Sn(n,{recursive:!0,force:!0})}}function mo(e){return`rerun ${e==="overwrite"?"install":"uninstall"} --amp`}function Al(e,t,n){let r=U(e,t),o=E(r);if(!o)return;if(o.isSymbolicLink()||!o.isFile())throw Error(`Refusing to ${n} ${t} in your Amp personal plugins repository: not a regular file. Remove it there and ${mo(n)}.`);let i=dt(r);if(Dn(i))return i;throw Error(`Refusing to ${n} unmanaged file ${t} in your Amp personal plugins repository. Remove it there and ${mo(n)}.`)}function El(e,t){let n=U(e,Ne),r=E(n);if(!r)return;if(r.isSymbolicLink()||!r.isDirectory())throw Error(`Refusing to ${t} ${Ne} in your Amp personal plugins repository: not a regular directory. Remove it there and ${mo(t)}.`);return Al(e,Fe,t)}function Vf(e){let t=U(e,ct),n=E(t);if(!n||n.isSymbolicLink()||!n.isFile())return;let r=dt(t);return Dn(r)?r:void 0}async function Pl(e,t,n,r){if(await Ht(e,n,t),(await Ht(e,["git","status","--porcelain"],t)).stdout.trim()==="")return!1;return await Ht(e,["git","-c","commit.gpgsign=false","-c","user.name=cc-safety-net","-c","user.email=cc-safety-net@localhost","commit","-m",r],t),await Ht(e,["git","push","origin","HEAD"],t),!0}function kn(e,t){zf(e,t),Kf(e,t)}function Tl(e,t){if(t==="keep")return;throw Error(`Local Amp plugin ${e} is not a managed copy and masks the personal plugin. Remove it and rerun install --amp.`)}function zf(e,t){let n=Gf(e),r=E(n);if(!r)return;if(!r.isSymbolicLink()&&r.isFile()&&Dn(dt(n))){Sn(n);return}Tl(n,t)}function Kf(e,t){let n=U(e,".config","amp","plugins",Ne),r=E(n);if(!r)return;if(!r.isSymbolicLink()&&r.isDirectory()&&Wf(n)){Sn(n,{recursive:!0});return}Tl(n,t)}function Wf(e){let t=Mf(Fe);if(Ff(e).join("\x00")!==t)return!1;let n=U(e,t),r=E(n);return!!r&&!r.isSymbolicLink()&&r.isFile()&&Dn(dt(n))}function Jf(){let e=wt();if(!Cl(e))return"";let t=Sl(dt(e,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))return"";return`;globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__ = ${JSON.stringify(Cn(t))};
203
- `}async function Il(e,t=qf(),n=fo){let r=Buffer.concat([dt(t),Buffer.from(Jf(),"utf-8")]),o=await Dl(n);return Rl(n,async(i)=>{let s=`${o}/${Ne}`,a=El(i,"overwrite"),l=Al(i,ct,"overwrite");if(a?.equals(r)&&!l)return kn(e,"fail"),{path:s,alreadyInstalled:!0};if($f(U(i,Ne),{recursive:!0}),_(U(i,Fe),r),l)Sn(U(i,ct));let c=await Pl(n,i,["git","add","--",Fe,...l?[ct]:[]],`chore: update cc-safety-net plugin to v${P()}`);return kn(e,"fail"),{path:s,alreadyInstalled:!c}})}async function _l(e,t=fo){let n=await Dl(t);return Rl(t,async(r)=>{let o=El(r,"remove"),i=Vf(r),s=`${n}/${i&&!o?ct:Ne}`;if(!o&&!i)return kn(e,"keep"),{path:s,alreadyInstalled:!1};return await Pl(t,r,["git","rm","--",...o?[Fe]:[],...i?[ct]:[]],`chore: remove cc-safety-net plugin v${P()}`),kn(e,"keep"),{path:s,alreadyInstalled:!0}})}import{existsSync as Ol,mkdirSync as Yf,readFileSync as Zf}from"node:fs";import{dirname as Xf}from"node:path";var go="npx -y cc-safety-net hook --agy-cli",He="cc-safety-net";function Me(e){return Boolean(e)&&typeof e==="object"&&!Array.isArray(e)}function An(){return{PreToolUse:[{hooks:[{type:"command",command:go,timeout:30}]}]}}function $l(e){try{let t=JSON.parse(Zf(e,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))throw Error("Antigravity hooks config must be a JSON object");return t}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Antigravity hooks config ${e}: ${t.message}`);throw t}}function Nl(e){let t=e[He];if(t===void 0){let r=An();return e[He]=r,{definition:r,preToolUse:r.PreToolUse??[]}}if(!Me(t))throw Error(`Antigravity hooks config entry "${He}" must be an object`);let n=Array.isArray(t.PreToolUse)?t.PreToolUse:[];return t.PreToolUse=n,{definition:t,preToolUse:n}}function Fl(e){if(!Array.isArray(e.PreToolUse))return!1;return e.PreToolUse.some((t)=>Me(t)&&Array.isArray(t.hooks)&&t.hooks.some((n)=>Me(n)&&n.command===go))}function Qf(e){return Object.values(e).some((t)=>Me(t)&&t.enabled!==!1&&Fl(t))}function em(e){if(e[He]===void 0)return!1;let t=Nl(e);if(t.definition.enabled!==!1||!Fl(t.definition))return!1;return t.definition.enabled=!0,!0}function tm(e){if(e[He]===void 0){e[He]=An();return}let t=Nl(e);t.definition.enabled=!0,t.preToolUse.push(An().PreToolUse?.[0]??{hooks:[]})}function nm(e){let t=!1;for(let n of Object.values(e)){if(!Me(n)||!Array.isArray(n.PreToolUse))continue;n.PreToolUse=n.PreToolUse.flatMap((r)=>{if(!Me(r)||!Array.isArray(r.hooks))return[r];let o=r.hooks.filter((i)=>!Me(i)||i.command!==go);if(o.length!==r.hooks.length)t=!0;return o.length===0?[]:[{...r,hooks:o}]})}return t}function Rn(e,t){_(e,`${JSON.stringify(t,null,2)}
204
- `)}function Hl(e){let t=St(e);if(Yf(Xf(t),{recursive:!0}),!Ol(t))return Rn(t,{[He]:An()}),{path:t,alreadyInstalled:!1};let n=$l(t);if(Qf(n))return{path:t,alreadyInstalled:!0};if(em(n))return Rn(t,n),{path:t,alreadyInstalled:!1};return tm(n),Rn(t,n),{path:t,alreadyInstalled:!1}}function Ml(e){let t=St(e);if(!Ol(t))return{path:t,alreadyInstalled:!1};let n=$l(t);if(!nm(n))return{path:t,alreadyInstalled:!1};return Rn(t,n),{path:t,alreadyInstalled:!0}}import{existsSync as rm,readdirSync as om,rmSync as im}from"node:fs";import{join as sm}from"node:path";function jl(e,t=process.platform,n){if(!rm(e))return;let r=t==="win32"?/^bunx-\d+-cc-safety-net@/:new RegExp(`^bunx-${process.getuid?.()??0}-cc-safety-net@`);om(e).filter((o)=>o!==n&&r.test(o)).forEach((o)=>{im(sm(e,o),{recursive:!0,force:!0})})}import{spawn as am}from"node:child_process";var se=V.map((e)=>({target:e.id,flag:e.flag,label:R(e.id),probeCommand:e.probeCommand}));function ho(e){let t=new Set(e);return se.map((n)=>n.target).filter((n)=>t.has(n))}async function Ul(e,t){for(let n of e)await t(n)}var lm=5000;function yo(e){return new Promise((t)=>{let n=Ie([...e],process.env),r=am(n.cmd,n.args,{env:process.env,stdio:"ignore"}),o=!1,i=(a)=>{if(o)return;o=!0,clearTimeout(s),t(a)},s=setTimeout(()=>{r.kill(),i(!1)},lm);r.on("error",()=>i(!1)),r.on("close",(a)=>i(a===0))})}function Gl(e=yo,t={}){let n=new Set(t.configuredTargets??[]);return Promise.all(se.map(async(r)=>({target:r.target,flag:r.flag,label:r.label,...ql(t.action,await e(r.probeCommand),n.has(r.target))})))}function Bl(e,t){let n=new Set(t.configuredTargets??[]);return e.map((r)=>({...r,...ql(t.action,r.available,n.has(r.target))}))}function ql(e,t,n){if(e==="uninstall")return n?{available:!0}:{available:!1,unavailableReason:"not installed"};if(e==="install"&&n)return{available:!1,unavailableReason:"already installed"};if(!t)return{available:!1,unavailableReason:"CLI not installed"};return{available:!0}}import{existsSync as Vl,readdirSync as cm,rmSync as dm}from"node:fs";import{join as ut}from"node:path";function En(e,t=process.platform){let n=ut(process.env.npm_config_cache||(t==="win32"?ut(process.env.LOCALAPPDATA||ut(e,"AppData","Local"),"npm-cache"):ut(e,".npm")),"_npx");if(!Vl(n))return;cm(n).filter((r)=>Vl(ut(n,r,"node_modules","cc-safety-net"))).forEach((r)=>{dm(ut(n,r),{recursive:!0,force:!0})})}import{existsSync as Kl,mkdirSync as um,readFileSync as Wl}from"node:fs";import{dirname as pm,join as zl}from"node:path";var Mt="npx -y cc-safety-net hook --kimi-code",Lo=`[[hooks]]
203
+ `)}`.trim());let n=Bl(t.stdout),r=(Array.isArray(n)?n:[]).filter((o)=>b(o,"scope")==="user"&&b(o,"exists")===!0&&b(o,"viewerCanWrite")===!0).map((o)=>b(o,"cloneRef")).find((o)=>typeof o==="string"&&o.length>0);if(!r)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 r}async function Vl(e,t){let n=pm(U(mm(),"cc-safety-net-amp-"));try{return await Ut(e,["amp","clone","user-plugins",n]),await t(n)}finally{In(n,{recursive:!0,force:!0})}}function wo(e){return`rerun ${e==="overwrite"?"install":"uninstall"} --amp`}function zl(e,t,n){let r=U(e,t),o=E(r);if(!o)return;if(o.isSymbolicLink()||!o.isFile())throw Error(`Refusing to ${n} ${t} in your Amp personal plugins repository: not a regular file. Remove it there and ${wo(n)}.`);let i=pt(r);if(_n(i))return i;throw Error(`Refusing to ${n} unmanaged file ${t} in your Amp personal plugins repository. Remove it there and ${wo(n)}.`)}function Kl(e,t){let n=U(e,He),r=E(n);if(!r)return;if(r.isSymbolicLink()||!r.isDirectory())throw Error(`Refusing to ${t} ${He} in your Amp personal plugins repository: not a regular directory. Remove it there and ${wo(t)}.`);return zl(e,Me,t)}function wm(e){let t=U(e,ut),n=E(t);if(!n||n.isSymbolicLink()||!n.isFile())return;let r=pt(t);return _n(r)?r:void 0}async function Wl(e,t,n,r){if(await Ut(e,n,t),(await Ut(e,["git","status","--porcelain"],t)).stdout.trim()==="")return!1;return await Ut(e,["git","-c","commit.gpgsign=false","-c","user.name=cc-safety-net","-c","user.email=cc-safety-net@localhost","commit","-m",r],t),await Ut(e,["git","push","origin","HEAD"],t),!0}function Pn(e,t){km(e,t),xm(e,t)}function Jl(e,t){if(t==="keep")return;throw Error(`Local Amp plugin ${e} is not a managed copy and masks the personal plugin. Remove it and rerun install --amp.`)}function km(e,t){let n=Lm(e),r=E(n);if(!r)return;if(!r.isSymbolicLink()&&r.isFile()&&_n(pt(n))){In(n);return}Jl(n,t)}function xm(e,t){let n=U(e,".config","amp","plugins",He),r=E(n);if(!r)return;if(!r.isSymbolicLink()&&r.isDirectory()&&Cm(n)){In(n,{recursive:!0});return}Jl(n,t)}function Cm(e){let t=gm(Me);if(fm(e).join("\x00")!==t)return!1;let n=U(e,t),r=E(n);return!!r&&!r.isSymbolicLink()&&r.isFile()&&_n(pt(n))}function Sm(){let e=kt();if(!Gl(e))return"";let t=Bl(pt(e,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))return"";return`;globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__ = ${JSON.stringify(Tn(t))};
204
+ `}async function Yl(e,t=bm(),n=bo){let r=Buffer.concat([pt(t),Buffer.from(Sm(),"utf-8")]),o=await ql(n);return Vl(n,async(i)=>{let s=`${o}/${He}`,a=Kl(i,"overwrite"),l=zl(i,ut,"overwrite");if(a?.equals(r)&&!l)return Pn(e,"fail"),{path:s,alreadyInstalled:!0};if(um(U(i,He),{recursive:!0}),I(U(i,Me),r),l)In(U(i,ut));let c=await Wl(n,i,["git","add","--",Me,...l?[ut]:[]],`chore: update cc-safety-net plugin to v${T()}`);return Pn(e,"fail"),{path:s,alreadyInstalled:!c}})}async function Zl(e,t=bo){let n=await ql(t);return Vl(t,async(r)=>{let o=Kl(r,"remove"),i=wm(r),s=`${n}/${i&&!o?ut:He}`;if(!o&&!i)return Pn(e,"keep"),{path:s,alreadyInstalled:!1};return await Wl(t,r,["git","rm","--",...o?[Me]:[],...i?[ut]:[]],`chore: remove cc-safety-net plugin v${T()}`),Pn(e,"keep"),{path:s,alreadyInstalled:!0}})}import{existsSync as Xl,mkdirSync as Dm,readFileSync as Rm}from"node:fs";import{dirname as Am}from"node:path";var ko="npx -y cc-safety-net hook --agy-cli",je="cc-safety-net";function Ue(e){return Boolean(e)&&typeof e==="object"&&!Array.isArray(e)}function $n(){return{PreToolUse:[{hooks:[{type:"command",command:ko,timeout:30}]}]}}function Ql(e){try{let t=JSON.parse(Rm(e,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))throw Error("Antigravity hooks config must be a JSON object");return t}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Antigravity hooks config ${e}: ${t.message}`);throw t}}function ec(e){let t=e[je];if(t===void 0){let r=$n();return e[je]=r,{definition:r,preToolUse:r.PreToolUse??[]}}if(!Ue(t))throw Error(`Antigravity hooks config entry "${je}" must be an object`);let n=Array.isArray(t.PreToolUse)?t.PreToolUse:[];return t.PreToolUse=n,{definition:t,preToolUse:n}}function tc(e){if(!Array.isArray(e.PreToolUse))return!1;return e.PreToolUse.some((t)=>Ue(t)&&Array.isArray(t.hooks)&&t.hooks.some((n)=>Ue(n)&&n.command===ko))}function Em(e){return Object.values(e).some((t)=>Ue(t)&&t.enabled!==!1&&tc(t))}function Pm(e){if(e[je]===void 0)return!1;let t=ec(e);if(t.definition.enabled!==!1||!tc(t.definition))return!1;return t.definition.enabled=!0,!0}function Tm(e){if(e[je]===void 0){e[je]=$n();return}let t=ec(e);t.definition.enabled=!0,t.preToolUse.push($n().PreToolUse?.[0]??{hooks:[]})}function Im(e){let t=!1;for(let n of Object.values(e)){if(!Ue(n)||!Array.isArray(n.PreToolUse))continue;n.PreToolUse=n.PreToolUse.flatMap((r)=>{if(!Ue(r)||!Array.isArray(r.hooks))return[r];let o=r.hooks.filter((i)=>!Ue(i)||i.command!==ko);if(o.length!==r.hooks.length)t=!0;return o.length===0?[]:[{...r,hooks:o}]})}return t}function On(e,t){I(e,`${JSON.stringify(t,null,2)}
205
+ `)}function nc(e){let t=Dt(e);if(Dm(Am(t),{recursive:!0}),!Xl(t))return On(t,{[je]:$n()}),{path:t,alreadyInstalled:!1};let n=Ql(t);if(Em(n))return{path:t,alreadyInstalled:!0};if(Pm(n))return On(t,n),{path:t,alreadyInstalled:!1};return Tm(n),On(t,n),{path:t,alreadyInstalled:!1}}function rc(e){let t=Dt(e);if(!Xl(t))return{path:t,alreadyInstalled:!1};let n=Ql(t);if(!Im(n))return{path:t,alreadyInstalled:!1};return On(t,n),{path:t,alreadyInstalled:!0}}import{existsSync as _m,readdirSync as Om,rmSync as $m}from"node:fs";import{join as Nm}from"node:path";function oc(e,t=process.platform,n){if(!_m(e))return;let r=t==="win32"?/^bunx-\d+-cc-safety-net@/:new RegExp(`^bunx-${process.getuid?.()??0}-cc-safety-net@`);Om(e).filter((o)=>o!==n&&r.test(o)).forEach((o)=>{$m(Nm(e,o),{recursive:!0,force:!0})})}import{spawn as Fm}from"node:child_process";var ae=z.map((e)=>({target:e.id,flag:e.flag,label:R(e.id),probeCommand:e.probeCommand}));function xo(e){let t=new Set(e);return ae.map((n)=>n.target).filter((n)=>t.has(n))}async function ic(e,t){for(let n of e)await t(n)}var Hm=5000;function Co(e){return new Promise((t)=>{let n=_e([...e],process.env),r=Fm(n.cmd,n.args,{env:process.env,stdio:"ignore"}),o=!1,i=(a)=>{if(o)return;o=!0,clearTimeout(s),t(a)},s=setTimeout(()=>{r.kill(),i(!1)},Hm);r.on("error",()=>i(!1)),r.on("close",(a)=>i(a===0))})}function sc(e=Co,t={}){let n=new Set(t.configuredTargets??[]);return Promise.all(ae.map(async(r)=>({target:r.target,flag:r.flag,label:r.label,...lc(t.action,await e(r.probeCommand),n.has(r.target))})))}function ac(e,t){let n=new Set(t.configuredTargets??[]);return e.map((r)=>({...r,...lc(t.action,r.available,n.has(r.target))}))}function lc(e,t,n){if(e==="uninstall")return n?{available:!0}:{available:!1,unavailableReason:"not installed"};if(e==="install"&&n)return{available:!1,unavailableReason:"already installed"};if(!t)return{available:!1,unavailableReason:"CLI not installed"};return{available:!0}}import{existsSync as cc,readdirSync as Mm,rmSync as jm}from"node:fs";import{join as ft}from"node:path";function Nn(e,t=process.platform){let n=ft(process.env.npm_config_cache||(t==="win32"?ft(process.env.LOCALAPPDATA||ft(e,"AppData","Local"),"npm-cache"):ft(e,".npm")),"_npx");if(!cc(n))return;Mm(n).filter((r)=>cc(ft(n,r,"node_modules","cc-safety-net"))).forEach((r)=>{jm(ft(n,r),{recursive:!0,force:!0})})}import{existsSync as uc,mkdirSync as Um,readFileSync as pc}from"node:fs";import{dirname as Gm,join as dc}from"node:path";var Gt="npx -y cc-safety-net hook --kimi-code",So=`[[hooks]]
205
206
  event = "PreToolUse"
206
- command = "${Mt}"`,vo=`{ event = "PreToolUse", command = "${Mt}" }`;function Jl(e){return zl(process.env.KIMI_CODE_HOME??zl(e,".kimi-code"),"config.toml")}function fm(e){return e.split(`
207
+ command = "${Gt}"`,Do=`{ event = "PreToolUse", command = "${Gt}" }`;function fc(e){return dc(process.env.KIMI_CODE_HOME??dc(e,".kimi-code"),"config.toml")}function Bm(e){return e.split(`
207
208
  `).reduce((n,r)=>{if(/^\s*\[/.test(r))return n.activeTable=!0,n.lines.push(r),n;if(!n.activeTable&&/^\s*hooks\s*=\s*\[\s*]\s*(?:#.*)?$/.test(r))return n;return n.lines.push(r),n},{activeTable:!1,lines:[]}).lines.join(`
208
- `)}function mm(e,t){if(e[t]!=="#")return t;let n=e.indexOf(`
209
- `,t+1);return n===-1?e.length:n+1}function gm(e,t){return hn(e,t,{skipComment:mm,stringError:"Unterminated string in Kimi Code config",bracketError:"Unmatched hooks array in Kimi Code config"})}function Yl(e){let t=!1,n=0;while(n<e.length){let r=e.indexOf(`
210
- `,n),o=r===-1?e.length:r,i=e.slice(n,o);if(/^\s*\[/.test(i))t=!0;if(!t){let s=/^(\s*)hooks\s*=\s*\[/.exec(i);if(s){let a=n+s[0].lastIndexOf("[");return{start:a,end:gm(e,a)}}}n=r===-1?e.length:r+1}return}function hm(e,t){let n=e.slice(0,t.end).trimEnd(),r=Ua(e,t.end),o=r===""?" ":`${r} `,i=!n.endsWith("[")&&!n.endsWith(",");return`${n}${i?",":""}
211
- ${o}${vo}${e.slice(t.end)}`}function ym(e){let t=Yl(e);if(t&&e.slice(t.start+1,t.end).trim())return hm(e,t);let n=fm(e).trimEnd();if(n==="")return`${Lo}
209
+ `)}function qm(e,t){if(e[t]!=="#")return t;let n=e.indexOf(`
210
+ `,t+1);return n===-1?e.length:n+1}function Vm(e,t){return xn(e,t,{skipComment:qm,stringError:"Unterminated string in Kimi Code config",bracketError:"Unmatched hooks array in Kimi Code config"})}function mc(e){let t=!1,n=0;while(n<e.length){let r=e.indexOf(`
211
+ `,n),o=r===-1?e.length:r,i=e.slice(n,o);if(/^\s*\[/.test(i))t=!0;if(!t){let s=/^(\s*)hooks\s*=\s*\[/.exec(i);if(s){let a=n+s[0].lastIndexOf("[");return{start:a,end:Vm(e,a)}}}n=r===-1?e.length:r+1}return}function zm(e,t){let n=e.slice(0,t.end).trimEnd(),r=il(e,t.end),o=r===""?" ":`${r} `,i=!n.endsWith("[")&&!n.endsWith(",");return`${n}${i?",":""}
212
+ ${o}${Do}${e.slice(t.end)}`}function Km(e){let t=mc(e);if(t&&e.slice(t.start+1,t.end).trim())return zm(e,t);let n=Bm(e).trimEnd();if(n==="")return`${So}
212
213
  `;return`${n}
213
214
 
214
- ${Lo}
215
- `}function Lm(e){return e.split(/(?=^\s*\[)/m).filter((n)=>!/^\s*\[\[hooks]]\s*$/m.test(n)||!n.includes(Mt)).join("").trimEnd()}function vm(e,t){let n=e.indexOf(vo,t.start);if(n===-1||n>t.end)return e;return yn(e,{start:n,end:n+vo.length})}function Zl(e){let t=Jl(e);if(um(pm(t),{recursive:!0}),!Kl(t))return _(t,`${Lo}
216
- `),{path:t,alreadyInstalled:!1};let n=Wl(t,"utf-8");if(n.includes(Mt))return{path:t,alreadyInstalled:!0};return _(t,ym(n)),{path:t,alreadyInstalled:!1}}function Xl(e){let t=Jl(e);if(!Kl(t))return{path:t,alreadyInstalled:!1};let n=Wl(t,"utf-8");if(!n.includes(Mt))return{path:t,alreadyInstalled:!1};let r=Yl(n),o=r?vm(n,r):`${Lm(n)}
217
- `;return _(t,o),{path:t,alreadyInstalled:!0}}var wo="safety-net@cc-marketplace",Ql=new Set(["claude-code","codex","copilot-cli","gemini-cli","hermes-agent","openclaw","opencode","pi"]),ec=new Set(["antigravity-cli","cursor","hermes-agent","kimi-code"]);function ko(e){return/^\s*safety-net@cc-marketplace[^a-z0-9-][^\n]*installed,/m.test(e??"")}function ic(e){return/^\s*cc-safety-net[^a-z0-9-][^\n]*installed,/m.test(e??"")}function xm(e){return/^Marketplace `cc-marketplace`\s*$/m.test(e??"")}var sc={"claude-code":{installCommands:(e)=>{let t=sn(e,"cc-safety-net@cc-marketplace");return{commands:[...t?[["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"]],...Ir(e).status==="disabled"?[["claude","plugin","enable","cc-safety-net@cc-marketplace"]]:[]],cleanupCommands:sn(e,wo)?[["claude","plugin","uninstall",wo]]:[],update:t}},uninstallCommands:[["claude","plugin","uninstall","cc-safety-net@cc-marketplace"],["claude","plugin","marketplace","remove","cc-marketplace"]]},codex:{installCommands:async(e,t)=>{let n=t??await ie(["codex","plugin","list"]),r=ic(n);return{commands:[r||xm(n)?["codex","plugin","marketplace","upgrade","cc-marketplace"]:["codex","plugin","marketplace","add","kenryu42/cc-marketplace"],["codex","plugin","add","cc-safety-net@cc-marketplace"]],cleanupCommands:ko(n)?[["codex","plugin","remove","safety-net@cc-marketplace"]]:[],update:r}},uninstallCommands:[["codex","plugin","remove","cc-safety-net@cc-marketplace"],["codex","plugin","marketplace","remove","cc-marketplace"]],postInstallMessage:"Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it."},"copilot-cli":{installCommands:async()=>{let e=await ie(["copilot","plugin","list"]),t=[...Qs(e)?[["copilot","plugin","uninstall","copilot-safety-net"]]:[],...ea(e)?[["copilot","plugin","uninstall",Ys]]:[]];if(Zs(e))return{commands:[["copilot","plugin","marketplace","update","cc-marketplace"],["copilot","plugin","update",oe]],cleanupCommands:t,update:!0};return{commands:[Xs(await ie(["copilot","plugin","marketplace","list"]))?["copilot","plugin","marketplace","update","cc-marketplace"]:["copilot","plugin","marketplace","add","kenryu42/cc-marketplace"],["copilot","plugin","install",oe]],cleanupCommands:t}},uninstallCommands:[["copilot","plugin","uninstall","cc-safety-net@cc-marketplace"],["copilot","plugin","marketplace","remove","cc-marketplace"]]},"gemini-cli":{installCommands:(e)=>{let t=Mr(e);if(t.status==="configured")return{commands:[["gemini","extensions","update","gemini-safety-net"]],update:!0};if(t.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:Xr,installCommands:()=>({commands:_a()}),uninstallCommands:[["openclaw","plugins","uninstall",A,"--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(`
218
- `)},opencode:{beforeInstall:to,installCommands:[["opencode","plugin","-g","-f","cc-safety-net@latest"]]},pi:{installCommands:[["pi","install","npm:cc-safety-net"]],uninstallCommands:[["pi","uninstall","npm:cc-safety-net"]]}};function Tn(){return process.env.HOME??bm()}function ac(e,t=(n)=>n){try{let n=JSON.parse(t(oc(e,"utf-8")));if(!n||typeof n!=="object"||Array.isArray(n))throw Error(`Settings file ${e} must be a JSON object`);return n}catch(n){if(n instanceof SyntaxError)throw Error(`Failed to parse ${e}: ${n.message}`);throw n}}function km(e){let t=bo(Tt(e),"settings.json");if(!xo(t))return;let n=ac(t,q),r=n.enabledPlugins;if(!r||typeof r!=="object"||Array.isArray(r))return;if(r[oe]!==!1)return;let o=oc(t,"utf-8"),i=o.replace(new RegExp(`("${oe}"\\s*:\\s*)false`),"$1true");return r[oe]=!0,_(t,i!==o?i:`${JSON.stringify(n,null,2)}
219
- `),`Enabled ${oe} plugin in ${t}`}function Cm(e){let t=no(e);if(!xo(t))return;let n=ac(t);if(!Array.isArray(n.packages))return;let r=n.packages.find((o)=>!!o&&typeof o==="object"&&!Array.isArray(o)&&ro(o.source)&&("extensions"in o));if(!r)return;return delete r.extensions,_(t,`${JSON.stringify(n,null,2)}
220
- `),`Enabled npm:cc-safety-net extensions in ${t}`}function tc(e,t){let n=T({label:t,booleans:Object.fromEntries(se.map((i)=>[i.target,[i.flag]]))},e),r=n.errors[0];if(r)throw Error(r);let o=se.filter((i)=>n.flags[i.target]).map((i)=>i.target);if(o.length!==1)throw Error(`Choose exactly one ${t} target: ${se.map((i)=>i.flag).join(", ")}`);return o[0]}async function lc(e=Tn(),t=nt){let[n,r,o]=await Promise.all([t(["amp","plugins","list"],30000),t(["codex","plugin","list"],30000),t(["copilot","--binary-version"])]);return{codexPluginListOutput:r,hooks:lt(process.cwd(),{homeDir:e,ampPluginListOutput:n,codexPluginListOutput:r,copilotCliVersion:o})}}async function Sm(e,t=nt){let n=await lc(Tn(),t);return n.hooks.filter((r)=>e==="install"?r.configured:r.detected||r.inspectionStatus==="not-inspected").filter((r)=>r.platform!=="codex"||!ko(n.codexPluginListOutput)||ic(n.codexPluginListOutput)).map((r)=>r.platform)}function Dm(e,t,n){if(t.length>0)return{finish:async()=>[tc(t,e)]};if(!n.selectTargets&&!uo(n.input,n.output))return{finish:async()=>[tc(t,e)]};let r=n.detectConfiguredTargets??(()=>Sm(e,n.fetchVersion)),o=Promise.all([Gl(n.probeTargets),r()]);return{ready:o,finish:async()=>{let[i,s]=await o,a=Bl(i,{action:e,configuredTargets:s}),l=n.selectTargets?await n.selectTargets(e,rc(e,a)):await xl(e,rc(e,a),{input:n.input,output:n.output});if(l==="update")return l;if(!l||l.length===0)return null;return ho(l)}}}async function je(e,t,n=!1,r){let o=sc[e];o.beforeInstall?.(t);let i=typeof o.installCommands==="function"?await o.installCommands(t,r):{commands:o.installCommands};return await Jr(i.commands),await Ra(i.cleanupCommands??[]),[`${i.update||n?"Updated":"Installed"} ${R(e)} integration`,o.postInstallMessage].filter(Boolean).join(`
221
- `)}async function pt(e){let t=sc[e];if(!t.uninstallCommands)throw Error(`${R(e)} uninstall is not supported`);return await Jr(t.uninstallCommands),`Uninstalled ${R(e)} integration`}function Rm(e){let t=Xa(e);return t.alreadyInstalled?`Uninstalled OpenCode plugin from ${t.path}`:`OpenCode plugin not installed in ${t.path}`}var Am={"antigravity-cli":{install:Hl,uninstall:Ml},cursor:{install:da,uninstall:ua},"kimi-code":{install:Zl,uninstall:Xl}};function ft(e,t,n,r=!1){if(e==="install"&&!r)En(n);let o=Am[t][e](n),i=R(t),s=e!=="install"?"Uninstalled":r?"Updated":"Installed";return e==="install"&&o.alreadyInstalled?r?`${i} hook up to date in ${o.path}`:`${i} hook already installed in ${o.path}`:e==="uninstall"&&!o.alreadyInstalled?`${i} hook not installed in ${o.path}`:`${s} ${i} hook ${e==="install"?"in":"from"} ${o.path}`}var Em={amp:{install:Il,uninstall:_l,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:ya,uninstall:La,afterInstall:async(e)=>{let t=zr(e);return await ie(["hermes","plugins","enable",z,"--no-allow-tool-override"]),!t},beforeUninstall:async(e)=>{Vr(e);try{await ie(["hermes","plugins","disable",z])}catch(t){console.warn(`${t instanceof Error?t.message:String(t)}
222
- Removing the plugin files anyway; ${z} may still be listed in the Hermes config.`)}},restartNote:"Restart Hermes to apply the change."}};async function Pn(e,t,n,r=!1){let o=Em[t];if(e==="uninstall")await o.beforeUninstall?.(n);let i=e==="install"?await o.install(n):await o.uninstall(n),s=e==="install"&&await o.afterInstall?.(n),a=R(t),l=!s&&(e==="install"&&i.alreadyInstalled||e==="uninstall"&&!i.alreadyInstalled);return[l?e==="install"?`${a} plugin ${r?"up to date":"already installed"} at ${i.path}`:`${a} plugin not installed at ${i.path}`:`${e!=="install"?"Uninstalled":r?"Updated":"Installed"} ${a} plugin ${e==="install"?"at":"from"} ${i.path}`,l?void 0:o.restartNote].filter(Boolean).join(`
223
- `)}var Pm={amp:{install:(e,t)=>Pn("install","amp",e,t),uninstall:(e)=>Pn("uninstall","amp",e)},"antigravity-cli":{install:(e,t)=>ft("install","antigravity-cli",e,t),uninstall:(e)=>ft("uninstall","antigravity-cli",e)},"claude-code":{install:(e,t)=>je("claude-code",e,t),uninstall:()=>pt("claude-code")},codex:{install:(e,t,n)=>je("codex",e,t,n),uninstall:()=>pt("codex")},"copilot-cli":{install:async(e,t)=>[await je("copilot-cli",e,t),km(e)].filter(Boolean).join(`
224
- `),uninstall:()=>pt("copilot-cli")},cursor:{install:(e,t)=>ft("install","cursor",e,t),uninstall:(e)=>ft("uninstall","cursor",e)},"gemini-cli":{install:(e,t)=>je("gemini-cli",e,t),uninstall:()=>pt("gemini-cli")},"hermes-agent":{install:(e,t)=>{if(!t)En(e);return Pn("install","hermes-agent",e,t)},uninstall:(e)=>Pn("uninstall","hermes-agent",e)},"kimi-code":{install:(e,t)=>ft("install","kimi-code",e,t),uninstall:(e)=>ft("uninstall","kimi-code",e)},openclaw:{install:async(e,t)=>{let n=await je("openclaw",e,t);return await Oa(),n},uninstall:(e)=>(Xr(e),pt("openclaw"))},opencode:{install:async(e,t)=>{let n=await je("opencode",e,t);return await Wa(e),n},uninstall:(e)=>Rm(e)},pi:{install:async(e,t)=>[await je("pi",e,t),Cm(e)].filter(Boolean).join(`
225
- `),uninstall:()=>pt("pi")}},nc=["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(`
226
- `);function Tm(e){if(Ot({homeDir:e,cwd:process.cwd()}).status!=="configured")return nc;return[nc,"",h.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(`
215
+ ${So}
216
+ `}function Wm(e){return e.split(/(?=^\s*\[)/m).filter((n)=>!/^\s*\[\[hooks]]\s*$/m.test(n)||!n.includes(Gt)).join("").trimEnd()}function Jm(e,t){let n=e.indexOf(Do,t.start);if(n===-1||n>t.end)return e;return Cn(e,{start:n,end:n+Do.length})}function gc(e){let t=fc(e);if(Um(Gm(t),{recursive:!0}),!uc(t))return I(t,`${So}
217
+ `),{path:t,alreadyInstalled:!1};let n=pc(t,"utf-8");if(n.includes(Gt))return{path:t,alreadyInstalled:!0};return I(t,Km(n)),{path:t,alreadyInstalled:!1}}function hc(e){let t=fc(e);if(!uc(t))return{path:t,alreadyInstalled:!1};let n=pc(t,"utf-8");if(!n.includes(Gt))return{path:t,alreadyInstalled:!1};let r=mc(n),o=r?Jm(n,r):`${Wm(n)}
218
+ `;return I(t,o),{path:t,alreadyInstalled:!0}}var Ao="safety-net@cc-marketplace",yc=new Set(["claude-code","codex","copilot-cli","gemini-cli","hermes-agent","openclaw","opencode","pi"]),Lc=new Set(["antigravity-cli","cursor","grok-build","hermes-agent","kimi-code"]);function Po(e){return/^\s*safety-net@cc-marketplace[^a-z0-9-][^\n]*installed,/m.test(e??"")}function xc(e){return/^\s*cc-safety-net[^a-z0-9-][^\n]*installed,/m.test(e??"")}function Xm(e){return/^Marketplace `cc-marketplace`\s*$/m.test(e??"")}var Cc={"claude-code":{installCommands:(e)=>{let t=cn(e,"cc-safety-net@cc-marketplace");return{commands:[...t?[["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"]],...Mr(e).status==="disabled"?[["claude","plugin","enable","cc-safety-net@cc-marketplace"]]:[]],cleanupCommands:cn(e,Ao)?[["claude","plugin","uninstall",Ao]]:[],update:t}},uninstallCommands:[["claude","plugin","uninstall","cc-safety-net@cc-marketplace"],["claude","plugin","marketplace","remove","cc-marketplace"]]},codex:{installCommands:async(e,t)=>{let n=t??await se(["codex","plugin","list"]),r=xc(n);return{commands:[r||Xm(n)?["codex","plugin","marketplace","upgrade","cc-marketplace"]:["codex","plugin","marketplace","add","kenryu42/cc-marketplace"],["codex","plugin","add","cc-safety-net@cc-marketplace"]],cleanupCommands:Po(n)?[["codex","plugin","remove","safety-net@cc-marketplace"]]:[],update:r}},uninstallCommands:[["codex","plugin","remove","cc-safety-net@cc-marketplace"],["codex","plugin","marketplace","remove","cc-marketplace"]],postInstallMessage:"Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it."},"copilot-cli":{installCommands:async()=>{let e=await se(["copilot","plugin","list"]),t=[...aa(e)?[["copilot","plugin","uninstall","copilot-safety-net"]]:[],...la(e)?[["copilot","plugin","uninstall",oa]]:[]];if(ia(e))return{commands:[["copilot","plugin","marketplace","update","cc-marketplace"],["copilot","plugin","update",ie]],cleanupCommands:t,update:!0};return{commands:[sa(await se(["copilot","plugin","marketplace","list"]))?["copilot","plugin","marketplace","update","cc-marketplace"]:["copilot","plugin","marketplace","add","kenryu42/cc-marketplace"],["copilot","plugin","install",ie]],cleanupCommands:t}},uninstallCommands:[["copilot","plugin","uninstall","cc-safety-net@cc-marketplace"],["copilot","plugin","marketplace","remove","cc-marketplace"]]},"gemini-cli":{installCommands:(e)=>{let t=zr(e);if(t.status==="configured")return{commands:[["gemini","extensions","update","gemini-safety-net"]],update:!0};if(t.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:io,installCommands:()=>({commands:Za()}),uninstallCommands:[["openclaw","plugins","uninstall",A,"--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(`
219
+ `)},opencode:{beforeInstall:lo,installCommands:[["opencode","plugin","-g","-f","cc-safety-net@latest"]]},pi:{installCommands:[["pi","install","npm:cc-safety-net"]],uninstallCommands:[["pi","uninstall","npm:cc-safety-net"]]}};function Hn(){return process.env.HOME??Ym()}function Sc(e,t=(n)=>n){try{let n=JSON.parse(t(kc(e,"utf-8")));if(!n||typeof n!=="object"||Array.isArray(n))throw Error(`Settings file ${e} must be a JSON object`);return n}catch(n){if(n instanceof SyntaxError)throw Error(`Failed to parse ${e}: ${n.message}`);throw n}}function Qm(e){let t=Ro(It(e),"settings.json");if(!Eo(t))return;let n=Sc(t,q),r=n.enabledPlugins;if(!r||typeof r!=="object"||Array.isArray(r))return;if(r[ie]!==!1)return;let o=kc(t,"utf-8"),i=o.replace(new RegExp(`("${ie}"\\s*:\\s*)false`),"$1true");return r[ie]=!0,I(t,i!==o?i:`${JSON.stringify(n,null,2)}
220
+ `),`Enabled ${ie} plugin in ${t}`}function eg(e){let t=co(e);if(!Eo(t))return;let n=Sc(t);if(!Array.isArray(n.packages))return;let r=n.packages.find((o)=>!!o&&typeof o==="object"&&!Array.isArray(o)&&uo(o.source)&&("extensions"in o));if(!r)return;return delete r.extensions,I(t,`${JSON.stringify(n,null,2)}
221
+ `),`Enabled npm:cc-safety-net extensions in ${t}`}function vc(e,t){let n=_({label:t,booleans:Object.fromEntries(ae.map((i)=>[i.target,[i.flag]]))},e),r=n.errors[0];if(r)throw Error(r);let o=ae.filter((i)=>n.flags[i.target]).map((i)=>i.target);if(o.length!==1)throw Error(`Choose exactly one ${t} target: ${ae.map((i)=>i.flag).join(", ")}`);return o[0]}async function Dc(e=Hn(),t=ot){let[n,r,o]=await Promise.all([t(["amp","plugins","list"],30000),t(["codex","plugin","list"],30000),t(["copilot","--binary-version"])]);return{codexPluginListOutput:r,hooks:dt(process.cwd(),{homeDir:e,ampPluginListOutput:n,codexPluginListOutput:r,copilotCliVersion:o})}}async function tg(e,t=ot){let n=await Dc(Hn(),t);return n.hooks.filter((r)=>e==="install"?r.configured:r.detected||r.inspectionStatus==="not-inspected").filter((r)=>r.platform!=="codex"||!Po(n.codexPluginListOutput)||xc(n.codexPluginListOutput)).map((r)=>r.platform)}function ng(e,t,n){if(t.length>0)return{finish:async()=>[vc(t,e)]};if(!n.selectTargets&&!Lo(n.input,n.output))return{finish:async()=>[vc(t,e)]};let r=n.detectConfiguredTargets??(()=>tg(e,n.fetchVersion)),o=Promise.all([sc(n.probeTargets),r()]);return{ready:o,finish:async()=>{let[i,s]=await o,a=ac(i,{action:e,configuredTargets:s}),l=n.selectTargets?await n.selectTargets(e,wc(e,a)):await jl(e,wc(e,a),{input:n.input,output:n.output});if(l==="update")return l;if(!l||l.length===0)return null;return xo(l)}}}async function Ge(e,t,n=!1,r){let o=Cc[e];o.beforeInstall?.(t);let i=typeof o.installCommands==="function"?await o.installCommands(t,r):{commands:o.installCommands};return await no(i.commands),await Va(i.cleanupCommands??[]),[`${i.update||n?"Updated":"Installed"} ${R(e)} integration`,o.postInstallMessage].filter(Boolean).join(`
222
+ `)}async function mt(e){let t=Cc[e];if(!t.uninstallCommands)throw Error(`${R(e)} uninstall is not supported`);return await no(t.uninstallCommands),`Uninstalled ${R(e)} integration`}function rg(e){let t=hl(e);return t.alreadyInstalled?`Uninstalled OpenCode plugin from ${t.path}`:`OpenCode plugin not installed in ${t.path}`}var og={"antigravity-cli":{install:nc,uninstall:rc},cursor:{install:La,uninstall:va},"grok-build":{install:Ea,uninstall:Pa},"kimi-code":{install:gc,uninstall:hc}};function xe(e,t,n,r=!1){if(e==="install"&&!r)Nn(n);let o=og[t][e](n),i=R(t),s=e!=="install"?"Uninstalled":r?"Updated":"Installed";return e==="install"&&o.alreadyInstalled?r?`${i} hook up to date in ${o.path}`:`${i} hook already installed in ${o.path}`:e==="uninstall"&&!o.alreadyInstalled?`${i} hook not installed in ${o.path}`:`${s} ${i} hook ${e==="install"?"in":"from"} ${o.path}`}var ig={amp:{install:Yl,uninstall:Zl,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:$a,uninstall:Na,afterInstall:async(e)=>{let t=Qr(e);return await se(["hermes","plugins","enable",K,"--no-allow-tool-override"]),!t},beforeUninstall:async(e)=>{Xr(e);try{await se(["hermes","plugins","disable",K])}catch(t){console.warn(`${t instanceof Error?t.message:String(t)}
223
+ Removing the plugin files anyway; ${K} may still be listed in the Hermes config.`)}},restartNote:"Restart Hermes to apply the change."}};async function Fn(e,t,n,r=!1){let o=ig[t];if(e==="uninstall")await o.beforeUninstall?.(n);let i=e==="install"?await o.install(n):await o.uninstall(n),s=e==="install"&&await o.afterInstall?.(n),a=R(t),l=!s&&(e==="install"&&i.alreadyInstalled||e==="uninstall"&&!i.alreadyInstalled);return[l?e==="install"?`${a} plugin ${r?"up to date":"already installed"} at ${i.path}`:`${a} plugin not installed at ${i.path}`:`${e!=="install"?"Uninstalled":r?"Updated":"Installed"} ${a} plugin ${e==="install"?"at":"from"} ${i.path}`,l?void 0:o.restartNote].filter(Boolean).join(`
224
+ `)}var sg={amp:{install:(e,t)=>Fn("install","amp",e,t),uninstall:(e)=>Fn("uninstall","amp",e)},"antigravity-cli":{install:(e,t)=>xe("install","antigravity-cli",e,t),uninstall:(e)=>xe("uninstall","antigravity-cli",e)},"claude-code":{install:(e,t)=>Ge("claude-code",e,t),uninstall:()=>mt("claude-code")},codex:{install:(e,t,n)=>Ge("codex",e,t,n),uninstall:()=>mt("codex")},"copilot-cli":{install:async(e,t)=>[await Ge("copilot-cli",e,t),Qm(e)].filter(Boolean).join(`
225
+ `),uninstall:()=>mt("copilot-cli")},cursor:{install:(e,t)=>xe("install","cursor",e,t),uninstall:(e)=>xe("uninstall","cursor",e)},"gemini-cli":{install:(e,t)=>Ge("gemini-cli",e,t),uninstall:()=>mt("gemini-cli")},"grok-build":{install:(e,t)=>xe("install","grok-build",e,t),uninstall:(e)=>xe("uninstall","grok-build",e)},"hermes-agent":{install:(e,t)=>{if(!t)Nn(e);return Fn("install","hermes-agent",e,t)},uninstall:(e)=>Fn("uninstall","hermes-agent",e)},"kimi-code":{install:(e,t)=>xe("install","kimi-code",e,t),uninstall:(e)=>xe("uninstall","kimi-code",e)},openclaw:{install:async(e,t)=>{let n=await Ge("openclaw",e,t);return await Xa(),n},uninstall:(e)=>(io(e),mt("openclaw"))},opencode:{install:async(e,t)=>{let n=await Ge("opencode",e,t);return await pl(e),n},uninstall:(e)=>rg(e)},pi:{install:async(e,t)=>[await Ge("pi",e,t),eg(e)].filter(Boolean).join(`
226
+ `),uninstall:()=>mt("pi")}},bc=["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(`
227
+ `);function ag(e){if(Ft({homeDir:e,cwd:process.cwd()}).status!=="configured")return bc;return[bc,"",h.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(`
227
228
  `))].join(`
228
- `)}function rc(e,t){return t.map((n)=>e==="install"&&n.target==="kimi-code"&&n.unavailableReason==="already installed"?{...n,available:!0,unavailableReason:void 0,label:`${n.label} (global hook installed)`}:n)}function Im(e,t){if(e.selectKimiInstallMethod)return e.selectKimiInstallMethod();if(!uo(e.input,e.output))return Promise.resolve("global-hook");return wl({input:e.input,output:e.output,globalHookInstalled:Ot({homeDir:t,cwd:process.cwd()}).status==="configured"})}async function cc(e,t,n,r=!1,o){return Pm[t][e](n,r,o)}function _m(e){let t=T({label:"update"},e).errors[0];if(t)throw Error(t)}async function Om(e,t=nt){let n=await lc(e,t),r=bo(Tt(e),"installed-plugins");return{targets:ho([...n.hooks.filter((i)=>i.platform!=="copilot-cli"&&i.detected).map((i)=>i.platform),...[an,Js,Ws].flatMap((i)=>xo(bo(r,...i))?["copilot-cli"]:[]),...sn(e,wo)?["claude-code"]:[],...ko(n.codexPluginListOutput)?["codex"]:[]]),codexPluginListOutput:n.codexPluginListOutput}}async function $m(e){let t=Tn(),n=e.output??process.stdout,r=(e.scriptPath??process.argv[1]??"").split(/[\\/]/),o=r.find((u)=>/^bunx-\d+-/.test(u)),i=o!==void 0||r.includes("_npx")?null:(e.checkLatestVersion??ve)(),s=async()=>{let u=i&&await i;if(u?.updateAvailable)n.write(`
229
+ `)}function wc(e,t){return t.map((n)=>e==="install"&&n.target==="kimi-code"&&n.unavailableReason==="already installed"?{...n,available:!0,unavailableReason:void 0,label:`${n.label} (global hook installed)`}:n)}function lg(e,t){if(e.selectKimiInstallMethod)return e.selectKimiInstallMethod();if(!Lo(e.input,e.output))return Promise.resolve("global-hook");return Ml({input:e.input,output:e.output,globalHookInstalled:Ft({homeDir:t,cwd:process.cwd()}).status==="configured"})}async function Rc(e,t,n,r=!1,o){return sg[t][e](n,r,o)}function cg(e){let t=_({label:"update"},e).errors[0];if(t)throw Error(t)}async function dg(e,t=ot){let n=await Dc(e,t),r=Ro(It(e),"installed-plugins");return{targets:xo([...n.hooks.filter((i)=>i.platform!=="copilot-cli"&&i.detected).map((i)=>i.platform),...[dn,ra,na].flatMap((i)=>Eo(Ro(r,...i))?["copilot-cli"]:[]),...cn(e,Ao)?["claude-code"]:[],...Po(n.codexPluginListOutput)?["codex"]:[]]),codexPluginListOutput:n.codexPluginListOutput}}async function ug(e){let t=Hn(),n=e.output??process.stdout,r=(e.scriptPath??process.argv[1]??"").split(/[\\/]/),o=r.find((u)=>/^bunx-\d+-/.test(u)),i=o!==void 0||r.includes("_npx")?null:(e.checkLatestVersion??be)(),s=async()=>{let u=i&&await i;if(u?.updateAvailable)n.write(`
229
230
  Update available: cc-safety-net ${u.currentVersion} → ${u.latestVersion}. Update this CLI with your package manager, e.g. \`npm i -g cc-safety-net@latest\` for a global install.
230
- `)},a=Om(t,e.fetchVersion??nt).then(async(u)=>{let m=new Set(u.targets);return{targets:u.targets,codexPluginListOutput:u.codexPluginListOutput,available:new Map(await Promise.all(se.filter((f)=>m.has(f.target)&&Ql.has(f.target)).map(async(f)=>[f.target,await yo(f.probeCommand)])))}}),l=await Pt(e.showBanner??!0,()=>({ready:a,finish:()=>a}),()=>Et({input:e.input??process.stdin,output:n}),{loadingMessage:"Checking installed integrations…",output:n}),c=await Promise.resolve().then(()=>(jl(wm(),process.platform,o),null)).catch((u)=>jt(u));if(l.targets.length===0){if(n.write("No installed integrations found. Run `cc-safety-net install` to set one up.\n"),c!==null)console.error(c);return await s(),c===null?0:1}let d=l.targets.some((u)=>ec.has(u))?await Promise.resolve().then(()=>(En(t),null)).catch((u)=>jt(u)):null,p=await nn(Promise.all(l.targets.map((u)=>{if(Ql.has(u)&&!l.available.get(u))return Promise.resolve({message:`${R(u)} not found; skipped`,failed:!1});if(d!==null&&ec.has(u))return Promise.resolve({message:d,failed:!0});return cc("install",u,t,!0,l.codexPluginListOutput).then((m)=>({message:m,failed:!1}),(m)=>({message:jt(m),failed:!0}))})),{loadingMessage:`Updating ${l.targets.length} integration${l.targets.length===1?"":"s"}…`,output:n}),g=c===null?p:[...p,{message:c,failed:!0}];return g.forEach((u)=>{u.failed?console.error(u.message):n.write(`${u.message}
231
- `)}),await s(),g.some((u)=>u.failed)?1:0}function Co(e,t={}){return Promise.resolve().then(()=>_m(e)).then(()=>$m(t)).catch((n)=>(console.error(jt(n)),1))}async function Ut(e,t,n={}){try{let r=await Pt(!0,()=>Dm(e,t,n),()=>Et({input:n.input??process.stdin,output:n.output??process.stdout}),{loadingMessage:e==="install"?"Checking available integrations…":"Checking installed integrations…",output:n.output??process.stdout});if(!r)return(n.output??process.stdout).write(`Cancelled: nothing was ${e}ed.
232
- `),0;if(r==="update")return(n.runUpdate??(()=>Co([],{fetchVersion:n.fetchVersion,input:n.input,output:n.output,showBanner:!1})))();let o=Tn(),i=n.output??process.stdout;return await Ul(r,async(s)=>{if(s==="kimi-code"&&e==="install"){let l=await Im(n,o);if(l===null){i.write(`Cancelled: Kimi Code integration was not installed.
233
- `);return}if(l==="plugin"){i.write(`${Tm(o)}
234
- `);return}}let a=await nn(cc(e,s,o),{loadingMessage:`${e==="install"?"Installing":"Uninstalling"} ${R(s)} integration…`,output:i});i.write(`${a}
235
- `)}),0}catch(r){return console.error(jt(r)),1}}function jt(e){let t=e instanceof Error?e.message:String(e),n=typeof e==="object"&&e!==null&&"code"in e?e.code:null;if(n==="EACCES"||n==="EPERM")return`${t}
231
+ `)},a=dg(t,e.fetchVersion??ot).then(async(u)=>{let m=new Set(u.targets);return{targets:u.targets,codexPluginListOutput:u.codexPluginListOutput,available:new Map(await Promise.all(ae.filter((f)=>m.has(f.target)&&yc.has(f.target)).map(async(f)=>[f.target,await Co(f.probeCommand)])))}}),l=await Tt(e.showBanner??!0,()=>({ready:a,finish:()=>a}),()=>Pt({input:e.input??process.stdin,output:n}),{loadingMessage:"Checking installed integrations…",output:n}),c=await Promise.resolve().then(()=>(oc(Zm(),process.platform,o),null)).catch((u)=>Bt(u));if(l.targets.length===0){if(n.write("No installed integrations found. Run `cc-safety-net install` to set one up.\n"),c!==null)console.error(c);return await s(),c===null?0:1}let d=l.targets.some((u)=>Lc.has(u))?await Promise.resolve().then(()=>(Nn(t),null)).catch((u)=>Bt(u)):null,p=await sn(Promise.all(l.targets.map((u)=>{if(yc.has(u)&&!l.available.get(u))return Promise.resolve({message:`${R(u)} not found; skipped`,failed:!1});if(d!==null&&Lc.has(u))return Promise.resolve({message:d,failed:!0});return Rc("install",u,t,!0,l.codexPluginListOutput).then((m)=>({message:m,failed:!1}),(m)=>({message:Bt(m),failed:!0}))})),{loadingMessage:`Updating ${l.targets.length} integration${l.targets.length===1?"":"s"}…`,output:n}),g=c===null?p:[...p,{message:c,failed:!0}];return g.forEach((u)=>{u.failed?console.error(u.message):n.write(`${u.message}
232
+ `)}),await s(),g.some((u)=>u.failed)?1:0}function To(e,t={}){return Promise.resolve().then(()=>cg(e)).then(()=>ug(t)).catch((n)=>(console.error(Bt(n)),1))}async function qt(e,t,n={}){try{let r=await Tt(!0,()=>ng(e,t,n),()=>Pt({input:n.input??process.stdin,output:n.output??process.stdout}),{loadingMessage:e==="install"?"Checking available integrations…":"Checking installed integrations…",output:n.output??process.stdout});if(!r)return(n.output??process.stdout).write(`Cancelled: nothing was ${e}ed.
233
+ `),0;if(r==="update")return(n.runUpdate??(()=>To([],{fetchVersion:n.fetchVersion,input:n.input,output:n.output,showBanner:!1})))();let o=Hn(),i=n.output??process.stdout;return await ic(r,async(s)=>{if(s==="kimi-code"&&e==="install"){let l=await lg(n,o);if(l===null){i.write(`Cancelled: Kimi Code integration was not installed.
234
+ `);return}if(l==="plugin"){i.write(`${ag(o)}
235
+ `);return}}let a=await sn(Rc(e,s,o),{loadingMessage:`${e==="install"?"Installing":"Uninstalling"} ${R(s)} integration…`,output:i});i.write(`${a}
236
+ `)}),0}catch(r){return console.error(Bt(r)),1}}function Bt(e){let t=e instanceof Error?e.message:String(e),n=typeof e==="object"&&e!==null&&"code"in e?e.code:null;if(n==="EACCES"||n==="EPERM")return`${t}
236
237
  Check file permissions for the target config file and parent directory.`;if(n==="ENOENT")return`${t}
237
238
  Check that the target config path and parent directory exist.`;if(n==="ENOTDIR")return`${t}
238
- Check that every parent path component is a directory.`;return t}import{join as vg}from"node:path";var dc="# Custom Rules Reference\n\nAgent reference for generating CC Safety Net rulebook configuration.\n\n## Config Locations\n\n| Scope | Config path | Rulebook path | Cache path | Priority |\n|-------|-------------|---------------|------------|----------|\n| User | `~/.cc-safety-net/rules/rule.json` | `~/.cc-safety-net/rules/<rulebook-name>/rulebook.json` | `~/.cc-safety-net/cache/rulebooks/` | First |\n| Project | `.cc-safety-net/rules/rule.json` | `.cc-safety-net/rules/<rulebook-name>/rulebook.json` | `.cc-safety-net/cache/rulebooks/` | Second |\n| GitHub source | Listed in a local `rule.json` | `.cc-safety-net/rules/<rulebook-name>/rulebook.json` in the source repository | Consumer local cache | Source order |\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 sync`/`rule verify` report 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- GitHub sources use `owner/repo#ref/<rulebook-name>`.\n- GitHub refs must be one path segment, such as a tag, SHA, or branch name without `/`.\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` |\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### 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. Fixtures are shape-validated only; CC Safety Net does not execute them.\n\n## Matching Behavior\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; it adds the source and syncs it.\n5. Run `cc-safety-net rule sync` after manual `rule.json` changes or local rulebook edits.\n6. Run `cc-safety-net rule verify` to validate config, lock/cache state, local rulebooks, and shareable GitHub-source rulebook directories in the current repository (it does not fetch remote content).\n7. Run `cc-safety-net rule list` to inspect active rulebooks and transparent wrappers.\n\nAn edited or invalid local rulebook keeps its last synced, digest-verified cached version enforced until `cc-safety-net rule sync` validates the edit. A missing lock entry or cache, a cache digest mismatch, or an invalid cached rulebook makes that source inactive; a missing lockfile or 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. Repair the reported condition, then run `cc-safety-net rule sync`. Run `cc-safety-net status` to see degraded sources.\n";function Gt(e,t){if(!e.ok){Mm(e);return}jm(e),console.log(t),console.log("Rule config synced."),console.log(""),Nm(e.entries)}function Nm(e){if(e.length===0){console.log("Active rulebooks: (none)");return}console.log(`Active rulebooks (${e.length}):`);for(let t of e)console.log(` - ${t.name} ${t.version} (${Fm(t.ruleCount??0)})`),console.log(` Source: ${ir(t)}`)}function Fm(e){return`${e} ${e===1?"rule":"rules"}`}function pc(e,t){Ue("Active sources",e.rulebooks,(n)=>[`[${n.source}] ${n.name} ${n.version}`,` Source: ${t[n.source].get(n.spec)??n.spec}`]),Ue("Active rules",e.rules,(n)=>[`[${Hm(e,n.name)}] ${n.name}`,` Command: ${n.subcommand?`${n.command} ${n.subcommand}`:n.command}`,` Block args: ${n.block_args.join(", ")}`,` Reason: ${n.reason}`]),Ue("Disabled rules",uc(e,"off"),(n)=>[n.key]),Ue("Reason overrides",uc(e,"reason"),(n)=>[n.key,` Reason: ${n.value.reason}`]),Ue("Transparent wrappers",e.transparent_wrappers,(n)=>[n]),Ue("Issues",e.errors,(n)=>[n]),Ue("Warnings",e.warnings,(n)=>[n])}function Ue(e,t,n){if(t.length===0){console.log(`${e}: (none)`);return}console.log(`${e} (${t.length}):`);for(let r of t){let[o,...i]=n(r);console.log(` - ${o}`);for(let s of i)console.log(` ${s}`)}}function Hm(e,t){return e.rulebooks.find((n)=>n.rules.includes(t))?.source??"project"}function uc(e,t){return Object.entries({...e.userConfig?.overrides??{},...e.projectConfig?.overrides??{}}).filter((n)=>{if(t==="off")return n[1]==="off";return!!n[1]&&typeof n[1]==="object"}).map(([n,r])=>({key:n,value:r}))}function Mm(e){for(let t of e.errors)console.error(t)}function jm(e){if(!e.warnings||e.warnings.length===0)return;for(let t of e.warnings)console.warn(t)}import{dirname as fc,join as In}from"node:path";var Um=".safety-net.json",Gm="~/.cc-safety-net/config.json";async function hc(e){return[await mc({legacyPath:gc({cwd:e.cwd}),configPath:X(e.cwd),defaultRulebookName:"project-rules",migratedFrom:Um,cleanup:e.cleanup,syncOptions:{cwd:e.cwd}}),await mc({legacyPath:yt(),configPath:Q(),defaultRulebookName:"user-rules",migratedFrom:Gm,cleanup:e.cleanup,syncOptions:{cwd:e.cwd,global:!0}})].every((n)=>n)?0:1}async function mc(e){let t=J(e.syncOptions),n=x(t.filesystemScope,e.legacyPath),r=w(n);if(r===null)return console.log(`No legacy config found at ${e.legacyPath}`),!0;let o=qm(r);if(!o.ok){for(let g of o.errors)console.error(g);return!1}let i=Y(t.configTarget);if(i.errors.length>0){for(let g of i.errors)console.error(g);return!1}let s=i.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},a=Vm(fc(e.configPath),s.rules,e.defaultRulebookName,e.migratedFrom,t.filesystemScope),l=In(fc(e.configPath),a,"rulebook.json"),c=x(t.filesystemScope,l),d=[So(t.configTarget),So(c),So(t.lockTarget)],p=await Bm(e,t.configTarget,c,a,o.config.rules,s.rules.includes(a)?s.rules:[...s.rules,a],s.overrides??{},s.transparent_wrappers??[]);if(!p.ok){Wm(d);for(let g of p.errors)console.error(g);return!1}if(!e.cleanup)return console.log(`Migrated legacy config at ${e.legacyPath}. Legacy file is no longer used.`),!0;if(!Km(t.configTarget,c,a,e.migratedFrom,o.config.rules))return console.error(`Migration cleanup verification failed for ${e.legacyPath}`),!1;return Ke(n),console.log(`Deleted legacy config at ${e.legacyPath}`),!0}async function Bm(e,t,n,r,o,i,s,a){try{return Z(t,{version:1,rules:i,overrides:s,transparent_wrappers:a}),Z(n,zm(r,e.migratedFrom,o)),await We(e.syncOptions)}catch(l){return{ok:!1,errors:[l instanceof Error?l.message:String(l)]}}}function qm(e){try{let t=JSON.parse(e),n=zn(t);if(n.errors.length>0)return{ok:!1,errors:n.errors};return{ok:!0,config:{version:1,rules:t.rules??[]}}}catch{return{ok:!1,errors:["Invalid JSON"]}}}function Vm(e,t,n,r,o){let i=t.find((s)=>Jm(x(o,In(e,s,"rulebook.json")))===r);if(i)return i;if(w(x(o,In(e,n,"rulebook.json")))===null)return n;for(let s=2;;s++){let a=`${n}-${s}`;if(w(x(o,In(e,a,"rulebook.json")))===null)return a}}function zm(e,t,n){return{rulebook_version:1,name:e,version:"1.0.0",description:"Migrated CC Safety Net rules.",author:"project",migrated_from:t,allowed_commands:[...new Set(n.map((r)=>r.command))],rules:n,tests:n.map((r)=>({command:[r.command,r.subcommand,r.block_args[0]].filter(Boolean).join(" "),expect:"blocked",rule:r.name}))}}function Km(e,t,n,r,o){if(!Y(e).config?.rules.includes(n))return!1;try{let s=w(t);if(s===null)return!1;let a=JSON.parse(s);return a.migrated_from===r&&JSON.stringify(a.rules)===JSON.stringify(o)}catch{return!1}}function So(e){return{target:e,content:w(e)}}function Wm(e){for(let t of e){if(t.content===null){Ke(t.target);continue}ke(t.target,t.content)}}function Jm(e){let t=w(e);if(t===null)return null;try{let n=JSON.parse(t);return typeof n.migrated_from==="string"?n.migrated_from:null}catch{return null}}import{mkdir as Ym,readFile as Zm,writeFile as Xm}from"node:fs/promises";import{dirname as Qm,join as eg}from"node:path";var tg=86400000,ng=604800000;async function Lc(e=Date.now()){if(process.env.CC_SAFETY_NET_NO_UPDATE_CHECK)return null;let t=lr();if(!t)return null;let n=eg(t,".cc-safety-net","update-check.json"),r=await rg(n,e);if(!r.lastCheck||e-r.lastCheck>tg){let s=await ve();if(r.lastCheck=e,s.latestVersion)r.latestVersion=s.latestVersion;if(!await yc(n,r))return null;if(s.error)return null}let o=r.latestVersion,i=P();if(!o||!Rr(o,i))return null;if(r.notifiedVersion===o&&r.notifiedAt!==void 0&&e-r.notifiedAt<ng)return null;if(r.notifiedVersion=o,r.notifiedAt=e,!await yc(n,r))return null;return`UPDATE_AVAILABLE: cc-safety-net v${o} is available (running v${i}). 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 rg(e,t){let n=await Zm(e,"utf8").then((i)=>JSON.parse(i)).catch(()=>{return});if(!n||typeof n!=="object"||Array.isArray(n))return{};let r=n,o=(i)=>typeof i==="number"&&Number.isFinite(i)&&i<=t?i:void 0;return{lastCheck:o(r.lastCheck),latestVersion:typeof r.latestVersion==="string"?r.latestVersion:void 0,notifiedVersion:typeof r.notifiedVersion==="string"?r.notifiedVersion:void 0,notifiedAt:o(r.notifiedAt)}}async function yc(e,t){return Ym(Qm(e),{recursive:!0,mode:448}).then(()=>Xm(e,JSON.stringify(t),{mode:384})).then(()=>!0).catch(()=>!1)}import{dirname as og,join as ig,resolve as Do}from"node:path";var bc="CC Safety Net Config",sg="═".repeat(bc.length),ag="https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json",lg=new Set(["rule.json","rule.lock","cache"]);function wc(e={}){try{return cg(e)}catch(t){if(t instanceof N)return console.error(t.message),1;throw t}}function cg(e){let t=e.cwd??process.cwd(),n=e.userConfigPath??Q(),r=e.projectConfigPath??X(t),o=e.legacyUserConfigPath??yt(),i=e.legacyProjectConfigPath??Jo(t),s=Do(t,or),a=og(n),l=ee({cwd:t,userConfigPath:n,projectConfigPath:r}),c=ee({cwd:t}),d=x(l.userScope,n),p=x(l.projectScope,r),g=e.legacyUserConfigPath?mt(e.legacyUserConfigPath,"user policy"):x(c.userScope,o),u=e.legacyProjectConfigPath?mt(e.legacyProjectConfigPath,"project policy"):x(c.projectScope,i),m=!1,f=!1,L=[],v=[],k=dg(x(c.projectScope,s));if(pg(),w(d)!==null){let y=le(d);if(y.errors.push(...ce(n,Je({userConfigDir:a}),{userConfigDir:a},l.userScope)),L.push({scope:"User",path:n,result:y,schema:"rules",sourceDisplayMap:Se(n,l.userScope),target:d}),y.errors.length>0)m=!0}if(w(g)!==null)if(f=!0,w(d)!==null)v.push(_n("user","cleanup"));else{let y=Kn(g);if(L.push({scope:"User",path:o,result:y,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:g}),v.push(_n("user",y.errors.length>0?"fix-or-delete":"migrate")),y.errors.length>0)m=!0}if(w(p)!==null){let y=le(p);if(y.errors.push(...ce(r,Ye(r),{userConfigDir:a},l.projectScope)),L.push({scope:"Project",path:Do(r),result:y,schema:"rules",sourceDisplayMap:Se(r,l.projectScope),target:p}),y.errors.length>0)m=!0;if(w(u)!==null)f=!0,v.push(_n("project","cleanup"))}else if(w(u)!==null){f=!0,m=!0;let y=Kn(u);L.push({scope:"Project",path:Do(i),result:y,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:u}),v.push(_n("project",y.errors.length>0?"fix-or-delete":"migrate"))}if(k?.result.errors.length)m=!0;if(L.length===0&&!k)return console.log(`
239
- No config files found. Using built-in rules only.`),0;for(let y of L)if(y.inactive)mg(y.scope,y.path,y.result,y.sourceDisplayMap);else if(y.result.errors.length>0)gg(y.scope,y.path,y.result.errors);else{if(y.schema==="rules"&&Lg(y.target))console.log(`
240
- Added $schema to ${y.scope.toLowerCase()} config.`);fg(y.scope,y.path,y.result,y.schema,y.sourceDisplayMap)}for(let y of v)console.error(`
241
- ${h.red(y)}`);if(k)if(k.result.errors.length>0)yg(k.path,k.result.errors);else hg(k.path,k.result);if(m)return console.error(`
239
+ Check that every parent path component is a directory.`;return t}import{join as Jg}from"node:path";var Ac="# Custom Rules Reference\n\nAgent reference for generating CC Safety Net rulebook configuration.\n\n## Config Locations\n\n| Scope | Config path | Rulebook path | Cache path | Priority |\n|-------|-------------|---------------|------------|----------|\n| User | `~/.cc-safety-net/rules/rule.json` | `~/.cc-safety-net/rules/<rulebook-name>/rulebook.json` | `~/.cc-safety-net/cache/rulebooks/` | First |\n| Project | `.cc-safety-net/rules/rule.json` | `.cc-safety-net/rules/<rulebook-name>/rulebook.json` | `.cc-safety-net/cache/rulebooks/` | Second |\n| GitHub source | Listed in a local `rule.json` | `.cc-safety-net/rules/<rulebook-name>/rulebook.json` in the source repository | Consumer local cache | Source order |\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 sync`/`rule verify` report 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- GitHub sources use `owner/repo#ref/<rulebook-name>`.\n- GitHub refs must be one path segment, such as a tag, SHA, or branch name without `/`.\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` |\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### 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. Fixtures are shape-validated only; CC Safety Net does not execute them.\n\n## Matching Behavior\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; it adds the source and syncs it.\n5. Run `cc-safety-net rule sync` after manual `rule.json` changes or local rulebook edits.\n6. Run `cc-safety-net rule verify` to validate config, lock/cache state, local rulebooks, and shareable GitHub-source rulebook directories in the current repository (it does not fetch remote content).\n7. Run `cc-safety-net rule list` to inspect active rulebooks and transparent wrappers.\n\nAn edited or invalid local rulebook keeps its last synced, digest-verified cached version enforced until `cc-safety-net rule sync` validates the edit. A missing lock entry or cache, a cache digest mismatch, or an invalid cached rulebook makes that source inactive; a missing lockfile or 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. Repair the reported condition, then run `cc-safety-net rule sync`. Run `cc-safety-net status` to see degraded sources.\n";function Vt(e,t){if(!e.ok){gg(e);return}hg(e),console.log(t),console.log("Rule config synced."),console.log(""),pg(e.entries)}function pg(e){if(e.length===0){console.log("Active rulebooks: (none)");return}console.log(`Active rulebooks (${e.length}):`);for(let t of e)console.log(` - ${t.name} ${t.version} (${fg(t.ruleCount??0)})`),console.log(` Source: ${pr(t)}`)}function fg(e){return`${e} ${e===1?"rule":"rules"}`}function Pc(e,t){Be("Active sources",e.rulebooks,(n)=>[`[${n.source}] ${n.name} ${n.version}`,` Source: ${t[n.source].get(n.spec)??n.spec}`]),Be("Active rules",e.rules,(n)=>[`[${mg(e,n.name)}] ${n.name}`,` Command: ${n.subcommand?`${n.command} ${n.subcommand}`:n.command}`,` Block args: ${n.block_args.join(", ")}`,` Reason: ${n.reason}`]),Be("Disabled rules",Ec(e,"off"),(n)=>[n.key]),Be("Reason overrides",Ec(e,"reason"),(n)=>[n.key,` Reason: ${n.value.reason}`]),Be("Transparent wrappers",e.transparent_wrappers,(n)=>[n]),Be("Issues",e.errors,(n)=>[n]),Be("Warnings",e.warnings,(n)=>[n])}function Be(e,t,n){if(t.length===0){console.log(`${e}: (none)`);return}console.log(`${e} (${t.length}):`);for(let r of t){let[o,...i]=n(r);console.log(` - ${o}`);for(let s of i)console.log(` ${s}`)}}function mg(e,t){return e.rulebooks.find((n)=>n.rules.includes(t))?.source??"project"}function Ec(e,t){return Object.entries({...e.userConfig?.overrides??{},...e.projectConfig?.overrides??{}}).filter((n)=>{if(t==="off")return n[1]==="off";return!!n[1]&&typeof n[1]==="object"}).map(([n,r])=>({key:n,value:r}))}function gg(e){for(let t of e.errors)console.error(t)}function hg(e){if(!e.warnings||e.warnings.length===0)return;for(let t of e.warnings)console.warn(t)}import{dirname as Tc,join as Mn}from"node:path";var yg=".safety-net.json",Lg="~/.cc-safety-net/config.json";async function Oc(e){return[await Ic({legacyPath:_c({cwd:e.cwd}),configPath:Q(e.cwd),defaultRulebookName:"project-rules",migratedFrom:yg,cleanup:e.cleanup,syncOptions:{cwd:e.cwd}}),await Ic({legacyPath:Lt(),configPath:ee(),defaultRulebookName:"user-rules",migratedFrom:Lg,cleanup:e.cleanup,syncOptions:{cwd:e.cwd,global:!0}})].every((n)=>n)?0:1}async function Ic(e){let t=Y(e.syncOptions),n=k(t.filesystemScope,e.legacyPath),r=w(n);if(r===null)return console.log(`No legacy config found at ${e.legacyPath}`),!0;let o=bg(r);if(!o.ok){for(let g of o.errors)console.error(g);return!1}let i=Z(t.configTarget);if(i.errors.length>0){for(let g of i.errors)console.error(g);return!1}let s=i.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},a=wg(Tc(e.configPath),s.rules,e.defaultRulebookName,e.migratedFrom,t.filesystemScope),l=Mn(Tc(e.configPath),a,"rulebook.json"),c=k(t.filesystemScope,l),d=[Io(t.configTarget),Io(c),Io(t.lockTarget)],p=await vg(e,t.configTarget,c,a,o.config.rules,s.rules.includes(a)?s.rules:[...s.rules,a],s.overrides??{},s.transparent_wrappers??[]);if(!p.ok){Cg(d);for(let g of p.errors)console.error(g);return!1}if(!e.cleanup)return console.log(`Migrated legacy config at ${e.legacyPath}. Legacy file is no longer used.`),!0;if(!xg(t.configTarget,c,a,e.migratedFrom,o.config.rules))return console.error(`Migration cleanup verification failed for ${e.legacyPath}`),!1;return Je(n),console.log(`Deleted legacy config at ${e.legacyPath}`),!0}async function vg(e,t,n,r,o,i,s,a){try{return X(t,{version:1,rules:i,overrides:s,transparent_wrappers:a}),X(n,kg(r,e.migratedFrom,o)),await Ye(e.syncOptions)}catch(l){return{ok:!1,errors:[l instanceof Error?l.message:String(l)]}}}function bg(e){try{let t=JSON.parse(e),n=Qn(t);if(n.errors.length>0)return{ok:!1,errors:n.errors};return{ok:!0,config:{version:1,rules:t.rules??[]}}}catch{return{ok:!1,errors:["Invalid JSON"]}}}function wg(e,t,n,r,o){let i=t.find((s)=>Sg(k(o,Mn(e,s,"rulebook.json")))===r);if(i)return i;if(w(k(o,Mn(e,n,"rulebook.json")))===null)return n;for(let s=2;;s++){let a=`${n}-${s}`;if(w(k(o,Mn(e,a,"rulebook.json")))===null)return a}}function kg(e,t,n){return{rulebook_version:1,name:e,version:"1.0.0",description:"Migrated CC Safety Net rules.",author:"project",migrated_from:t,allowed_commands:[...new Set(n.map((r)=>r.command))],rules:n,tests:n.map((r)=>({command:[r.command,r.subcommand,r.block_args[0]].filter(Boolean).join(" "),expect:"blocked",rule:r.name}))}}function xg(e,t,n,r,o){if(!Z(e).config?.rules.includes(n))return!1;try{let s=w(t);if(s===null)return!1;let a=JSON.parse(s);return a.migrated_from===r&&JSON.stringify(a.rules)===JSON.stringify(o)}catch{return!1}}function Io(e){return{target:e,content:w(e)}}function Cg(e){for(let t of e){if(t.content===null){Je(t.target);continue}Se(t.target,t.content)}}function Sg(e){let t=w(e);if(t===null)return null;try{let n=JSON.parse(t);return typeof n.migrated_from==="string"?n.migrated_from:null}catch{return null}}import{mkdir as Dg,readFile as Rg,writeFile as Ag}from"node:fs/promises";import{dirname as Eg,join as Pg}from"node:path";var Tg=86400000,Ig=604800000;async function Nc(e=Date.now()){if(process.env.CC_SAFETY_NET_NO_UPDATE_CHECK)return null;let t=gr();if(!t)return null;let n=Pg(t,".cc-safety-net","update-check.json"),r=await _g(n,e);if(!r.lastCheck||e-r.lastCheck>Tg){let s=await be();if(r.lastCheck=e,s.latestVersion)r.latestVersion=s.latestVersion;if(!await $c(n,r))return null;if(s.error)return null}let o=r.latestVersion,i=T();if(!o||!Or(o,i))return null;if(r.notifiedVersion===o&&r.notifiedAt!==void 0&&e-r.notifiedAt<Ig)return null;if(r.notifiedVersion=o,r.notifiedAt=e,!await $c(n,r))return null;return`UPDATE_AVAILABLE: cc-safety-net v${o} is available (running v${i}). 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 _g(e,t){let n=await Rg(e,"utf8").then((i)=>JSON.parse(i)).catch(()=>{return});if(!n||typeof n!=="object"||Array.isArray(n))return{};let r=n,o=(i)=>typeof i==="number"&&Number.isFinite(i)&&i<=t?i:void 0;return{lastCheck:o(r.lastCheck),latestVersion:typeof r.latestVersion==="string"?r.latestVersion:void 0,notifiedVersion:typeof r.notifiedVersion==="string"?r.notifiedVersion:void 0,notifiedAt:o(r.notifiedAt)}}async function $c(e,t){return Dg(Eg(e),{recursive:!0,mode:448}).then(()=>Ag(e,JSON.stringify(t),{mode:384})).then(()=>!0).catch(()=>!1)}import{dirname as Og,join as $g,resolve as _o}from"node:path";var Hc="CC Safety Net Config",Ng="═".repeat(Hc.length),Fg="https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json",Hg=new Set(["rule.json","rule.lock","cache"]);function Mc(e={}){try{return Mg(e)}catch(t){if(t instanceof H)return console.error(t.message),1;throw t}}function Mg(e){let t=e.cwd??process.cwd(),n=e.userConfigPath??ee(),r=e.projectConfigPath??Q(t),o=e.legacyUserConfigPath??Lt(),i=e.legacyProjectConfigPath??ni(t),s=_o(t,ur),a=Og(n),l=te({cwd:t,userConfigPath:n,projectConfigPath:r}),c=te({cwd:t}),d=k(l.userScope,n),p=k(l.projectScope,r),g=e.legacyUserConfigPath?gt(e.legacyUserConfigPath,"user policy"):k(c.userScope,o),u=e.legacyProjectConfigPath?gt(e.legacyProjectConfigPath,"project policy"):k(c.projectScope,i),m=!1,f=!1,L=[],v=[],x=jg(k(c.projectScope,s));if(Gg(),w(d)!==null){let y=ce(d);if(y.errors.push(...de(n,Ze({userConfigDir:a}),{userConfigDir:a},l.userScope)),L.push({scope:"User",path:n,result:y,schema:"rules",sourceDisplayMap:Re(n,l.userScope),target:d}),y.errors.length>0)m=!0}if(w(g)!==null)if(f=!0,w(d)!==null)v.push(jn("user","cleanup"));else{let y=er(g);if(L.push({scope:"User",path:o,result:y,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:g}),v.push(jn("user",y.errors.length>0?"fix-or-delete":"migrate")),y.errors.length>0)m=!0}if(w(p)!==null){let y=ce(p);if(y.errors.push(...de(r,Xe(r),{userConfigDir:a},l.projectScope)),L.push({scope:"Project",path:_o(r),result:y,schema:"rules",sourceDisplayMap:Re(r,l.projectScope),target:p}),y.errors.length>0)m=!0;if(w(u)!==null)f=!0,v.push(jn("project","cleanup"))}else if(w(u)!==null){f=!0,m=!0;let y=er(u);L.push({scope:"Project",path:_o(i),result:y,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:u}),v.push(jn("project",y.errors.length>0?"fix-or-delete":"migrate"))}if(x?.result.errors.length)m=!0;if(L.length===0&&!x)return console.log(`
240
+ No config files found. Using built-in rules only.`),0;for(let y of L)if(y.inactive)qg(y.scope,y.path,y.result,y.sourceDisplayMap);else if(y.result.errors.length>0)Vg(y.scope,y.path,y.result.errors);else{if(y.schema==="rules"&&Wg(y.target))console.log(`
241
+ Added $schema to ${y.scope.toLowerCase()} config.`);Bg(y.scope,y.path,y.result,y.schema,y.sourceDisplayMap)}for(let y of v)console.error(`
242
+ ${h.red(y)}`);if(x)if(x.result.errors.length>0)Kg(x.path,x.result.errors);else zg(x.path,x.result);if(m)return console.error(`
242
243
  Config validation failed.`),1;return console.log(f?`
243
244
  Configs valid with warnings.`:`
244
- All configs valid.`),0}function _n(e,t){let n=`legacy ${e} config`;if(t==="cleanup")return`Warning: Legacy ${e} config is no longer needed. Run \`npx -y cc-safety-net rule migrate --cleanup\` to clean it up safely.`;if(t==="migrate")return`Warning: Legacy ${e} config is ignored by CC Safety Net. Run \`npx -y cc-safety-net rule migrate\`.`;return`Warning: Legacy ${e} config is no longer supported. Fix or delete the ${n}, then run \`npx -y cc-safety-net rule migrate\`.`}function dg(e){if(Ce(e)===null)return null;let t=ug(e);if(t.ruleNames.size===0&&t.errors.length===0)return null;return{path:e.path,result:t}}function ug(e){let t=[],n=new Set,r=(Ce(e)??[]).filter((o)=>!lg.has(o.name)).sort((o,i)=>o.name.localeCompare(i.name));if(r.length===0)return{errors:t,ruleNames:n};for(let o of r){if(!ht.test(o.name)){t.push(`rulebook directory names must match ${ht}: ${o.name}`);continue}if(o.kind!=="directory"){t.push(`${o.name} must be a rulebook directory`);continue}let i=x(e.scope,ig(e.path,o.name,"rulebook.json")),s=w(i);if(s===null){t.push(`${o.name}/rulebook.json is required`);continue}try{let a;try{a=JSON.parse(s)}catch{t.push(`${o.name}/rulebook.json: invalid JSON`);continue}let l=vc(a);if(l.name!==o.name){t.push(`rulebook name "${l.name}" must match folder "${o.name}"`);continue}n.add(o.name)}catch(a){t.push(a instanceof Error?`${o.name}/rulebook.json: ${a.message}`:`${o.name}/rulebook.json: ${String(a)}`)}}return{errors:t,ruleNames:n}}function pg(){console.log(bc),console.log(sg)}function fg(e,t,n,r,o){if(console.log(`
245
- ✓ ${e} config: ${t}`),console.log(` Schema: ${r==="rules"?"rulebook sources":"legacy inline rules"}`),n.ruleNames.size>0){console.log(` ${r==="rules"?"Sources":"Rules"}:`);let i=1;for(let s of n.ruleNames)console.log(` ${i}. ${o.get(s)??s}`),i++}else console.log(` ${r==="rules"?"Sources":"Rules"}: (none)`)}function mg(e,t,n,r){if(console.error(`
246
- ✗ Legacy ${e.toLowerCase()} config: ${t}`),console.error(" Schema: legacy inline rules"),console.error(" Status: ignored by CC Safety Net"),n.errors.length>0){console.error(" Errors:");let o=1;for(let i of n.errors)for(let s of i.split("; "))console.error(` ${o}. ${s}`),o++;return}if(n.ruleNames.size>0){console.error(" Rules:");let o=1;for(let i of n.ruleNames)console.error(` ${o}. ${r.get(i)??i}`),o++;return}console.error(" Rules: (none)")}function gg(e,t,n){xc(`${e} config`,t,n)}function hg(e,t){console.log(`
247
- ✓ GitHub source rules: ${e}`),console.log(" Rulebooks:");let n=1;for(let r of t.ruleNames)console.log(` ${n}. ${r}`),n++}function yg(e,t){xc("GitHub source rules",e,t)}function xc(e,t,n){console.error(`
248
- ✗ ${e}: ${t}`),console.error(" Errors:");let r=1;for(let o of n)for(let i of o.split("; "))console.error(` ${r}. ${i}`),r++}function Lg(e){try{let t=w(e);if(t===null)return!1;let n=JSON.parse(t);if(n.$schema)return!1;return ke(e,JSON.stringify({$schema:ag,...n},null,2)),!0}catch(t){if(t instanceof N)throw t;return!1}}var kc=new Set(["init","add","remove","update","sync","list","wrapper","migrate","doc","verify"]),bg=new Set(["add","remove","list"]);async function Sc(e){try{return await wg(e)}catch(t){if(t instanceof N)return console.error(t.message),1;throw t}}async function wg(e){let t=kg(e),n=t.help?xg(t.positionals):null;if(n)return xn(n),0;if(t.errors.length>0){for(let s of t.errors)console.error(s);return 1}let r=t.positionals[0];if(!r)return xn(tt,console.error),1;let o=t.positionals[1],i={global:t.global,check:t.check};if(r==="init"){let s=J(i),a=s.configDir;Dg(s.configTarget),Cc(x(s.filesystemScope,Vt({...i,cacheConfigDir:a})));let l=vg(a,"example-rules","rulebook.json"),c=x(s.filesystemScope,l);if(t.example&&w(c)===null)ar(c,"example-rules");let d=await We(i);return Gt(d,"Rule config initialized."),d.ok?0:1}if(r==="add"){if(!o)return console.error("rule add requires a source"),1;let s=await tr(o,i);return Gt(s,`Added rulebook source: ${o}`),s.ok?0:1}if(r==="remove"){if(!o)return console.error("rule remove requires a source"),1;let s=await rr(o,{...i,deleteSource:t.deleteSource});return Gt(s,`Removed rulebook source: ${o}`),s.ok?0:1}if(r==="update"||r==="sync"){let s=await We({...i,only:r==="update"?o:void 0});return Gt(s,t.check?"Rule config checked.":"Rule config synced."),s.ok?0:1}if(r==="list"){let s=Le(),a=ee({});return pc(s,{user:Se(s.userConfigPath,a.userScope),project:Se(s.projectConfigPath,a.projectScope)}),s.errors.length>0?1:0}if(r==="wrapper")return Rg(t);if(r==="migrate")return hc({cleanup:t.cleanup,cwd:process.cwd()});if(r==="doc"){console.log(dc);let s=await Lc();if(s)console.error(s);return 0}if(r==="verify")return wc();return 1}function xg(e){if(e.length===0)return tt;let t=tt.subcommands.filter((r)=>r.usage.split(" ")[0]===e[0]);if(t.length===0)return null;if(e.length===1&&t.length>1)return{name:`rule ${e[0]}`,description:`Subcommands of rule ${e[0]}`,usage:`rule ${e[0]} <subcommand>`,subcommands:t,options:[]};let n=e.length===1?t[0]:t.find((r)=>r.usage.split(" ")[1]===e[1]);if(!n)return null;return{name:`rule ${e[0]}`,description:n.description,usage:`rule ${n.usage}`,options:[]}}function kg(e){let t=T({label:"rule",booleans:{global:["-g","--global"],check:["--check"],cleanup:["--cleanup"],deleteSource:["--delete-source"],example:["--example"]},positionals:"list"},e),n={...t.flags,help:t.help,positionals:t.positionals,errors:t.errors};return Cg(n),n}function Cg(e){let[t]=e.positionals;if(t&&!kc.has(t))e.errors.push(`Unknown rule subcommand: ${t}`);if(e.deleteSource&&t!=="remove")if(t&&kc.has(t))e.errors.push(`Unknown option for rule ${t}: --delete-source`);else e.errors.push("--delete-source is only valid with 'rule remove'");if(e.cleanup&&t!=="migrate")e.errors.push(On(t,"--cleanup"));if(e.example&&t!=="init")e.errors.push(On(t,"--example"));if(t==="migrate"){if(e.global)e.errors.push(On(t,"--global"));if(e.check)e.errors.push(On(t,"--check"));if(e.positionals.length>1)e.errors.push(`Unexpected rule migrate argument: ${e.positionals[1]}`)}else if(t==="wrapper")Sg(e);else if(e.positionals.length>2)e.errors.push(`Unexpected rule argument: ${e.positionals[2]}`);if(t==="list"&&e.global)e.errors.push("Unknown option for rule list: --global")}function On(e,t){return e?`Unknown option for rule ${e}: ${t}`:`Unknown option for rule: ${t}`}function Sg(e){let t=e.positionals[1],n=e.positionals[2];if(!t){e.errors.push("rule wrapper requires add, remove, or list");return}if(!bg.has(t)){e.errors.push(`Unknown rule wrapper action: ${t}`);return}if(t==="list"){if(n)e.errors.push(`Unexpected rule wrapper argument: ${n}`);return}if(!n){e.errors.push(`rule wrapper ${t} requires a command`);return}if(e.positionals.length>3)e.errors.push(`Unexpected rule wrapper argument: ${e.positionals[3]}`)}function Dg(e){if(w(e)===null){sr(e);return}let t=Y(e);if(!t.config)return;Z(e,{version:1,rules:t.config.rules,overrides:t.config.overrides??{},transparent_wrappers:t.config.transparent_wrappers??[]})}async function Rg(e){let t=e.positionals[1],n=e.positionals[2],r=J({global:e.global}).configTarget;if(t==="list"){let a=Y(r);if(a.errors.length>0){for(let l of a.errors)console.error(l);return 1}return Ag(a.config?.transparent_wrappers??[]),0}if(!n||!cr.test(n))return console.error("transparent wrapper must match command pattern"),1;if(ur(n))return console.error(`reserved command "${n}" cannot be a wrapper`),1;let o=Y(r);if(o.errors.length>0){for(let a of o.errors)console.error(a);return 1}let i=o.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},s=t==="add"?[...new Set([...i.transparent_wrappers??[],n])]:(i.transparent_wrappers??[]).filter((a)=>a!==n);return Z(r,{version:1,rules:i.rules,overrides:i.overrides??{},transparent_wrappers:s}),console.log(t==="add"?`Added transparent wrapper: ${n}`:`Removed transparent wrapper: ${n}`),0}function Ag(e){if(e.length===0){console.log("Transparent wrappers: (none)");return}console.log(`Transparent wrappers (${e.length}):`);for(let t of e)console.log(` - ${t}`)}import{homedir as Dc}from"node:os";import{existsSync as Eg,readFileSync as Pg}from"node:fs";import{homedir as Tg}from"node:os";import{join as Ig}from"node:path";async function _g(e){if(e.isTTY)return null;return(await Lr(e).catch(()=>null))?.trim()||null}function Og(){if(process.env.CLAUDE_SETTINGS_PATH)return process.env.CLAUDE_SETTINGS_PATH;return Ig(Tg(),".claude","settings.json")}function Ro(){let e=Og();if(!Eg(e))return!1;try{let t=Pg(e,"utf-8"),n=JSON.parse(t);if(!n.enabledPlugins)return!1;let r="cc-safety-net@cc-marketplace";if(!(r in n.enabledPlugins))return!1;return n.enabledPlugins[r]===!0}catch(t){if(bt(S.debug))console.error(`CC Safety Net debug: failed to read Claude settings: ${e}: ${t instanceof Error?t.message:String(t)}`);return!1}}async function Ao(e=process.stdin){let t=Ro(),n;if(!t)n="\uD83D\uDEE1️ CC Safety Net ❌";else{let o=B({cwd:process.cwd()}),i=o.policy,s=de(i),a=Object.values(Ae(i,s.capabilities)).some((c)=>c.changesInherited);n=`\uD83D\uDEE1️ CC Safety Net ${{standard:"✅",strict:"\uD83D\uDD12",paranoid:"\uD83D\uDC41️",custom:"\uD83D\uDD27"}[a?"custom":s.effectiveLevel]}${s.worktreeMode?"\uD83C\uDF33":""}${o.state==="degraded"?"⚠️":""}`}let r=await _g(e);if(r&&!r.startsWith("{"))console.log(`${r} | ${n}`);else console.log(n)}function Rc(){let e=B({cwd:process.cwd()}),t=e.policy,n=de(t),r=!!process.env.NO_COLOR||!process.stdout.isTTY,o=Math.min(process.stdout.columns||80,100),i=r?"ok":"✔",s=r?"OFF":"✘",a=(u,m)=>{let f=` ${u.padEnd(13)}${m}`;return(f.length>o?`${f.slice(0,o-1)}…`:f).replaceAll(s,h.red(s))},l=Object.values(Ae(t,n.capabilities)).some((u)=>u.changesInherited),c=wt(),d={ready:h.green,degraded:h.yellow}[e.state],p=[...Ro()?[]:["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."],...e.diagnostics],g=r?"-":"·";console.log([`${r?"":"\uD83D\uDEE1️ "}CC Safety Net — ${d(e.state)}`,"",a("Protection",`destructive ${t.destructiveCommandProtectionEnabled?i:s} secrets ${t.secretProtection.enabled?i:s}`),a("Level",l?`${n.effectiveLevel} (customised)`:n.effectiveLevel),a("Rules",t.rules.length===0?"none active":`${t.rules.length} active`),a("Policy",c.startsWith(Dc())?`~${c.slice(Dc().length)}`:c),...n.worktreeMode?[a("Worktree","relaxations active")]:[],"",...p.length===0?[" Everything configured is active."]:[" Not active",...p.flatMap((u)=>wn(u," ",o-6).map((m,f)=>f===0?` ${g} ${m}`:m)),""," Full report: cc-safety-net doctor"]].join(`
249
- `))}import{spawn as zc}from"node:child_process";import{randomBytes as Vg}from"node:crypto";import{createServer as zg}from"node:http";import{Writable as Kg}from"node:stream";import{homedir as $g}from"node:os";var $n=500;function Ng(e){let t=e.filter((o)=>o.decision!=="allow"),n=e.filter((o)=>o.decision==="allow"),r=Math.min(t.length,Math.max($n-n.length,Math.ceil($n/2)));return[...t.slice(0,r),...n.slice(0,$n-r)]}function Ac(e,t=ue()){if(t)De(t);let n=(f)=>new Date(f.getFullYear(),f.getMonth(),f.getDate()).getTime(),r=n(new Date),o=new Date(r);o.setDate(o.getDate()-(e-1));let i=o.getTime(),s=[],a={count:0};for(let f of t?ye(t,a):[])for(let L of xe(f,a)){if(!L||typeof L.ts!=="string"||typeof L.command!=="string")continue;let v=new Date(L.ts).getTime();if(!Number.isFinite(v))continue;if(v>=i)s.push(L)}s.sort((f,L)=>new Date(L.ts).getTime()-new Date(f.ts).getTime());let l=Array.from({length:e},()=>0),c=Array.from({length:e},()=>0),d={},p={},g={},u=0,m=0;for(let f of s){let L=f.agent||"unknown";d[L]=(d[L]??0)+1;let v=Math.round((r-n(new Date(f.ts)))/86400000),k=e-1-v,y=v>=0&&v<e;if(y)c[k]=(c[k]??0)+1;if(f.decision!=="allow"){if(u++,f.ruleId)p[f.ruleId]=(p[f.ruleId]??0)+1;let C=Ge(f.segment||f.command);if(C)g[C]=(g[C]??0)+1;if(f.failureStage)m++;if(y)l[k]=(l[k]??0)+1}}return{days:e,logsDir:t,homeDir:$g(),totalInWindow:s.length,truncated:s.length>$n,unreadable:a.count,counts:{blocked:u,allowed:s.length-u,agents:d,blockedByDay:l,analyzedByDay:c,rules:p,commands:g,errors:m},entries:Ng(s).sort((f,L)=>new Date(L.ts).getTime()-new Date(f.ts).getTime())}}import{spawn as Fg}from"node:child_process";import{existsSync as Hg,statSync as Ec}from"node:fs";import{delimiter as Mg,join as jg}from"node:path";var Ug=120000,Nn="Choose the project folder",Gg=`try
250
- return POSIX path of (choose folder with prompt "${Nn}")
245
+ All configs valid.`),0}function jn(e,t){let n=`legacy ${e} config`;if(t==="cleanup")return`Warning: Legacy ${e} config is no longer needed. Run \`npx -y cc-safety-net rule migrate --cleanup\` to clean it up safely.`;if(t==="migrate")return`Warning: Legacy ${e} config is ignored by CC Safety Net. Run \`npx -y cc-safety-net rule migrate\`.`;return`Warning: Legacy ${e} config is no longer supported. Fix or delete the ${n}, then run \`npx -y cc-safety-net rule migrate\`.`}function jg(e){if(De(e)===null)return null;let t=Ug(e);if(t.ruleNames.size===0&&t.errors.length===0)return null;return{path:e.path,result:t}}function Ug(e){let t=[],n=new Set,r=(De(e)??[]).filter((o)=>!Hg.has(o.name)).sort((o,i)=>o.name.localeCompare(i.name));if(r.length===0)return{errors:t,ruleNames:n};for(let o of r){if(!yt.test(o.name)){t.push(`rulebook directory names must match ${yt}: ${o.name}`);continue}if(o.kind!=="directory"){t.push(`${o.name} must be a rulebook directory`);continue}let i=k(e.scope,$g(e.path,o.name,"rulebook.json")),s=w(i);if(s===null){t.push(`${o.name}/rulebook.json is required`);continue}try{let a;try{a=JSON.parse(s)}catch{t.push(`${o.name}/rulebook.json: invalid JSON`);continue}let l=Fc(a);if(l.name!==o.name){t.push(`rulebook name "${l.name}" must match folder "${o.name}"`);continue}n.add(o.name)}catch(a){t.push(a instanceof Error?`${o.name}/rulebook.json: ${a.message}`:`${o.name}/rulebook.json: ${String(a)}`)}}return{errors:t,ruleNames:n}}function Gg(){console.log(Hc),console.log(Ng)}function Bg(e,t,n,r,o){if(console.log(`
246
+ ✓ ${e} config: ${t}`),console.log(` Schema: ${r==="rules"?"rulebook sources":"legacy inline rules"}`),n.ruleNames.size>0){console.log(` ${r==="rules"?"Sources":"Rules"}:`);let i=1;for(let s of n.ruleNames)console.log(` ${i}. ${o.get(s)??s}`),i++}else console.log(` ${r==="rules"?"Sources":"Rules"}: (none)`)}function qg(e,t,n,r){if(console.error(`
247
+ ✗ Legacy ${e.toLowerCase()} config: ${t}`),console.error(" Schema: legacy inline rules"),console.error(" Status: ignored by CC Safety Net"),n.errors.length>0){console.error(" Errors:");let o=1;for(let i of n.errors)for(let s of i.split("; "))console.error(` ${o}. ${s}`),o++;return}if(n.ruleNames.size>0){console.error(" Rules:");let o=1;for(let i of n.ruleNames)console.error(` ${o}. ${r.get(i)??i}`),o++;return}console.error(" Rules: (none)")}function Vg(e,t,n){jc(`${e} config`,t,n)}function zg(e,t){console.log(`
248
+ ✓ GitHub source rules: ${e}`),console.log(" Rulebooks:");let n=1;for(let r of t.ruleNames)console.log(` ${n}. ${r}`),n++}function Kg(e,t){jc("GitHub source rules",e,t)}function jc(e,t,n){console.error(`
249
+ ✗ ${e}: ${t}`),console.error(" Errors:");let r=1;for(let o of n)for(let i of o.split("; "))console.error(` ${r}. ${i}`),r++}function Wg(e){try{let t=w(e);if(t===null)return!1;let n=JSON.parse(t);if(n.$schema)return!1;return Se(e,JSON.stringify({$schema:Fg,...n},null,2)),!0}catch(t){if(t instanceof H)throw t;return!1}}var Uc=new Set(["init","add","remove","update","sync","list","wrapper","migrate","doc","verify"]),Yg=new Set(["add","remove","list"]);async function Bc(e){try{return await Zg(e)}catch(t){if(t instanceof H)return console.error(t.message),1;throw t}}async function Zg(e){let t=Qg(e),n=t.help?Xg(t.positionals):null;if(n)return En(n),0;if(t.errors.length>0){for(let s of t.errors)console.error(s);return 1}let r=t.positionals[0];if(!r)return En(rt,console.error),1;let o=t.positionals[1],i={global:t.global,check:t.check};if(r==="init"){let s=Y(i),a=s.configDir;n1(s.configTarget),Gc(k(s.filesystemScope,Wt({...i,cacheConfigDir:a})));let l=Jg(a,"example-rules","rulebook.json"),c=k(s.filesystemScope,l);if(t.example&&w(c)===null)mr(c,"example-rules");let d=await Ye(i);return Vt(d,"Rule config initialized."),d.ok?0:1}if(r==="add"){if(!o)return console.error("rule add requires a source"),1;let s=await lr(o,i);return Vt(s,`Added rulebook source: ${o}`),s.ok?0:1}if(r==="remove"){if(!o)return console.error("rule remove requires a source"),1;let s=await dr(o,{...i,deleteSource:t.deleteSource});return Vt(s,`Removed rulebook source: ${o}`),s.ok?0:1}if(r==="update"||r==="sync"){let s=await Ye({...i,only:r==="update"?o:void 0});return Vt(s,t.check?"Rule config checked.":"Rule config synced."),s.ok?0:1}if(r==="list"){let s=ve(),a=te({});return Pc(s,{user:Re(s.userConfigPath,a.userScope),project:Re(s.projectConfigPath,a.projectScope)}),s.errors.length>0?1:0}if(r==="wrapper")return r1(t);if(r==="migrate")return Oc({cleanup:t.cleanup,cwd:process.cwd()});if(r==="doc"){console.log(Ac);let s=await Nc();if(s)console.error(s);return 0}if(r==="verify")return Mc();return 1}function Xg(e){if(e.length===0)return rt;let t=rt.subcommands.filter((r)=>r.usage.split(" ")[0]===e[0]);if(t.length===0)return null;if(e.length===1&&t.length>1)return{name:`rule ${e[0]}`,description:`Subcommands of rule ${e[0]}`,usage:`rule ${e[0]} <subcommand>`,subcommands:t,options:[]};let n=e.length===1?t[0]:t.find((r)=>r.usage.split(" ")[1]===e[1]);if(!n)return null;return{name:`rule ${e[0]}`,description:n.description,usage:`rule ${n.usage}`,options:[]}}function Qg(e){let t=_({label:"rule",booleans:{global:["-g","--global"],check:["--check"],cleanup:["--cleanup"],deleteSource:["--delete-source"],example:["--example"]},positionals:"list"},e),n={...t.flags,help:t.help,positionals:t.positionals,errors:t.errors};return e1(n),n}function e1(e){let[t]=e.positionals;if(t&&!Uc.has(t))e.errors.push(`Unknown rule subcommand: ${t}`);if(e.deleteSource&&t!=="remove")if(t&&Uc.has(t))e.errors.push(`Unknown option for rule ${t}: --delete-source`);else e.errors.push("--delete-source is only valid with 'rule remove'");if(e.cleanup&&t!=="migrate")e.errors.push(Un(t,"--cleanup"));if(e.example&&t!=="init")e.errors.push(Un(t,"--example"));if(t==="migrate"){if(e.global)e.errors.push(Un(t,"--global"));if(e.check)e.errors.push(Un(t,"--check"));if(e.positionals.length>1)e.errors.push(`Unexpected rule migrate argument: ${e.positionals[1]}`)}else if(t==="wrapper")t1(e);else if(e.positionals.length>2)e.errors.push(`Unexpected rule argument: ${e.positionals[2]}`);if(t==="list"&&e.global)e.errors.push("Unknown option for rule list: --global")}function Un(e,t){return e?`Unknown option for rule ${e}: ${t}`:`Unknown option for rule: ${t}`}function t1(e){let t=e.positionals[1],n=e.positionals[2];if(!t){e.errors.push("rule wrapper requires add, remove, or list");return}if(!Yg.has(t)){e.errors.push(`Unknown rule wrapper action: ${t}`);return}if(t==="list"){if(n)e.errors.push(`Unexpected rule wrapper argument: ${n}`);return}if(!n){e.errors.push(`rule wrapper ${t} requires a command`);return}if(e.positionals.length>3)e.errors.push(`Unexpected rule wrapper argument: ${e.positionals[3]}`)}function n1(e){if(w(e)===null){fr(e);return}let t=Z(e);if(!t.config)return;X(e,{version:1,rules:t.config.rules,overrides:t.config.overrides??{},transparent_wrappers:t.config.transparent_wrappers??[]})}async function r1(e){let t=e.positionals[1],n=e.positionals[2],r=Y({global:e.global}).configTarget;if(t==="list"){let a=Z(r);if(a.errors.length>0){for(let l of a.errors)console.error(l);return 1}return o1(a.config?.transparent_wrappers??[]),0}if(!n||!hr.test(n))return console.error("transparent wrapper must match command pattern"),1;if(Lr(n))return console.error(`reserved command "${n}" cannot be a wrapper`),1;let o=Z(r);if(o.errors.length>0){for(let a of o.errors)console.error(a);return 1}let i=o.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},s=t==="add"?[...new Set([...i.transparent_wrappers??[],n])]:(i.transparent_wrappers??[]).filter((a)=>a!==n);return X(r,{version:1,rules:i.rules,overrides:i.overrides??{},transparent_wrappers:s}),console.log(t==="add"?`Added transparent wrapper: ${n}`:`Removed transparent wrapper: ${n}`),0}function o1(e){if(e.length===0){console.log("Transparent wrappers: (none)");return}console.log(`Transparent wrappers (${e.length}):`);for(let t of e)console.log(` - ${t}`)}import{homedir as qc}from"node:os";import{existsSync as i1,readFileSync as s1}from"node:fs";import{homedir as a1}from"node:os";import{join as l1}from"node:path";async function c1(e){if(e.isTTY)return null;return(await Sr(e).catch(()=>null))?.trim()||null}function d1(){if(process.env.CLAUDE_SETTINGS_PATH)return process.env.CLAUDE_SETTINGS_PATH;return l1(a1(),".claude","settings.json")}function Oo(){let e=d1();if(!i1(e))return!1;try{let t=s1(e,"utf-8"),n=JSON.parse(t);if(!n.enabledPlugins)return!1;let r="cc-safety-net@cc-marketplace";if(!(r in n.enabledPlugins))return!1;return n.enabledPlugins[r]===!0}catch(t){if(wt(S.debug))console.error(`CC Safety Net debug: failed to read Claude settings: ${e}: ${t instanceof Error?t.message:String(t)}`);return!1}}async function $o(e=process.stdin){let t=Oo(),n;if(!t)n="\uD83D\uDEE1️ CC Safety Net ❌";else{let o=B({cwd:process.cwd()}),i=o.policy,s=ue(i),a=Object.values(Pe(i,s.capabilities)).some((c)=>c.changesInherited);n=`\uD83D\uDEE1️ CC Safety Net ${{standard:"✅",strict:"\uD83D\uDD12",paranoid:"\uD83D\uDC41️",custom:"\uD83D\uDD27"}[a?"custom":s.effectiveLevel]}${s.worktreeMode?"\uD83C\uDF33":""}${o.state==="degraded"?"⚠️":""}`}let r=await c1(e);if(r&&!r.startsWith("{"))console.log(`${r} | ${n}`);else console.log(n)}function Vc(){let e=B({cwd:process.cwd()}),t=e.policy,n=ue(t),r=!!process.env.NO_COLOR||!process.stdout.isTTY,o=Math.min(process.stdout.columns||80,100),i=r?"ok":"✔",s=r?"OFF":"✘",a=(u,m)=>{let f=` ${u.padEnd(13)}${m}`;return(f.length>o?`${f.slice(0,o-1)}…`:f).replaceAll(s,h.red(s))},l=Object.values(Pe(t,n.capabilities)).some((u)=>u.changesInherited),c=kt(),d={ready:h.green,degraded:h.yellow}[e.state],p=[...Oo()?[]:["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."],...e.diagnostics],g=r?"-":"·";console.log([`${r?"":"\uD83D\uDEE1️ "}CC Safety Net — ${d(e.state)}`,"",a("Protection",`destructive ${t.destructiveCommandProtectionEnabled?i:s} secrets ${t.secretProtection.enabled?i:s}`),a("Level",l?`${n.effectiveLevel} (customised)`:n.effectiveLevel),a("Rules",t.rules.length===0?"none active":`${t.rules.length} active`),a("Policy",c.startsWith(qc())?`~${c.slice(qc().length)}`:c),...n.worktreeMode?[a("Worktree","relaxations active")]:[],"",...p.length===0?[" Everything configured is active."]:[" Not active",...p.flatMap((u)=>An(u," ",o-6).map((m,f)=>f===0?` ${g} ${m}`:m)),""," Full report: cc-safety-net doctor"]].join(`
250
+ `))}import{spawn as dd}from"node:child_process";import{randomBytes as w1}from"node:crypto";import{createServer as k1}from"node:http";import{Writable as x1}from"node:stream";import{homedir as u1}from"node:os";var Gn=500;function p1(e){let t=e.filter((o)=>o.decision!=="allow"),n=e.filter((o)=>o.decision==="allow"),r=Math.min(t.length,Math.max(Gn-n.length,Math.ceil(Gn/2)));return[...t.slice(0,r),...n.slice(0,Gn-r)]}function zc(e,t=pe()){if(t)Ae(t);let n=(f)=>new Date(f.getFullYear(),f.getMonth(),f.getDate()).getTime(),r=n(new Date),o=new Date(r);o.setDate(o.getDate()-(e-1));let i=o.getTime(),s=[],a={count:0};for(let f of t?Le(t,a):[])for(let L of Ce(f,a)){if(!L||typeof L.ts!=="string"||typeof L.command!=="string")continue;let v=new Date(L.ts).getTime();if(!Number.isFinite(v))continue;if(v>=i)s.push(L)}s.sort((f,L)=>new Date(L.ts).getTime()-new Date(f.ts).getTime());let l=Array.from({length:e},()=>0),c=Array.from({length:e},()=>0),d={},p={},g={},u=0,m=0;for(let f of s){let L=f.agent||"unknown";d[L]=(d[L]??0)+1;let v=Math.round((r-n(new Date(f.ts)))/86400000),x=e-1-v,y=v>=0&&v<e;if(y)c[x]=(c[x]??0)+1;if(f.decision!=="allow"){if(u++,f.ruleId)p[f.ruleId]=(p[f.ruleId]??0)+1;let C=qe(f.segment||f.command);if(C)g[C]=(g[C]??0)+1;if(f.failureStage)m++;if(y)l[x]=(l[x]??0)+1}}return{days:e,logsDir:t,homeDir:u1(),totalInWindow:s.length,truncated:s.length>Gn,unreadable:a.count,counts:{blocked:u,allowed:s.length-u,agents:d,blockedByDay:l,analyzedByDay:c,rules:p,commands:g,errors:m},entries:p1(s).sort((f,L)=>new Date(L.ts).getTime()-new Date(f.ts).getTime())}}import{spawn as f1}from"node:child_process";import{existsSync as m1,statSync as Kc}from"node:fs";import{delimiter as g1,join as h1}from"node:path";var y1=120000,Bn="Choose the project folder",L1=`try
251
+ return POSIX path of (choose folder with prompt "${Bn}")
251
252
  on error number -128
252
253
  return ""
253
- end try`,Bg=`Add-Type -AssemblyName System.Windows.Forms
254
+ end try`,v1=`Add-Type -AssemblyName System.Windows.Forms
254
255
  $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
255
- $dialog.Description = '${Nn}'
256
- if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.Write($dialog.SelectedPath) }`,Pc=[{binary:"zenity",args:["--file-selection","--directory",`--title=${Nn}`]},{binary:"kdialog",args:["--getexistingdirectory",".","--title",Nn]}],Tc=(e,t)=>(t.PATH??"").split(Mg).some((n)=>{if(n.length===0)return!1;try{let r=Ec(jg(n,e));return r.isFile()&&(r.mode&73)!==0}catch{return!1}});function Ic(e,t){if(e==="darwin"||e==="win32")return!0;if(e!=="linux")return!1;if(!t.DISPLAY&&!t.WAYLAND_DISPLAY)return!1;return Pc.some((n)=>Tc(n.binary,t))}function qg(e,t){if(e==="darwin")return{cmd:"osascript",args:["-e",Gg]};if(e==="win32")return{cmd:"powershell.exe",args:["-NoProfile","-STA","-Command",Bg]};let n=Pc.find((r)=>Tc(r.binary,t));return n?{cmd:n.binary,args:n.args}:null}function _c(e=process.platform,t=process.env){let n=qg(e,t);if(!n)return Promise.resolve({error:"No folder dialog is available on this system"});return new Promise((r)=>{let o=Fg(n.cmd,n.args,{env:t,stdio:["ignore","pipe","pipe"]}),i="",s=!1,a=(c)=>{if(s)return;s=!0,clearTimeout(l),r(c)},l=setTimeout(()=>{o.kill(),a({error:"The folder dialog timed out"})},Ug);o.stdout.on("data",(c)=>{i+=c.toString()}),o.on("error",()=>a({error:`Could not open the folder dialog (${n.cmd})`})),o.on("close",()=>{let c=i.trim().replace(/\/+$/,"");if(!c)return a({cancelled:!0});if(!Hg(c)||!Ec(c).isDirectory())return a({error:"That selection is not a folder on disk"});a({path:c})})})}var Oc=`<!doctype html>
256
+ $dialog.Description = '${Bn}'
257
+ if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.Write($dialog.SelectedPath) }`,Wc=[{binary:"zenity",args:["--file-selection","--directory",`--title=${Bn}`]},{binary:"kdialog",args:["--getexistingdirectory",".","--title",Bn]}],Jc=(e,t)=>(t.PATH??"").split(g1).some((n)=>{if(n.length===0)return!1;try{let r=Kc(h1(n,e));return r.isFile()&&(r.mode&73)!==0}catch{return!1}});function Yc(e,t){if(e==="darwin"||e==="win32")return!0;if(e!=="linux")return!1;if(!t.DISPLAY&&!t.WAYLAND_DISPLAY)return!1;return Wc.some((n)=>Jc(n.binary,t))}function b1(e,t){if(e==="darwin")return{cmd:"osascript",args:["-e",L1]};if(e==="win32")return{cmd:"powershell.exe",args:["-NoProfile","-STA","-Command",v1]};let n=Wc.find((r)=>Jc(r.binary,t));return n?{cmd:n.binary,args:n.args}:null}function Zc(e=process.platform,t=process.env){let n=b1(e,t);if(!n)return Promise.resolve({error:"No folder dialog is available on this system"});return new Promise((r)=>{let o=f1(n.cmd,n.args,{env:t,stdio:["ignore","pipe","pipe"]}),i="",s=!1,a=(c)=>{if(s)return;s=!0,clearTimeout(l),r(c)},l=setTimeout(()=>{o.kill(),a({error:"The folder dialog timed out"})},y1);o.stdout.on("data",(c)=>{i+=c.toString()}),o.on("error",()=>a({error:`Could not open the folder dialog (${n.cmd})`})),o.on("close",()=>{let c=i.trim().replace(/\/+$/,"");if(!c)return a({cancelled:!0});if(!m1(c)||!Kc(c).isDirectory())return a({error:"That selection is not a folder on disk"});a({path:c})})})}var Xc=`<!doctype html>
257
258
  <html lang="en">
258
259
  <head>
259
260
  <meta charset="utf-8">
@@ -3154,17 +3155,34 @@ var catalog = [
3154
3155
  }
3155
3156
  },
3156
3157
  {
3157
- id: "hermes-agent",
3158
- displayName: "Hermes Agent",
3158
+ id: "grok-build",
3159
+ displayName: "Grok Build",
3159
3160
  doctorOrder: 8,
3160
3161
  runtime: {
3161
3162
  order: 6,
3163
+ flags: ["-gb", "--grok-build"],
3164
+ description: "Run as Grok Build PreToolUse hook",
3165
+ legacyTopLevelFlags: []
3166
+ },
3167
+ install: {
3168
+ order: 8,
3169
+ flag: "--grok-build",
3170
+ artifactKind: "hook config",
3171
+ probeCommand: ["grok", "--version"]
3172
+ }
3173
+ },
3174
+ {
3175
+ id: "hermes-agent",
3176
+ displayName: "Hermes Agent",
3177
+ doctorOrder: 9,
3178
+ runtime: {
3179
+ order: 7,
3162
3180
  flags: ["-ha", "--hermes-agent"],
3163
3181
  description: "Run as Hermes Agent pre_tool_call hook",
3164
3182
  legacyTopLevelFlags: []
3165
3183
  },
3166
3184
  install: {
3167
- order: 8,
3185
+ order: 9,
3168
3186
  flag: "--hermes-agent",
3169
3187
  artifactKind: "plugin",
3170
3188
  probeCommand: ["hermes", "--version"]
@@ -3173,15 +3191,15 @@ var catalog = [
3173
3191
  {
3174
3192
  id: "kimi-code",
3175
3193
  displayName: "Kimi Code",
3176
- doctorOrder: 9,
3194
+ doctorOrder: 10,
3177
3195
  runtime: {
3178
- order: 7,
3196
+ order: 8,
3179
3197
  flags: ["-kc", "--kimi-code"],
3180
3198
  description: "Run as Kimi Code PreToolUse hook",
3181
3199
  legacyTopLevelFlags: []
3182
3200
  },
3183
3201
  install: {
3184
- order: 9,
3202
+ order: 10,
3185
3203
  flag: "--kimi-code",
3186
3204
  artifactKind: "hook config",
3187
3205
  probeCommand: ["kimi", "--version"]
@@ -3190,9 +3208,9 @@ var catalog = [
3190
3208
  {
3191
3209
  id: "openclaw",
3192
3210
  displayName: "OpenClaw",
3193
- doctorOrder: 10,
3211
+ doctorOrder: 11,
3194
3212
  install: {
3195
- order: 10,
3213
+ order: 11,
3196
3214
  flag: "--openclaw",
3197
3215
  artifactKind: "plugin",
3198
3216
  probeCommand: ["openclaw", "--version"]
@@ -3201,9 +3219,9 @@ var catalog = [
3201
3219
  {
3202
3220
  id: "opencode",
3203
3221
  displayName: "OpenCode",
3204
- doctorOrder: 11,
3222
+ doctorOrder: 12,
3205
3223
  install: {
3206
- order: 11,
3224
+ order: 12,
3207
3225
  flag: "--opencode",
3208
3226
  artifactKind: "plugin",
3209
3227
  probeCommand: ["opencode", "--version"]
@@ -3212,9 +3230,9 @@ var catalog = [
3212
3230
  {
3213
3231
  id: "pi",
3214
3232
  displayName: "Pi",
3215
- doctorOrder: 12,
3233
+ doctorOrder: 13,
3216
3234
  install: {
3217
- order: 12,
3235
+ order: 13,
3218
3236
  flag: "--pi",
3219
3237
  artifactKind: "package",
3220
3238
  probeCommand: ["pi", "--version"]
@@ -5309,5 +5327,5 @@ load().then((loaded) => {
5309
5327
  </script>
5310
5328
  </body>
5311
5329
  </html>
5312
- `;var $c='<script id="ccsn-data" type="application/json">';function Nc(e){return Oc.replace($c,()=>$c+JSON.stringify({token:e}).replaceAll("<","\\u003c"))}var Hn="kenryu42/cc-safety-net",Wg=`https://github.com/${Hn}`,To=1e4,Jg=7;async function Kc(e,t={}){let n=T({label:"gui",booleans:{noOpen:["--no-open"]}},e),r=t.log??console.log,o=t.error??console.error;if(n.errors.length>0){for(let s of n.errors)o(s);return o("Usage: cc-safety-net gui [--no-open]"),1}let i=await Yg(t);if(r(`CC Safety Net policy GUI: ${i.url}`),!n.flags.noOpen)try{await(t.openBrowser??i1)(i.url)}catch(s){o(`Failed to open browser: ${s instanceof Error?s.message:String(s)}`),o(`Open this URL manually: ${i.url}`)}if(t.keepAlive===!1)return await i.close(),0;return await o1(i),0}async function Yg(e={}){let t=Vg(24).toString("base64url"),n=zg((i,s)=>{Zg(i,s,t,e)});await new Promise((i,s)=>{n.once("error",s),n.listen(0,"127.0.0.1",()=>{n.off("error",s),i()})});let o=`http://127.0.0.1:${n.address().port}`;return{origin:o,token:t,url:`${o}/?token=${encodeURIComponent(t)}`,close:()=>r1(n)}}async function Zg(e,t,n,r){let o=new URL(e.url??"/","http://127.0.0.1");if(e.method==="GET"&&o.pathname==="/favicon.ico"){t.writeHead(204,{"cache-control":"no-store"}),t.end();return}if(!e1(e,o,n)){D(t,403,{error:"Forbidden"});return}if(e.method==="GET"&&o.pathname==="/"){n1(t,Nc(n));return}if(e.method==="GET"&&o.pathname==="/api/policy"){let i=jc(r);D(t,200,{...i,configState:xt(B(r)),destructiveCommandRules:Lt,secretPatterns:Hc,version:P(),preview:i.errors.length>0?null:Gc(i.policy)});return}if(e.method==="POST"&&o.pathname==="/api/policy/preview"){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=Uc(i.value);D(t,s.errors.length>0?400:200,s);return}if(e.method==="POST"&&o.pathname==="/api/policy/explain"){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=i.value;if(s===null||typeof s.command!=="string"){D(t,400,{errors:["command must be a string"]});return}let a=gr(s.policy);if(a.length>0){D(t,400,{errors:a});return}D(t,200,Xg(s.command,s.policy,r));return}if(e.method==="POST"&&o.pathname==="/api/policy"){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=Eo(i.value,r);D(t,s.errors.length>0?400:200,s);return}if(e.method==="POST"&&o.pathname==="/api/reset"){D(t,200,Eo(Mc,r));return}if(e.method==="POST"&&o.pathname==="/api/repair"){D(t,200,Bc(r));return}if(e.method==="GET"&&o.pathname==="/api/activity"){let i=Qe(r),s=Qg(o.searchParams.get("days"),i);if(s===null){D(t,400,{error:`days must be an integer between 1 and ${i}`});return}D(t,200,Ac(s,r.activityLogsDir));return}if(e.method==="POST"&&o.pathname==="/api/rules/choose-directory"){D(t,200,await _c());return}if(e.method==="GET"&&o.pathname==="/api/rules"){let i=Le(r),s=new Map(i.rules.map((a)=>[a.name,a]));D(t,200,{projectPath:r.cwd??process.cwd(),canPickDirectory:Ic(process.platform,process.env),rulebooks:i.rulebooks.map((a)=>({source:a.source,spec:a.spec,name:a.name,version:a.version,rules:a.rules.flatMap((l)=>{let c=s.get(l);if(!c)return[];return[{name:c.name,command:c.command,subcommand:c.subcommand,block_args:c.block_args,reason:c.reason}]})})),errors:i.errors,warnings:i.warnings});return}if(e.method==="GET"&&o.pathname==="/api/star/context"){D(t,200,await(r.fetchStarContext??(()=>d1({logsDir:r.activityLogsDir})))());return}if(e.method==="POST"&&o.pathname==="/api/star"){let i=await(r.starRepo??s1)();D(t,200,i.ok?{ok:!0}:{ok:!1,fallbackUrl:Wg});return}if(e.method==="GET"&&o.pathname==="/api/integrations"){D(t,200,await(r.fetchIntegrations??a1)());return}if(e.method==="GET"&&o.pathname==="/api/health"){D(t,200,await(r.fetchHealth??l1)());return}if(e.method==="POST"&&(o.pathname==="/api/install"||o.pathname==="/api/uninstall")){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=i.value?.target;if(typeof s!=="string"||!se.some((l)=>l.target===s)){D(t,400,{error:"unknown target"});return}let a=o.pathname==="/api/install"?"install":"uninstall";D(t,200,await(r.runIntegration??c1)(a,s));return}D(t,404,{error:"Not found"})}function Xg(e,t,n){let r=Cn(t),o=B(n),i=vt({rules:o.policy.rules,transparentWrappers:o.policy.transparentWrappers,safety:Vc(r.safety),worktreeMode:r.workflow.worktree_mode,destructiveCommandProtectionEnabled:r.destructive_command_protection.enabled,destructiveCommandRuleOverrides:r.destructive_command_protection.overrides,destructiveCommandAllowPaths:r.destructive_command_protection.allow_paths,secretProtection:{enabled:r.secret_protection.enabled,disabledRules:qc(r.secret_protection.overrides),denyPaths:r.secret_protection.deny_paths,allowPaths:r.secret_protection.allow_paths}});return Xe(e,{policySnapshot:i,cwd:n.cwd,userConfigDir:n.userConfigDir})}function Qg(e,t){if(e===null)return Math.min(Jg,t);let n=Number(e);if(!Number.isInteger(n)||n<1||n>t)return null;return n}function e1(e,t,n){if(t.searchParams.get("token")!==n)return!1;if(e.method!=="POST")return!0;return e.headers["x-cc-safety-net-token"]===n}var t1=1048576;async function Fn(e){let t=[],n=0;for await(let r of e){let o=r;if(n+=o.byteLength,n>t1)return{ok:!1,status:413,error:"Request body is too large"};t.push(o)}try{return{ok:!0,value:JSON.parse(Buffer.concat(t).toString("utf-8")||"{}")}}catch(r){return{ok:!1,status:400,error:`Invalid JSON: ${r instanceof Error?r.message:String(r)}`}}}function n1(e,t){e.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),e.end(t)}function D(e,t,n){e.writeHead(t,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),e.end(JSON.stringify(n))}function r1(e){return new Promise((t,n)=>{e.close((r)=>r?n(r):t())})}function o1(e){return new Promise((t)=>{let n=()=>{process.off("SIGINT",r),process.off("SIGTERM",r)},r=()=>{n(),e.close().then(t)};process.once("SIGINT",r),process.once("SIGTERM",r)})}function i1(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",n=process.platform==="win32"?["/c","start","",e]:[e];return new Promise((r,o)=>{let i=zc(t,n,{detached:!0,stdio:"ignore"}),s=(l)=>{i.off("spawn",a),o(l)},a=()=>{i.off("error",s),i.unref(),r()};i.once("error",s),i.once("spawn",a)})}async function s1(e="gh",t=To){return{ok:await Po(e,["api","-X","PUT",`/user/starred/${Hn}`],t)===0}}async function a1(e={}){let t=await Rt(e.fetcher),n=Wc(t,e.homeDir);return{targets:V.map((r)=>{let o=n.find((i)=>i.platform===r.id);return{target:r.id,label:R(r.id),version:t.versions[r.id]??null,status:o?.configured?"active":o?.detected?"disabled":o?.inspectionStatus==="not-inspected"?"not-inspected":"not-installed"}}),system:{version:t.version,nodeVersion:t.nodeVersion,platform:t.platform}}}function Wc(e,t){return lt(process.cwd(),{homeDir:t,ampPluginListOutput:e.ampPluginListOutput,codexPluginListOutput:e.codexPluginListOutput,copilotCliVersion:e.versions["copilot-cli"]})}async function l1(e={}){let[t,n]=await Promise.all([Rt(e.fetcher),(e.checkUpdates??ve)()]);return{hooks:Wc(t,e.homeDir).filter((r)=>r.detected).map((r)=>({platform:r.platform,label:R(r.platform),configured:r.configured})),update:{currentVersion:n.currentVersion,latestVersion:n.latestVersion??null,updateAvailable:n.updateAvailable}}}var Fc=Promise.resolve();function c1(e,t,n={}){let r=async()=>{let i=[],s=console.log,a=console.error;console.log=(...l)=>i.push(l.map(String).join(" ")),console.error=console.log;try{return{ok:await Ut(e,[],{selectTargets:async()=>[t],output:new Kg({write(c,d,p){i.push(String(c).replace(/\n$/,"")),p()}}),...n})===0,output:i.join(`
5313
- `)}}finally{console.log=s,console.error=a}},o=Fc.then(r);return Fc=o.then(()=>{return},()=>{return}),o}async function d1(e={}){let[t,n,r]=await Promise.all([u1(e.command),p1(e.fetchRepo),Promise.resolve(Xt(Qe(),e.logsDir).totalBlocked)]);return{starred:t,starCount:n,blockedTotal:r}}async function u1(e="gh",t=To){if(await Po(e,["auth","status"],t)!==0)return null;let n=await Po(e,["api",`/user/starred/${Hn}`],t);if(n===0)return!0;if(n===null)return null;return!1}function Po(e,t,n){return new Promise((r)=>{let o=zc(e,t,{stdio:"ignore",windowsHide:!0}),i=!1,s,a=(l)=>{if(i)return;if(i=!0,s)clearTimeout(s);r(l)};o.once("error",()=>a(null)),o.once("close",a),s=setTimeout(()=>{o.kill(),a(null)},n)})}async function p1(e=fetch){try{let t=await e(`https://api.github.com/repos/${Hn}`,{headers:{accept:"application/vnd.github+json"},signal:AbortSignal.timeout(To)});if(!t.ok)return null;let n=await t.json();return typeof n.stargazers_count==="number"?n.stargazers_count:null}catch{return null}}function f1(e){if(e[0]!=="help")return!1;let t=e[1];if(!t)co(),process.exit(0);if(Ft(t))process.exit(0);console.error(`Unknown command: ${t}`),console.error("Run 'cc-safety-net --help' for available commands."),process.exit(1)}var m1={hook:async(e)=>{let t=ts(e);if(t){await t.run();return}console.error("hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code"),Ft("hook",console.error),process.exit(1)},install:async(e)=>{process.exit(await Ut("install",e))},update:async(e)=>{process.exit(await Co(e))},uninstall:async(e)=>{process.exit(await Ut("uninstall",e))},rule:async(e)=>{process.exit(await Sc(e))},status:async(e)=>{if(ae(T({label:"status"},e).errors))process.exit(1);Rc()},statusline:async(e)=>{let t=T({label:"statusline",booleans:{claudeCode:["-cc","--claude-code"]}},e);if(t.errors.length===0&&t.flags.claudeCode){await Ao();return}if(ae(t.errors),!t.flags.claudeCode)console.error("statusline requires --claude-code (-cc)");Ft("statusline",console.error),process.exit(1)},doctor:async(e)=>{let t=oo(e);if(!t)process.exit(1);let n=await nl({json:t.json,skipUpdateCheck:t.skipUpdateCheck});process.exit(n)},logs:async(e)=>{process.exit(await Ci(e))},gui:async(e)=>{process.exit(await Kc(e))},explain:async(e)=>{process.exit(await cl(e))}};async function g1(){let e=process.argv.slice(2),t=T({label:"cc-safety-net",booleans:{version:["-V","--version"]},positionals:"list"},e);if(f1(e))return;let n=e[0],r=n?Zt(n):void 0;if(t.help&&r&&r.name!=="rule")Ft(r.name),process.exit(0);if(!n||t.help&&!r)co(),process.exit(0);if(t.flags.version)pl(),process.exit(0);if(r){await m1[r.name](e.slice(1));return}let o=ns(n);if(o){await o.run();return}if(n==="--statusline"){await Ao();return}console.error(n.startsWith("-")?`Unknown option: ${n}`:`Unknown command: ${n}`),console.error("Run 'cc-safety-net --help' for usage."),process.exit(1)}g1().catch((e)=>{console.error("CC Safety Net error:",e),process.exit(1)});
5330
+ `;var Qc='<script id="ccsn-data" type="application/json">';function ed(e){return Xc.replace(Qc,()=>Qc+JSON.stringify({token:e}).replaceAll("<","\\u003c"))}var Vn="kenryu42/cc-safety-net",C1=`https://github.com/${Vn}`,Ho=1e4,S1=7;async function ud(e,t={}){let n=_({label:"gui",booleans:{noOpen:["--no-open"]}},e),r=t.log??console.log,o=t.error??console.error;if(n.errors.length>0){for(let s of n.errors)o(s);return o("Usage: cc-safety-net gui [--no-open]"),1}let i=await D1(t);if(r(`CC Safety Net policy GUI: ${i.url}`),!n.flags.noOpen)try{await(t.openBrowser??$1)(i.url)}catch(s){o(`Failed to open browser: ${s instanceof Error?s.message:String(s)}`),o(`Open this URL manually: ${i.url}`)}if(t.keepAlive===!1)return await i.close(),0;return await O1(i),0}async function D1(e={}){let t=w1(24).toString("base64url"),n=k1((i,s)=>{R1(i,s,t,e)});await new Promise((i,s)=>{n.once("error",s),n.listen(0,"127.0.0.1",()=>{n.off("error",s),i()})});let o=`http://127.0.0.1:${n.address().port}`;return{origin:o,token:t,url:`${o}/?token=${encodeURIComponent(t)}`,close:()=>_1(n)}}async function R1(e,t,n,r){let o=new URL(e.url??"/","http://127.0.0.1");if(e.method==="GET"&&o.pathname==="/favicon.ico"){t.writeHead(204,{"cache-control":"no-store"}),t.end();return}if(!P1(e,o,n)){D(t,403,{error:"Forbidden"});return}if(e.method==="GET"&&o.pathname==="/"){I1(t,ed(n));return}if(e.method==="GET"&&o.pathname==="/api/policy"){let i=od(r);D(t,200,{...i,configState:xt(B(r)),destructiveCommandRules:vt,secretPatterns:nd,version:T(),preview:i.errors.length>0?null:sd(i.policy)});return}if(e.method==="POST"&&o.pathname==="/api/policy/preview"){let i=await qn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=id(i.value);D(t,s.errors.length>0?400:200,s);return}if(e.method==="POST"&&o.pathname==="/api/policy/explain"){let i=await qn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=i.value;if(s===null||typeof s.command!=="string"){D(t,400,{errors:["command must be a string"]});return}let a=kr(s.policy);if(a.length>0){D(t,400,{errors:a});return}D(t,200,A1(s.command,s.policy,r));return}if(e.method==="POST"&&o.pathname==="/api/policy"){let i=await qn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=No(i.value,r);D(t,s.errors.length>0?400:200,s);return}if(e.method==="POST"&&o.pathname==="/api/reset"){D(t,200,No(rd,r));return}if(e.method==="POST"&&o.pathname==="/api/repair"){D(t,200,ad(r));return}if(e.method==="GET"&&o.pathname==="/api/activity"){let i=tt(r),s=E1(o.searchParams.get("days"),i);if(s===null){D(t,400,{error:`days must be an integer between 1 and ${i}`});return}D(t,200,zc(s,r.activityLogsDir));return}if(e.method==="POST"&&o.pathname==="/api/rules/choose-directory"){D(t,200,await Zc());return}if(e.method==="GET"&&o.pathname==="/api/rules"){let i=ve(r),s=new Map(i.rules.map((a)=>[a.name,a]));D(t,200,{projectPath:r.cwd??process.cwd(),canPickDirectory:Yc(process.platform,process.env),rulebooks:i.rulebooks.map((a)=>({source:a.source,spec:a.spec,name:a.name,version:a.version,rules:a.rules.flatMap((l)=>{let c=s.get(l);if(!c)return[];return[{name:c.name,command:c.command,subcommand:c.subcommand,block_args:c.block_args,reason:c.reason}]})})),errors:i.errors,warnings:i.warnings});return}if(e.method==="GET"&&o.pathname==="/api/star/context"){D(t,200,await(r.fetchStarContext??(()=>j1({logsDir:r.activityLogsDir})))());return}if(e.method==="POST"&&o.pathname==="/api/star"){let i=await(r.starRepo??N1)();D(t,200,i.ok?{ok:!0}:{ok:!1,fallbackUrl:C1});return}if(e.method==="GET"&&o.pathname==="/api/integrations"){D(t,200,await(r.fetchIntegrations??F1)());return}if(e.method==="GET"&&o.pathname==="/api/health"){D(t,200,await(r.fetchHealth??H1)());return}if(e.method==="POST"&&(o.pathname==="/api/install"||o.pathname==="/api/uninstall")){let i=await qn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=i.value?.target;if(typeof s!=="string"||!ae.some((l)=>l.target===s)){D(t,400,{error:"unknown target"});return}let a=o.pathname==="/api/install"?"install":"uninstall";D(t,200,await(r.runIntegration??M1)(a,s));return}D(t,404,{error:"Not found"})}function A1(e,t,n){let r=Tn(t),o=B(n),i=bt({rules:o.policy.rules,transparentWrappers:o.policy.transparentWrappers,safety:cd(r.safety),worktreeMode:r.workflow.worktree_mode,destructiveCommandProtectionEnabled:r.destructive_command_protection.enabled,destructiveCommandRuleOverrides:r.destructive_command_protection.overrides,destructiveCommandAllowPaths:r.destructive_command_protection.allow_paths,secretProtection:{enabled:r.secret_protection.enabled,disabledRules:ld(r.secret_protection.overrides),denyPaths:r.secret_protection.deny_paths,allowPaths:r.secret_protection.allow_paths}});return et(e,{policySnapshot:i,cwd:n.cwd,userConfigDir:n.userConfigDir})}function E1(e,t){if(e===null)return Math.min(S1,t);let n=Number(e);if(!Number.isInteger(n)||n<1||n>t)return null;return n}function P1(e,t,n){if(t.searchParams.get("token")!==n)return!1;if(e.method!=="POST")return!0;return e.headers["x-cc-safety-net-token"]===n}var T1=1048576;async function qn(e){let t=[],n=0;for await(let r of e){let o=r;if(n+=o.byteLength,n>T1)return{ok:!1,status:413,error:"Request body is too large"};t.push(o)}try{return{ok:!0,value:JSON.parse(Buffer.concat(t).toString("utf-8")||"{}")}}catch(r){return{ok:!1,status:400,error:`Invalid JSON: ${r instanceof Error?r.message:String(r)}`}}}function I1(e,t){e.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),e.end(t)}function D(e,t,n){e.writeHead(t,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),e.end(JSON.stringify(n))}function _1(e){return new Promise((t,n)=>{e.close((r)=>r?n(r):t())})}function O1(e){return new Promise((t)=>{let n=()=>{process.off("SIGINT",r),process.off("SIGTERM",r)},r=()=>{n(),e.close().then(t)};process.once("SIGINT",r),process.once("SIGTERM",r)})}function $1(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",n=process.platform==="win32"?["/c","start","",e]:[e];return new Promise((r,o)=>{let i=dd(t,n,{detached:!0,stdio:"ignore"}),s=(l)=>{i.off("spawn",a),o(l)},a=()=>{i.off("error",s),i.unref(),r()};i.once("error",s),i.once("spawn",a)})}async function N1(e="gh",t=Ho){return{ok:await Fo(e,["api","-X","PUT",`/user/starred/${Vn}`],t)===0}}async function F1(e={}){let t=await At(e.fetcher),n=pd(t,e.homeDir);return{targets:z.map((r)=>{let o=n.find((i)=>i.platform===r.id);return{target:r.id,label:R(r.id),version:t.versions[r.id]??null,status:o?.configured?"active":o?.detected?"disabled":o?.inspectionStatus==="not-inspected"?"not-inspected":"not-installed"}}),system:{version:t.version,nodeVersion:t.nodeVersion,platform:t.platform}}}function pd(e,t){return dt(process.cwd(),{homeDir:t,ampPluginListOutput:e.ampPluginListOutput,codexPluginListOutput:e.codexPluginListOutput,copilotCliVersion:e.versions["copilot-cli"]})}async function H1(e={}){let[t,n]=await Promise.all([At(e.fetcher),(e.checkUpdates??be)()]);return{hooks:pd(t,e.homeDir).filter((r)=>r.detected).map((r)=>({platform:r.platform,label:R(r.platform),configured:r.configured})),update:{currentVersion:n.currentVersion,latestVersion:n.latestVersion??null,updateAvailable:n.updateAvailable}}}var td=Promise.resolve();function M1(e,t,n={}){let r=async()=>{let i=[],s=console.log,a=console.error;console.log=(...l)=>i.push(l.map(String).join(" ")),console.error=console.log;try{return{ok:await qt(e,[],{selectTargets:async()=>[t],output:new x1({write(c,d,p){i.push(String(c).replace(/\n$/,"")),p()}}),...n})===0,output:i.join(`
5331
+ `)}}finally{console.log=s,console.error=a}},o=td.then(r);return td=o.then(()=>{return},()=>{return}),o}async function j1(e={}){let[t,n,r]=await Promise.all([U1(e.command),G1(e.fetchRepo),Promise.resolve(tn(tt(),e.logsDir).totalBlocked)]);return{starred:t,starCount:n,blockedTotal:r}}async function U1(e="gh",t=Ho){if(await Fo(e,["auth","status"],t)!==0)return null;let n=await Fo(e,["api",`/user/starred/${Vn}`],t);if(n===0)return!0;if(n===null)return null;return!1}function Fo(e,t,n){return new Promise((r)=>{let o=dd(e,t,{stdio:"ignore",windowsHide:!0}),i=!1,s,a=(l)=>{if(i)return;if(i=!0,s)clearTimeout(s);r(l)};o.once("error",()=>a(null)),o.once("close",a),s=setTimeout(()=>{o.kill(),a(null)},n)})}async function G1(e=fetch){try{let t=await e(`https://api.github.com/repos/${Vn}`,{headers:{accept:"application/vnd.github+json"},signal:AbortSignal.timeout(Ho)});if(!t.ok)return null;let n=await t.json();return typeof n.stargazers_count==="number"?n.stargazers_count:null}catch{return null}}function B1(e){if(e[0]!=="help")return!1;let t=e[1];if(!t)yo(),process.exit(0);if(jt(t))process.exit(0);console.error(`Unknown command: ${t}`),console.error("Run 'cc-safety-net --help' for available commands."),process.exit(1)}var q1={hook:async(e)=>{let t=cs(e);if(t){await t.run();return}console.error("hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code"),jt("hook",console.error),process.exit(1)},install:async(e)=>{process.exit(await qt("install",e))},update:async(e)=>{process.exit(await To(e))},uninstall:async(e)=>{process.exit(await qt("uninstall",e))},rule:async(e)=>{process.exit(await Bc(e))},status:async(e)=>{if(le(_({label:"status"},e).errors))process.exit(1);Vc()},statusline:async(e)=>{let t=_({label:"statusline",booleans:{claudeCode:["-cc","--claude-code"]}},e);if(t.errors.length===0&&t.flags.claudeCode){await $o();return}if(le(t.errors),!t.flags.claudeCode)console.error("statusline requires --claude-code (-cc)");jt("statusline",console.error),process.exit(1)},doctor:async(e)=>{let t=po(e);if(!t)process.exit(1);let n=await bl({json:t.json,skipUpdateCheck:t.skipUpdateCheck});process.exit(n)},logs:async(e)=>{process.exit(await Ti(e))},gui:async(e)=>{process.exit(await ud(e))},explain:async(e)=>{process.exit(await Rl(e))}};async function V1(){let e=process.argv.slice(2),t=_({label:"cc-safety-net",booleans:{version:["-V","--version"]},positionals:"list"},e);if(B1(e))return;let n=e[0],r=n?en(n):void 0;if(t.help&&r&&r.name!=="rule")jt(r.name),process.exit(0);if(!n||t.help&&!r)yo(),process.exit(0);if(t.flags.version)Pl(),process.exit(0);if(r){await q1[r.name](e.slice(1));return}let o=ds(n);if(o){await o.run();return}if(n==="--statusline"){await $o();return}console.error(n.startsWith("-")?`Unknown option: ${n}`:`Unknown command: ${n}`),console.error("Run 'cc-safety-net --help' for usage."),process.exit(1)}V1().catch((e)=>{console.error("CC Safety Net error:",e),process.exit(1)});